11#!/usr/bin/python
22from Qt import QtCore , QtGui , QtWidgets
33
4- from NodeGraphQt .constants import NodeEnum
4+ from NodeGraphQt .constants import NodeEnum , PortEnum
55from NodeGraphQt .qgraphics .node_base import NodeItem
66
77
@@ -17,9 +17,202 @@ class CircleNodeItem(NodeItem):
1717 def __init__ (self , name = 'circle' , parent = None ):
1818 super (CircleNodeItem , self ).__init__ (name , parent )
1919
20+ def _align_ports_horizontal (self , v_offset ):
21+ width = self ._width
22+ txt_offset = PortEnum .CLICK_FALLOFF .value - 2
23+ spacing = 1
24+
25+ node_center_y = self .boundingRect ().center ().y ()
26+ node_center_y += v_offset
27+
28+ # adjust input position
29+ inputs = [p for p in self .inputs if p .isVisible ()]
30+ if inputs :
31+ port_width = inputs [0 ].boundingRect ().width ()
32+ port_height = inputs [0 ].boundingRect ().height ()
33+
34+ count = len (inputs )
35+ if count > 2 :
36+ is_odd = bool (count % 2 )
37+ middle_idx = int (count / 2 )
38+
39+ # top half
40+ port_x = (port_width / 2 ) * - 1
41+ port_y = node_center_y - (port_height / 2 )
42+ for idx , port in enumerate (reversed (inputs [:middle_idx ])):
43+ if idx == 0 :
44+ if is_odd :
45+ port_x += (port_width / 2 ) - (txt_offset / 2 )
46+ port_y -= port_height + spacing
47+ else :
48+ port_y -= (port_height / 2 ) + spacing
49+ port .setPos (port_x , port_y )
50+ port_x += (port_width / 2 ) - (txt_offset / 2 )
51+ port_y -= port_height + spacing
52+
53+ # bottom half
54+ port_x = (port_width / 2 ) * - 1
55+ port_y = node_center_y - (port_height / 2 )
56+ for idx , port in enumerate (inputs [middle_idx :]):
57+ if idx == 0 :
58+ if not is_odd :
59+ port_y += (port_height / 2 ) + spacing
60+ port .setPos (port_x , port_y )
61+ port_x += (port_width / 2 ) - (txt_offset / 2 )
62+ port_y += port_height + spacing
63+
64+ else :
65+ port_x = (port_width / 2 ) * - 1
66+ port_y = node_center_y - (port_height / 2 )
67+ inputs [0 ].setPos (port_x , port_y - (port_height / 2 ) + spacing )
68+ inputs [1 ].setPos (port_x , port_y + (port_height / 2 ) + spacing )
69+
70+ # adjust input text position
71+ for port , text in self ._input_items .items ():
72+ if port .isVisible ():
73+ port_width = port .boundingRect ().width ()
74+ txt_x = port .pos ().x () + port_width - txt_offset
75+ text .setPos (txt_x , port .y () - 1.5 )
76+
77+ # adjust output position
78+ outputs = [p for p in self .outputs if p .isVisible ()]
79+ if outputs :
80+ port_width = outputs [0 ].boundingRect ().width ()
81+ port_height = outputs [0 ].boundingRect ().height ()
82+
83+ count = len (outputs )
84+ if count > 2 :
85+ is_odd = bool (count % 2 )
86+ middle_idx = int (count / 2 )
87+
88+ # top half
89+ port_x = width - (port_width / 2 )
90+ port_y = node_center_y - (port_height / 2 )
91+ for idx , port in enumerate (reversed (outputs [:middle_idx ])):
92+ if idx == 0 :
93+ if is_odd :
94+ port_x -= (port_width / 2 ) - (txt_offset / 2 )
95+ port_y -= port_height + spacing
96+ else :
97+ port_y -= (port_height / 2 ) + spacing
98+ port .setPos (port_x , port_y )
99+ port_x -= (port_width / 2 ) - (txt_offset / 2 )
100+ port_y -= port_height + spacing
101+
102+ # bottom half
103+ port_x = width - (port_width / 2 )
104+ port_y = node_center_y - (port_height / 2 )
105+ for idx , port in enumerate (outputs [middle_idx :]):
106+ if idx == 0 :
107+ if not is_odd :
108+ port_y += (port_width / 2 ) - (txt_offset / 2 )
109+ port .setPos (port_x , port_y )
110+ port_x -= (port_width / 2 ) - (txt_offset / 2 )
111+ port_y += port_height + spacing
112+ else :
113+ port_x = width - (port_width / 2 )
114+ port_y = node_center_y - (port_height / 2 )
115+ outputs [0 ].setPos (port_x , port_y - (port_height / 2 ) + spacing )
116+ outputs [1 ].setPos (port_x , port_y + (port_height / 2 ) + spacing )
117+
118+ # adjust output text position
119+ for port , text in self ._output_items .items ():
120+ if port .isVisible ():
121+ txt_width = text .boundingRect ().width () - txt_offset
122+ txt_x = port .x () - txt_width
123+ text .setPos (txt_x , port .y () - 1.5 )
124+
125+ def _align_ports_vertical (self , v_offset ):
126+ height = self ._height
127+ node_center_x = self .boundingRect ().center ().x () + v_offset
128+
129+ # adjust input position
130+ inputs = [p for p in self .inputs if p .isVisible ()]
131+ if inputs :
132+ port_width = inputs [0 ].boundingRect ().width ()
133+ port_height = inputs [0 ].boundingRect ().height ()
134+
135+ count = len (inputs )
136+ if count > 2 :
137+ is_odd = bool (count % 2 )
138+ middle_idx = int (count / 2 )
139+
140+ delta = (self ._width / (len (inputs ) + 1 )) / 2
141+
142+ # left half
143+ port_x = node_center_x - (port_width / 2 )
144+ port_y = (port_height / 2 ) * - 1
145+ for idx , port in enumerate (reversed (inputs [:middle_idx ])):
146+ if idx == 0 :
147+ if is_odd :
148+ port_x -= (port_width / 2 ) + delta
149+ port_y += (port_height / 2 )
150+ else :
151+ port_x -= delta
152+ port .setPos (port_x , port_y )
153+ port_x -= (port_width / 2 ) + delta
154+ port_y += (port_height / 2 )
155+
156+ # right half
157+ port_x = node_center_x - (port_width / 2 )
158+ port_y = (port_height / 2 ) * - 1
159+ for idx , port in enumerate (inputs [middle_idx :]):
160+ if idx == 0 :
161+ if not is_odd :
162+ port_x += delta
163+ port .setPos (port_x , port_y )
164+ port_x += (port_width / 2 ) + delta
165+ port_y += (port_height / 2 )
166+
167+ # adjust output position
168+ outputs = [p for p in self .outputs if p .isVisible ()]
169+ if outputs :
170+ port_width = outputs [0 ].boundingRect ().width ()
171+ port_height = outputs [0 ].boundingRect ().height ()
172+
173+ count = len (outputs )
174+ if count > 2 :
175+ is_odd = bool (count % 2 )
176+ middle_idx = int (count / 2 )
177+
178+ delta = (self ._width / (len (outputs ) + 1 )) / 2
179+
180+ # left half
181+ port_x = node_center_x - (port_width / 2 )
182+ port_y = height - (port_height / 2 )
183+ for idx , port in enumerate (reversed (outputs [:middle_idx ])):
184+ if idx == 0 :
185+ if is_odd :
186+ port_x -= (port_width / 2 ) + delta
187+ port_y -= (port_height / 2 )
188+ else :
189+ port_x -= delta
190+ port .setPos (port_x , port_y )
191+ port_x -= (port_width / 2 ) + delta
192+ port_y -= (port_height / 2 )
193+
194+ # right half
195+ port_x = node_center_x - (port_width / 2 )
196+ port_y = height - (port_height / 2 )
197+ for idx , port in enumerate (outputs [middle_idx :]):
198+ if idx == 0 :
199+ if not is_odd :
200+ port_x += delta
201+ port .setPos (port_x , port_y )
202+ port_x += (port_width / 2 ) + delta
203+ port_y -= (port_height / 2 )
204+
20205 def _paint_horizontal (self , painter , option , widget ):
21206 painter .save ()
22207
208+ # display node area for debugging
209+ # ----------------------------------------------------------------------
210+ # pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 80), 0.8)
211+ # pen.setStyle(QtCore.Qt.DotLine)
212+ # painter.setPen(pen)
213+ # painter.drawRect(self.boundingRect())
214+ # ----------------------------------------------------------------------
215+
23216 text_rect = self ._text_item .boundingRect ()
24217 text_width = text_rect .width ()
25218 if text_width < 20.0 :
@@ -60,7 +253,7 @@ def _paint_horizontal(self, painter, option, widget):
60253 )
61254 path = QtGui .QPainterPath ()
62255 path .moveTo (pt1 )
63- path .lineTo (QtCore .QPointF (pt1 .x () + 4.0 , pt1 .y ()))
256+ # path.lineTo(QtCore.QPointF(pt1.x() + 4.0, pt1.y()))
64257 path .lineTo (rect .center ())
65258 painter .drawPath (path )
66259
@@ -77,7 +270,7 @@ def _paint_horizontal(self, painter, option, widget):
77270 )
78271 path = QtGui .QPainterPath ()
79272 path .moveTo (pt1 )
80- path .lineTo (QtCore .QPointF (pt1 .x () - 2.0 , pt1 .y ()))
273+ # path.lineTo(QtCore.QPointF(pt1.x() - 2.0, pt1.y()))
81274 path .lineTo (rect .center ())
82275 painter .drawPath (path )
83276
@@ -124,6 +317,15 @@ def _paint_horizontal(self, painter, option, widget):
124317
125318 def _paint_vertical (self , painter , option , widget ):
126319 painter .save ()
320+
321+ # display node area for debugging
322+ # ----------------------------------------------------------------------
323+ # pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 80), 0.8)
324+ # pen.setStyle(QtCore.Qt.DotLine)
325+ # painter.setPen(pen)
326+ # painter.drawRect(self.boundingRect())
327+ # ----------------------------------------------------------------------
328+
127329 rect = self .boundingRect ()
128330 width = min (rect .width (), rect .height ()) / 1.8
129331 rect = QtCore .QRectF (
@@ -202,6 +404,45 @@ def _align_icon_vertical(self, h_offset, v_offset):
202404 y = rect .center ().y () - (icon_rect .height () / 2 )
203405 self ._icon_item .setPos (x + h_offset , y + v_offset )
204406
407+ def _align_widgets_horizontal (self , v_offset ):
408+ if not self ._widgets :
409+ return
410+ rect = self .boundingRect ()
411+ y = rect .bottom () + v_offset
412+ inputs = [p for p in self .inputs if p .isVisible ()]
413+ outputs = [p for p in self .outputs if p .isVisible ()]
414+ for widget in self ._widgets .values ():
415+ widget_rect = widget .boundingRect ()
416+ if not inputs :
417+ x = rect .left () + 10
418+ widget .widget ().setTitleAlign ('left' )
419+ elif not outputs :
420+ x = rect .right () - widget_rect .width () - 10
421+ widget .widget ().setTitleAlign ('right' )
422+ else :
423+ x = rect .center ().x () - (widget_rect .width () / 2 )
424+ widget .widget ().setTitleAlign ('center' )
425+ widget .setPos (x , y )
426+ y += widget_rect .height ()
427+
428+ def _align_widgets_vertical (self , v_offset ):
429+ if not self ._widgets :
430+ return
431+ rect = self .boundingRect ()
432+ y = rect .center ().y () + v_offset
433+ widget_height = 0.0
434+ for widget in self ._widgets .values ():
435+ widget_rect = widget .boundingRect ()
436+ widget_height += widget_rect .height ()
437+ y -= widget_height / 2
438+
439+ for widget in self ._widgets .values ():
440+ widget_rect = widget .boundingRect ()
441+ x = rect .center ().x () - (widget_rect .width () / 2 )
442+ widget .widget ().setTitleAlign ('center' )
443+ widget .setPos (x , y )
444+ y += widget_rect .height ()
445+
205446 def _align_label_horizontal (self , h_offset , v_offset ):
206447 rect = self .boundingRect ()
207448 text_rect = self ._text_item .boundingRect ()
@@ -212,19 +453,30 @@ def _align_label_horizontal(self, h_offset, v_offset):
212453 def _align_label_vertical (self , h_offset , v_offset ):
213454 rect = self .boundingRect ()
214455 text_rect = self ._text_item .boundingRect ()
215- x = rect .right () - (rect .width () / 3 )
456+ x = rect .right () - (rect .width () / 4 )
216457 y = rect .center ().y () - (text_rect .height () / 2 )
217458 self ._text_item .setPos (x + h_offset , y + v_offset )
218459
219460 def _draw_node_horizontal (self ):
220- add_width = self .text_item .boundingRect ().width () * 1.5
221- add_height = self .text_item .boundingRect ().width () / 2
222-
223461 # update port text items in visibility.
462+ text_width = 0
463+ port_widths = 0
224464 for port , text in self ._input_items .items ():
225465 text .setVisible (port .display_name )
466+ if port .display_name :
467+ if text .boundingRect ().width () > text_width :
468+ text_width = text .boundingRect ().width ()
469+ port_widths += port .boundingRect ().width () / len (self ._input_items )
470+
226471 for port , text in self ._output_items .items ():
227472 text .setVisible (port .display_name )
473+ if port .display_name :
474+ if text .boundingRect ().width () > text_width :
475+ text_width = text .boundingRect ().width ()
476+ port_widths += port .boundingRect ().width () / len (self ._output_items )
477+
478+ add_width = (text_width * 2 ) + port_widths
479+ add_height = self .text_item .boundingRect ().width () / 2
228480
229481 # setup initial base size.
230482 self ._set_base_size (add_w = add_width , add_h = add_height )
@@ -241,21 +493,28 @@ def _draw_node_horizontal(self):
241493 # arrange icon
242494 self .align_icon ()
243495 # arrange input and output ports.
244- self .align_ports (v_offset = add_height / 2 )
496+ self .align_ports ()
245497 # arrange node widgets
246498 self .align_widgets (v_offset = 0.0 )
247499
248500 self .update ()
249501
250502 def _draw_node_vertical (self ):
503+ add_height = 0
504+
251505 # hide the port text items in vertical layout.
252506 for port , text in self ._input_items .items ():
253507 text .setVisible (False )
508+ add_height += port .boundingRect ().height () / 2
254509 for port , text in self ._output_items .items ():
255510 text .setVisible (False )
511+ add_height += port .boundingRect ().height () / 2
512+
513+ if add_height < 50 :
514+ add_height = 50
256515
257516 # setup initial base size.
258- self ._set_base_size (add_w = 50 , add_h = 50 )
517+ self ._set_base_size (add_w = 50 , add_h = add_height )
259518 # set text color when node is initialized.
260519 self ._set_text_color (self .text_color )
261520 # set the tooltip
0 commit comments