@@ -158,6 +158,46 @@ def paint(self, painter, option, widget):
158158 # QPaintDevice: Cannot destroy paint device that is being painted.
159159 painter .restore ()
160160
161+ def __draw_path_cycled_vertical (self , start_port , pos1 , pos2 , path ):
162+ """
163+ Draws the pipe path around the node if the in port and out port
164+ connect to each other for cycle connection.
165+
166+ Args:
167+ start_port (PortItem): port used to draw the starting point.
168+ pos1 (QPointF): start port position.
169+ pos2 (QPointF): end port position.
170+ path (QPainterPath): path to draw.
171+ """
172+
173+ def __draw_path_cycled_horizontal (self , start_port , pos1 , pos2 , path ):
174+ """
175+ Draws the pipe path around the node if the in port and out port
176+ connect to each other for cycle connection.
177+
178+ Args:
179+ start_port (PortItem): port used to draw the starting point.
180+ pos1 (QPointF): start port position.
181+ pos2 (QPointF): end port position.
182+ path (QPainterPath): path to draw.
183+ """
184+ ptype = start_port .port_type
185+ in_pos = pos1 if ptype == PortTypeEnum .IN .value else pos2
186+ out_pos = pos2 if ptype == PortTypeEnum .IN .value else pos1
187+
188+ n_rect = start_port .node .boundingRect ()
189+ padding = 40
190+
191+ left = out_pos .x () + padding
192+ right = in_pos .x () - padding
193+ path .moveTo (out_pos )
194+ path .lineTo (left , out_pos .y ())
195+ path .lineTo (left , out_pos .y () + n_rect .bottom ())
196+ path .lineTo (right , out_pos .y () + n_rect .bottom ())
197+ path .lineTo (right , in_pos .y ())
198+ path .lineTo (in_pos )
199+ self .setPath (path )
200+
161201 def __draw_path_vertical (self , start_port , pos1 , pos2 , path ):
162202 """
163203 Draws the vertical path between ports.
@@ -274,45 +314,76 @@ def draw_path(self, start_port, end_port=None, cursor_pos=None):
274314 path = QtGui .QPainterPath ()
275315 path .moveTo (line .x1 (), line .y1 ())
276316
317+ direction = self .viewer_layout_direction ()
318+
319+ if end_port and not self .viewer ().acyclic :
320+ if end_port .node == start_port .node :
321+ if direction is LayoutDirectionEnum .VERTICAL .value :
322+ self .__draw_path_cycled_vertical (
323+ start_port , pos1 , pos2 , path
324+ )
325+ return
326+ elif direction is LayoutDirectionEnum .HORIZONTAL .value :
327+ self .__draw_path_cycled_horizontal (
328+ start_port , pos1 , pos2 , path
329+ )
330+ return
331+
277332 if self .viewer_pipe_layout () == PipeLayoutEnum .STRAIGHT .value :
278333 path .lineTo (pos2 )
279334 self .setPath (path )
280335 return
281336
282- if self . viewer_layout_direction () is LayoutDirectionEnum .VERTICAL .value :
337+ if direction is LayoutDirectionEnum .VERTICAL .value :
283338 self .__draw_path_vertical (start_port , pos1 , pos2 , path )
284- elif self . viewer_layout_direction () is LayoutDirectionEnum .HORIZONTAL .value :
339+ elif direction is LayoutDirectionEnum .HORIZONTAL .value :
285340 self .__draw_path_horizontal (start_port , pos1 , pos2 , path )
286341
287342 def reset_path (self ):
288343 path = QtGui .QPainterPath (QtCore .QPointF (0.0 , 0.0 ))
289344 self .setPath (path )
290345
291346 @staticmethod
292- def calc_distance (p1 , p2 ):
347+ def _calc_distance (p1 , p2 ):
293348 x = math .pow ((p2 .x () - p1 .x ()), 2 )
294349 y = math .pow ((p2 .y () - p1 .y ()), 2 )
295350 return math .sqrt (x + y )
296351
297352 def port_from_pos (self , pos , reverse = False ):
298353 inport_pos = self .input_port .scenePos ()
299354 outport_pos = self .output_port .scenePos ()
300- input_dist = self .calc_distance (inport_pos , pos )
301- output_dist = self .calc_distance (outport_pos , pos )
355+ input_dist = self ._calc_distance (inport_pos , pos )
356+ output_dist = self ._calc_distance (outport_pos , pos )
302357 if input_dist < output_dist :
303358 port = self .output_port if reverse else self .input_port
304359 else :
305360 port = self .input_port if reverse else self .output_port
306361 return port
307362
308- def viewer_pipe_layout (self ):
363+ def viewer (self ):
364+ """
365+ Returns:
366+ NodeViewer: node graph viewer.
367+ """
309368 if self .scene ():
310- viewer = self .scene ().viewer ()
369+ return self .scene ().viewer ()
370+
371+ def viewer_pipe_layout (self ):
372+ """
373+ Returns:
374+ int: pipe layout mode.
375+ """
376+ viewer = self .viewer ()
377+ if viewer :
311378 return viewer .get_pipe_layout ()
312379
313380 def viewer_layout_direction (self ):
314- if self .scene ():
315- viewer = self .scene ().viewer ()
381+ """
382+ Returns:
383+ int: graph layout mode.
384+ """
385+ viewer = self .viewer ()
386+ if viewer :
316387 return viewer .get_layout_direction ()
317388
318389 def activate (self ):
0 commit comments