@@ -134,7 +134,7 @@ def __init__(self, name='node', parent=None):
134134 self ._output_items = {}
135135 self ._widgets = {}
136136 self ._proxy_mode = False
137- self ._porxy_mode_threshold = 70
137+ self ._proxy_mode_threshold = 70
138138
139139 def paint (self , painter , option , widget ):
140140 """
@@ -221,7 +221,7 @@ def itemChange(self, change, value):
221221 if change == self .ItemSelectedChange and self .scene ():
222222 self .reset_pipes ()
223223 if value :
224- self .hightlight_pipes ()
224+ self .highlight_pipes ()
225225 self .setZValue (Z_VAL_NODE )
226226 if not self .selected :
227227 self .setZValue (Z_VAL_NODE + 1 )
@@ -274,7 +274,7 @@ def activate_pipes(self):
274274 for pipe in port .connected_pipes :
275275 pipe .activate ()
276276
277- def hightlight_pipes (self ):
277+ def highlight_pipes (self ):
278278 """
279279 highlight pipe color.
280280 """
@@ -497,7 +497,7 @@ def auto_switch_mode(self):
497497 # with is the node with in screen
498498 width = r .x () - l .x ()
499499
500- self .set_proxy_mode (width < self ._porxy_mode_threshold )
500+ self .set_proxy_mode (width < self ._proxy_mode_threshold )
501501
502502 def set_proxy_mode (self , mode ):
503503 if mode is self ._proxy_mode :
@@ -511,15 +511,13 @@ def set_proxy_mode(self, mode):
511511 w .widget .setVisible (visible )
512512 for port , text in self ._input_items .items ():
513513 port .setVisible (visible )
514- text .setVisible (visible )
515- # for pipe in port.connected_pipes:
516- # pipe.setVisible(visible)
514+ if text .visible_ :
515+ text .setVisible (visible )
517516
518517 for port , text in self ._output_items .items ():
519518 port .setVisible (visible )
520- text .setVisible (visible )
521- # for pipe in port.connected_pipes:
522- # pipe.setVisible(visible)
519+ if text .visible_ :
520+ text .setVisible (visible )
523521
524522 self .text_item .setVisible (visible )
525523 self ._icon_item .setVisible (visible )
@@ -567,7 +565,7 @@ def disabled(self, state=False):
567565 def selected (self , selected = False ):
568566 AbstractNodeItem .selected .fset (self , selected )
569567 if selected :
570- self .hightlight_pipes ()
568+ self .highlight_pipes ()
571569
572570 @AbstractNodeItem .name .setter
573571 def name (self , name = '' ):
@@ -625,6 +623,7 @@ def add_input(self, name='input', multi_port=False, display_name=True):
625623 text .font ().setPointSize (8 )
626624 text .setFont (text .font ())
627625 text .setVisible (display_name )
626+ text .visible_ = display_name
628627 text .setCacheMode (ITEM_CACHE_MODE )
629628 self ._input_items [port ] = text
630629 if self .scene ():
@@ -650,6 +649,7 @@ def add_output(self, name='output', multi_port=False, display_name=True):
650649 text .font ().setPointSize (8 )
651650 text .setFont (text .font ())
652651 text .setVisible (display_name )
652+ text .visible_ = display_name
653653 text .setCacheMode (ITEM_CACHE_MODE )
654654 self ._output_items [port ] = text
655655 if self .scene ():
@@ -731,3 +731,207 @@ def from_dict(self, node_dict):
731731 for name , value in widgets .items ():
732732 if self ._widgets .get (name ):
733733 self ._widgets [name ].value = value
734+
735+
736+ class NodeItemVertical (NodeItem ):
737+ def __init__ (self , name = 'node' , parent = None ):
738+ super (NodeItemVertical , self ).__init__ (name , parent )
739+ font = QtGui .QFont ()
740+ font .setPointSize (15 )
741+ self .text_item .setFont (font )
742+
743+ def paint (self , painter , option , widget ):
744+ """
745+ Draws the node base not the ports.
746+
747+ Args:
748+ painter (QtGui.QPainter): painter used for drawing the item.
749+ option (QtGui.QStyleOptionGraphicsItem):
750+ used to describe the parameters needed to draw.
751+ widget (QtWidgets.QWidget): not used.
752+ """
753+ self .auto_switch_mode ()
754+
755+ painter .save ()
756+ bg_border = 1.0
757+ rect = QtCore .QRectF (0.5 - (bg_border / 2 ),
758+ 0.5 - (bg_border / 2 ),
759+ self ._width + bg_border ,
760+ self ._height + bg_border )
761+ radius = 2
762+ border_color = QtGui .QColor (* self .border_color )
763+
764+ path = QtGui .QPainterPath ()
765+ path .addRoundedRect (rect , radius , radius )
766+
767+ rect = self .boundingRect ()
768+
769+ bg_color = QtGui .QColor (* self .color )
770+ painter .setBrush (bg_color )
771+ painter .setPen (QtCore .Qt .NoPen )
772+ painter .drawRoundedRect (rect , radius , radius )
773+
774+ if self .selected and NODE_SEL_COLOR :
775+ painter .setBrush (QtGui .QColor (* NODE_SEL_COLOR ))
776+ painter .drawRoundedRect (rect , radius , radius )
777+
778+ label_rect = QtCore .QRectF (rect .left (), rect .top (), self ._width , 15 )
779+ path = QtGui .QPainterPath ()
780+ path .addRoundedRect (label_rect , radius , radius )
781+ painter .setBrush (QtGui .QColor (30 , 30 , 30 , 200 ))
782+ painter .fillPath (path , painter .brush ())
783+
784+ label_rect = QtCore .QRectF (rect .left (), rect .bottom ()- 15 , self ._width , 15 )
785+ path = QtGui .QPainterPath ()
786+ path .addRoundedRect (label_rect , radius , radius )
787+ painter .fillPath (path , painter .brush ())
788+
789+ border_width = 0.8
790+ if self .selected and NODE_SEL_BORDER_COLOR :
791+ border_width = 1.2
792+ border_color = QtGui .QColor (* NODE_SEL_BORDER_COLOR )
793+ border_rect = QtCore .QRectF (rect .left () - (border_width / 2 ),
794+ rect .top () - (border_width / 2 ),
795+ rect .width () + border_width ,
796+ rect .height () + border_width )
797+
798+ pen = QtGui .QPen (border_color , border_width )
799+ pen .setCosmetic (self .viewer ().get_zoom () < 0.0 )
800+ path = QtGui .QPainterPath ()
801+ path .addRoundedRect (border_rect , radius , radius )
802+ painter .setBrush (QtCore .Qt .NoBrush )
803+ painter .setPen (pen )
804+ painter .drawPath (path )
805+
806+ painter .restore ()
807+
808+ def arrange_icon (self , h_offset = 0.0 , v_offset = 0.0 ):
809+ """
810+ Arrange node icon to the default top left of the node.
811+
812+ Args:
813+ v_offset (float): vertical offset.
814+ h_offset (float): horizontal offset.
815+ """
816+ # icon_rect = self._icon_item.boundingRect()
817+ # x = self._width / 2 - (icon_rect.width() / 2) + h_offset
818+ # y = self._height / 2 - (icon_rect.height() / 2) + v_offset
819+ x = 2.0 + h_offset
820+ y = 17.0 + v_offset
821+ self ._icon_item .setPos (x , y )
822+
823+ def arrange_label (self , h_offset = 0.0 , v_offset = 0.0 ):
824+ """
825+ Arrange node label to the default top center of the node.
826+
827+ Args:
828+ v_offset (float): vertical offset.
829+ h_offset (float): horizontal offset.
830+ """
831+ text_rect = self .text_item .boundingRect ()
832+ text_x = self ._width + 10 + h_offset
833+ text_y = self ._height / 2 - (text_rect .height () / 2 )
834+ self .text_item .setPos (text_x , text_y )
835+
836+ def arrange_ports (self , v_offset = 0.0 ):
837+ """
838+ Arrange input, output ports in the node layout.
839+ """
840+ # adjust input position
841+ inputs = [p for p in self .inputs if p .isVisible ()]
842+ if inputs :
843+ port_width = inputs [0 ].boundingRect ().width ()
844+ port_height = inputs [0 ].boundingRect ().height ()
845+ half_width = port_width / 2
846+ delta = self ._width / (len (inputs )+ 1 )
847+ port_x = delta
848+ port_y = (port_height / 2 ) * - 1
849+ for port in inputs :
850+ port .setPos (port_x - half_width , port_y )
851+ port_x += delta
852+
853+ # adjust output position
854+ outputs = [p for p in self .outputs if p .isVisible ()]
855+ if outputs :
856+ port_width = outputs [0 ].boundingRect ().width ()
857+ port_height = outputs [0 ].boundingRect ().height ()
858+ half_width = port_width / 2
859+ delta = self ._width / (len (outputs )+ 1 )
860+ port_x = delta
861+ port_y = self ._height - (port_height / 2 )
862+ for port in outputs :
863+ port .setPos (port_x - half_width , port_y )
864+ port_x += delta
865+
866+ def draw_node (self ):
867+ """
868+ Draw the node item in the scene.
869+ """
870+ # setup initial base size.
871+ self ._set_base_size (add_w = 0.0 , add_h = 0.0 )
872+ # set text color when node is initialized.
873+ self ._set_text_color (self .text_color )
874+ # set the tooltip
875+ self ._tooltip_disable (self .disabled )
876+
877+ # --- setup node layout ---
878+
879+ # arrange label text
880+ self .arrange_label (h_offset = 0.0 , v_offset = 0.0 )
881+ # arrange icon
882+ self .arrange_icon (h_offset = 0.0 , v_offset = 0.0 )
883+ # arrange input and output ports.
884+ self .arrange_ports ()
885+ # arrange node widgets
886+ self .arrange_widgets (v_offset = 0.0 )
887+ self .update ()
888+
889+ def calc_size (self , add_w = 0.0 , add_h = 0.0 ):
890+ """
891+ calculate minimum node size.
892+
893+ Args:
894+ add_w (float): additional width.
895+ add_h (float): additional height.
896+ """
897+ width = 0
898+ height = 0
899+
900+ if self ._widgets :
901+ wid_width = max ([
902+ w .boundingRect ().width () for w in self ._widgets .values ()
903+ ])
904+ width = max (width , wid_width )
905+
906+ port_width = 0.0
907+ if self ._input_items :
908+ port = list (self ._input_items .keys ())[0 ]
909+ height += port .boundingRect ().height ()
910+ port_width = port .boundingRect ().width ()
911+
912+ if self ._output_items :
913+ port = list (self ._output_items .keys ())[0 ]
914+ height += port .boundingRect ().height ()
915+ port_width = port .boundingRect ().width ()
916+
917+ in_count = len ([p for p in self .inputs if p .isVisible ()])
918+ out_count = len ([p for p in self .outputs if p .isVisible ()])
919+ width = max (width , port_width * max (in_count , out_count ))
920+ if self ._widgets :
921+ wid_height = 0.0
922+ for w in self ._widgets .values ():
923+ wid_height += w .boundingRect ().height ()
924+ wid_height += wid_height / len (self ._widgets .values ())
925+ if wid_height > height :
926+ height = wid_height
927+
928+ width += add_w
929+ height += add_h + 15
930+
931+ return width , height
932+
933+ def add_input (self , name = 'input' , multi_port = False , display_name = False ):
934+ return super (NodeItemVertical , self ).add_input (name , multi_port , False )
935+
936+ def add_output (self , name = 'output' , multi_port = False , display_name = False ):
937+ return super (NodeItemVertical , self ).add_output (name , multi_port , False )
0 commit comments