diff --git a/NodeGraphQt/constants.py b/NodeGraphQt/constants.py index 781cfca1..986e5cd3 100644 --- a/NodeGraphQt/constants.py +++ b/NodeGraphQt/constants.py @@ -164,7 +164,7 @@ class PipeEnum(Enum): #: default color. COLOR = (175, 95, 30, 255) #: pipe color to a node when it's disabled. - DISABLED_COLOR = (190, 20, 20, 255) + DISABLED_COLOR = (200, 60, 60, 255) #: pipe color when selected or mouse over. ACTIVE_COLOR = (70, 255, 220, 255) #: pipe color to a node when it's selected. diff --git a/NodeGraphQt/nodes/base_node.py b/NodeGraphQt/nodes/base_node.py index 6031d590..e80fb89d 100644 --- a/NodeGraphQt/nodes/base_node.py +++ b/NodeGraphQt/nodes/base_node.py @@ -86,11 +86,16 @@ def set_property(self, name, value, push_undo=True): if self.graph: undo_cmd = NodeVisibleCmd(self, value) if push_undo: - undo_stack = self.graph.undo_stack() - undo_stack.push(undo_cmd) + self.graph.undo_stack().push(undo_cmd) else: undo_cmd.redo() return + elif name == 'disabled': + # redraw the connected pipes in the scene. + ports = self.view.inputs + self.view.outputs + for port in ports: + for pipe in port.connected_pipes: + pipe.update() super(BaseNode, self).set_property(name, value, push_undo) def set_layout_direction(self, value=0): diff --git a/NodeGraphQt/pkg_info.py b/NodeGraphQt/pkg_info.py index 0848489c..3f5f4766 100644 --- a/NodeGraphQt/pkg_info.py +++ b/NodeGraphQt/pkg_info.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -__version__ = '0.5.11' +__version__ = '0.5.12' __status__ = 'Work in Progress' __license__ = 'MIT' diff --git a/NodeGraphQt/qgraphics/pipe.py b/NodeGraphQt/qgraphics/pipe.py index 467f708c..f9edcabc 100644 --- a/NodeGraphQt/qgraphics/pipe.py +++ b/NodeGraphQt/qgraphics/pipe.py @@ -73,9 +73,10 @@ def hoverLeaveEvent(self, event): def itemChange(self, change, value): if change == self.ItemSelectedChange and self.scene(): - self.reset() if value: self.highlight() + else: + self.reset() return super(PipeItem, self).itemChange(change, value) def paint(self, painter, option, widget): @@ -95,6 +96,7 @@ def paint(self, painter, option, widget): if not self._active: pen.setColor(QtGui.QColor(*PipeEnum.DISABLED_COLOR.value)) pen.setStyle(PIPE_STYLES.get(PipeEnum.DRAW_TYPE_DOTTED.value)) + pen.setWidth(pen.width() * 1.25) painter.setPen(pen) painter.setBrush(self.brush()) @@ -118,6 +120,14 @@ def _draw_direction_pointer(self): self._dir_pointer.setVisible(False) return + if self.disabled(): + if not (self._active or self._highlight): + color = QtGui.QColor(*PipeEnum.DISABLED_COLOR.value) + pen = self._dir_pointer.pen() + pen.setColor(color) + self._dir_pointer.setPen(pen) + self._dir_pointer.setBrush(color.darker(200)) + self._dir_pointer.setVisible(True) loc_pt = self.path().pointAtPercent(0.49) tgt_pt = self.path().pointAtPercent(0.51) @@ -130,6 +140,11 @@ def _draw_direction_pointer(self): cen_x = self.path().pointAtPercent(0.5).x() cen_y = self.path().pointAtPercent(0.5).y() dist = math.hypot(tgt_pt.x() - cen_x, tgt_pt.y() - cen_y) + + self._dir_pointer.setVisible(True) + if dist < 0.3: + self._dir_pointer.setVisible(False) + return if dist < 1.0: self._dir_pointer.setScale(dist) @@ -285,6 +300,8 @@ def draw_path(self, start_port, end_port=None, cursor_pos=None): """ if not start_port: return + + # get start / end positions. pos1 = start_port.scenePos() pos1.setX(pos1.x() + (start_port.boundingRect().width() / 2)) pos1.setY(pos1.y() + (start_port.boundingRect().height() / 2)) @@ -352,6 +369,7 @@ def reset_path(self): """ path = QtGui.QPainterPath(QtCore.QPointF(0.0, 0.0)) self.setPath(path) + self._draw_direction_pointer() def port_from_pos(self, pos, reverse=False): """ @@ -451,8 +469,14 @@ def reset(self): self._active = False self._highlight = False self.set_pipe_styling(color=self.color, width=1.2, style=self.style) + self._draw_direction_pointer() def set_connections(self, port1, port2): + """ + Args: + port1 (PortItem): port item object. + port2 (PortItem): port item object. + """ ports = { port1.port_type: port1, port2.port_type: port2 @@ -463,6 +487,10 @@ def set_connections(self, port1, port2): ports[PortTypeEnum.OUT.value].add_pipe(self) def disabled(self): + """ + Returns: + bool: true if pipe is a disabled connection. + """ if self.input_port and self.input_port.node.disabled: return True if self.output_port and self.output_port.node.disabled: @@ -525,12 +553,11 @@ def __init__(self): super(LivePipeItem, self).__init__() self.setZValue(Z_VAL_NODE_WIDGET + 1) - self.shift_selected = False - - self._color = PipeEnum.ACTIVE_COLOR.value - self._style = PipeEnum.DRAW_TYPE_DASHED.value + self.color = PipeEnum.ACTIVE_COLOR.value + self.style = PipeEnum.DRAW_TYPE_DASHED.value + self.set_pipe_styling(color=self.color, width=2.8, style=self.style) - self.set_pipe_styling(color=self.color, width=2.5, style=self.style) + self.shift_selected = False self._idx_pointer = LivePipePolygonItem(self) self._idx_pointer.setPolygon(self._poly) @@ -549,6 +576,13 @@ def __init__(self): font.setPointSize(7) self._idx_text.setFont(font) + def hoverEnterEvent(self, event): + """ + re-implemented back to the base default behaviour or the pipe will + lose it styling when another pipe is selected. + """ + QtWidgets.QGraphicsPathItem.hoverEnterEvent(self, event) + def draw_path(self, start_port, end_port=None, cursor_pos=None, color_mode=None): """ diff --git a/NodeGraphQt/widgets/viewer.py b/NodeGraphQt/widgets/viewer.py index cf439544..63ba033b 100644 --- a/NodeGraphQt/widgets/viewer.py +++ b/NodeGraphQt/widgets/viewer.py @@ -11,7 +11,7 @@ PortTypeEnum, PipeLayoutEnum, ViewerEnum, - Z_VAL_NODE_WIDGET + Z_VAL_PIPE, ) from NodeGraphQt.qgraphics.node_abstract import AbstractNodeItem from NodeGraphQt.qgraphics.node_backdrop import BackdropNodeItem @@ -99,8 +99,9 @@ def __init__(self, parent=None, undo_stack=None): ))) text_color.setAlpha(50) self._cusor_text = QtWidgets.QGraphicsTextItem() + self._cusor_text.setFlag(self._cusor_text.ItemIsSelectable, False) self._cusor_text.setDefaultTextColor(text_color) - self._cusor_text.setZValue(Z_VAL_NODE_WIDGET + 1) + self._cusor_text.setZValue(Z_VAL_PIPE - 1) font = self._cusor_text.font() font.setPointSize(7) self._cusor_text.setFont(font) @@ -468,7 +469,19 @@ def mousePressEvent(self, event): self._rubber_band.setGeometry(rect) self._rubber_band.isActive = True - if self.LMB_state and (self.SHIFT_state or self.CTRL_state): + # stop here so we don't select a node. + if self.CTRL_state: + return + + # allow new live pipe with the shift modifier on port that allow + # for multi connection. + if self.SHIFT_state and pipes: + pipes[0].reset() + port = pipes[0].port_from_pos(map_pos, reverse=True) + if not port.locked and port.multi_connection: + self._cusor_text.setPlainText('') + self._cusor_text.setVisible(False) + self.start_live_connection(port) return if not self._LIVE_PIPE.isVisible(): @@ -567,7 +580,8 @@ def mouseMoveEvent(self, event): if not self.ALT_state: if self.SHIFT_state or self.CTRL_state: - self._cusor_text.setPos(self.mapToScene(event.pos())) + if not self._LIVE_PIPE.isVisible(): + self._cusor_text.setPos(self.mapToScene(event.pos())) if self.LMB_state and self._rubber_band.isActive: rect = QtCore.QRect(self._origin_pos, event.pos()).normalized() @@ -673,6 +687,10 @@ def keyPressEvent(self, event): self.ALT_state = True self.SHIFT_state = True + if self._LIVE_PIPE.isVisible(): + super(NodeViewer, self).keyPressEvent(event) + return + # show cursor text overlay_text = None self._cusor_text.setVisible(False)