Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 109 additions & 14 deletions NodeGraphQt/qgraphics/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,33 @@ def delete(self):


class LivePipeItem(PipeItem):
"""
Live Pipe item used for drawing the live connection with the cursor.
"""

def __init__(self):
super(LivePipeItem, self).__init__()
self.setZValue(Z_VAL_NODE_WIDGET + 1)
self.shift_selected = False

color = QtGui.QColor(*PipeEnum.ACTIVE_COLOR.value)
pen = QtGui.QPen(color, PipeEnum.WIDTH.value + 0.35)
pen.setJoinStyle(QtCore.Qt.MiterJoin)
pen.setCapStyle(QtCore.Qt.RoundCap)

self._idx_pointer = LivePipePolygonItem(self)
self._idx_pointer.setPolygon(self._arrow)
self._idx_pointer.setBrush(color.darker(300))
self._idx_pointer.setPen(pen)

color = QtGui.QColor(*PipeEnum.ACTIVE_COLOR.value)
color.setAlpha(50)
self._idx_text = QtWidgets.QGraphicsTextItem(self)
self._idx_text.setDefaultTextColor(color)
font = self._idx_text.font()
font.setPointSize(7)
self._idx_text.setFont(font)

def paint(self, painter, option, widget):
"""
Draws the connection line.
Expand Down Expand Up @@ -449,21 +470,12 @@ def paint(self, painter, option, widget):
cen_y = self.path().pointAtPercent(0.5).y()
loc_pt = self.path().pointAtPercent(0.9)
tgt_pt = self.path().pointAtPercent(1.0)
start_pt = self.path().pointAtPercent(0.0)

dist = math.hypot(tgt_pt.x() - cen_x, tgt_pt.y() - cen_y)
if dist < 0.05:
painter.restore()
return

# draw start circle
size = 5.0
rect = QtCore.QRectF(start_pt.x() - (size / 2),
start_pt.y() - (size / 2),
size, size)
painter.setBrush(color)
painter.drawEllipse(rect)

# draw middle circle
size = 10.0
if dist < 50.0:
Expand All @@ -490,9 +502,92 @@ def paint(self, painter, option, widget):
degrees = math.degrees(radians) + 90
transform.rotate(degrees)

scale = 1.0
if dist < 20.0:
scale = dist / 20.0
transform.scale(scale, scale)
painter.drawPolygon(transform.map(self._arrow))
painter.restore()

def draw_path(self, start_port, end_port=None, cursor_pos=None,
color_mode=None):
"""
re-implemented to also update the index pointer arrow position.

Args:
start_port (PortItem): port used to draw the starting point.
end_port (PortItem): port used to draw the end point.
cursor_pos (QtCore.QPointF): cursor position if specified this
will be the draw end point.
color_mode (str): arrow index pointer color mode
('accept', 'reject' or None).
"""
super(LivePipeItem, self).draw_path(start_port, end_port, cursor_pos)
self.draw_index_pointer(start_port, cursor_pos, color_mode)

def draw_index_pointer(self, start_port, cursor_pos, color_mode=None):
"""
Update the index pointer arrow position and direction when the
live pipe path is redrawn.

Args:
start_port (PortItem): start port item.
cursor_pos (QtCore.QPoint): cursor scene position.
color_mode (str): arrow index pointer color mode
('accept', 'reject' or None).
"""
text_rect = self._idx_text.boundingRect()

transform = QtGui.QTransform()
transform.translate(cursor_pos.x(), cursor_pos.y())
if self.viewer_layout_direction() is LayoutDirectionEnum.VERTICAL.value:
text_pos = (
cursor_pos.x() + (text_rect.width() / 2.5),
cursor_pos.y() - (text_rect.height() / 2)
)
if start_port.port_type == PortTypeEnum.OUT.value:
transform.rotate(180)
elif self.viewer_layout_direction() is LayoutDirectionEnum.HORIZONTAL.value:
text_pos = (
cursor_pos.x() - (text_rect.width() / 2),
cursor_pos.y() - (text_rect.height() * 1.25)
)
if start_port.port_type == PortTypeEnum.IN.value:
transform.rotate(-90)
else:
transform.rotate(90)
self._idx_text.setPos(*text_pos)
self._idx_text.setPlainText('{}'.format(start_port.name))

self._idx_pointer.setPolygon(transform.map(self._arrow))

if color_mode == 'accept':
color = QtGui.QColor(*PipeEnum.HIGHLIGHT_COLOR.value)
elif color_mode == 'reject':
color = QtGui.QColor(*PipeEnum.DISABLED_COLOR.value)
else:
color = QtGui.QColor(*PipeEnum.ACTIVE_COLOR.value)

pen = self._idx_pointer.pen()
pen.setColor(color)
self._idx_pointer.setBrush(color.darker(300))
self._idx_pointer.setPen(pen)


class LivePipePolygonItem(QtWidgets.QGraphicsPolygonItem):
"""
Custom live pipe polygon shape.
"""

def __init__(self, parent):
super(LivePipePolygonItem, self).__init__(parent)
self.setFlag(self.ItemIsSelectable, True)

def paint(self, painter, option, widget):
"""
Args:
painter (QtGui.QPainter): painter used for drawing the item.
option (QtGui.QStyleOptionGraphicsItem):
used to describe the parameters needed to draw.
widget (QtWidgets.QWidget): not used.
"""
painter.save()
painter.setBrush(self.brush())
painter.setPen(self.pen())
painter.drawPolygon(self.polygon())
painter.restore()
34 changes: 25 additions & 9 deletions NodeGraphQt/widgets/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ def keyReleaseEvent(self, event):
def sceneMouseMoveEvent(self, event):
"""
triggered mouse move event for the scene.
- redraw the connection pipe.
- redraw the live connection pipe.

Args:
event (QtWidgets.QGraphicsSceneMouseEvent):
Expand All @@ -649,15 +649,27 @@ def sceneMouseMoveEvent(self, event):
return

pos = event.scenePos()
items = self.scene().items(pos)
if items and isinstance(items[0], PortItem):
x = items[0].boundingRect().width() / 2
y = items[0].boundingRect().height() / 2
pos = items[0].scenePos()
pos.setX(pos.x() + x)
pos.setY(pos.y() + y)
color_mode = None
for item in self.scene().items(pos):
if isinstance(item, PortItem):
x = item.boundingRect().width() / 2
y = item.boundingRect().height() / 2
pos = item.scenePos()
pos.setX(pos.x() + x)
pos.setY(pos.y() + y)
if item == self._start_port:
break
color_mode = 'accept'
if self.acyclic:
if item.node == self._start_port.node:
color_mode = 'reject'
elif item.port_type == self._start_port.port_type:
color_mode = 'reject'
break

self._LIVE_PIPE.draw_path(self._start_port, cursor_pos=pos)
self._LIVE_PIPE.draw_path(
self._start_port, cursor_pos=pos, color_mode=color_mode
)

def sceneMousePressEvent(self, event):
"""
Expand Down Expand Up @@ -874,6 +886,10 @@ def start_live_connection(self, selected_port):
elif self._start_port == PortTypeEnum.OUT.value:
self._LIVE_PIPE.output_port = self._start_port
self._LIVE_PIPE.setVisible(True)
self._LIVE_PIPE.draw_index_pointer(
selected_port,
self.mapToScene(self._origin_pos)
)

def end_live_connection(self):
"""
Expand Down