Skip to content

Commit

Permalink
node/port visibility support #310
Browse files Browse the repository at this point in the history
  • Loading branch information
jchanvfx committed Mar 21, 2023
1 parent b7c9810 commit 11aa7cf
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 26 deletions.
76 changes: 63 additions & 13 deletions NodeGraphQt/base/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, node, name, value):
self.old_val = node.get_property(name)
self.new_val = value

def set_node_prop(self, name, value):
def set_node_property(self, name, value):
"""
updates the node view and model.
"""
Expand All @@ -47,21 +47,60 @@ def set_node_prop(self, name, value):
name = 'xy_pos'
setattr(view, name, value)

# emit property changed signal.
graph = self.node.graph
graph.property_changed.emit(self.node, self.name, value)

def undo(self):
if self.old_val != self.new_val:
self.set_node_prop(self.name, self.old_val)

# emit property changed signal.
graph = self.node.graph
graph.property_changed.emit(self.node, self.name, self.old_val)
self.set_node_property(self.name, self.old_val)

def redo(self):
if self.old_val != self.new_val:
self.set_node_prop(self.name, self.new_val)
self.set_node_property(self.name, self.new_val)

# emit property changed signal.
graph = self.node.graph
graph.property_changed.emit(self.node, self.name, self.new_val)

class NodeVisibleCmd(QtWidgets.QUndoCommand):
"""
Node visibility changed command.
Args:
node (NodeGraphQt.NodeObject): node.
visible (bool): node visible value.
"""

def __init__(self, node, visible):
QtWidgets.QUndoCommand.__init__(self)
self.node = node
self.visible = visible
self.selected = self.node.selected()

def set_node_visible(self, visible):
model = self.node.model
model.set_property('visible', visible)

node_view = self.node.view
node_view.setVisible(visible)

# redraw the connected pipes in the scene.
ports = node_view.inputs + node_view.outputs
for port in ports:
for pipe in port.connected_pipes:
pipe.update()

# restore the node selected state.
if self.selected != node_view.isSelected():
node_view.setSelected(model.selected)

# emit property changed signal.
graph = self.node.graph
graph.property_changed.emit(self.node, 'visible', visible)

def undo(self):
self.set_node_visible(not self.visible)

def redo(self):
self.set_node_visible(self.visible)


class NodeMovedCmd(QtWidgets.QUndoCommand):
Expand Down Expand Up @@ -347,10 +386,14 @@ class PortVisibleCmd(QtWidgets.QUndoCommand):
port (NodeGraphQt.Port): node port.
"""

def __init__(self, port):
def __init__(self, port, visible):
QtWidgets.QUndoCommand.__init__(self)
self.port = port
self.visible = port.visible()
self.visible = visible
if visible:
self.setText('show port {}'.format(self.port.name()))
else:
self.setText('hide port {}'.format(self.port.name()))

def set_visible(self, visible):
self.port.model.visible = visible
Expand All @@ -363,7 +406,14 @@ def set_visible(self, visible):
text_item = node_view.get_output_text_item(self.port.view)
if text_item:
text_item.setVisible(visible)
node_view.post_init()

node_view.draw_node()

# redraw the connected pipes in the scene.
ports = node_view.inputs + node_view.outputs
for port in node_view.inputs + node_view.outputs:
for pipe in port.connected_pipes:
pipe.update()

def undo(self):
self.set_visible(not self.visible)
Expand Down
19 changes: 8 additions & 11 deletions NodeGraphQt/base/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,20 @@ def visible(self):
"""
return self.model.visible

def set_visible(self, visible=True):
def set_visible(self, visible=True, push_undo=True):
"""
Sets weather the port should be visible or not.
Args:
visible (bool): true if visible.
push_undo (bool): register the command to the undo stack. (default: True)
"""
self.model.visible = visible
label = 'show' if visible else 'hide'
undo_stack = self.node().graph.undo_stack()
undo_stack.beginMacro('{} port {}'.format(label, self.name()))

for port in self.connected_ports():
undo_stack.push(PortDisconnectedCmd(self, port))

undo_stack.push(PortVisibleCmd(self))
undo_stack.endMacro()
undo_cmd = PortVisibleCmd(self, visible)
if push_undo:
undo_stack = self.node().graph.undo_stack()
undo_stack.push(undo_cmd)
else:
undo_cmd.redo()

def locked(self):
"""
Expand Down
29 changes: 29 additions & 0 deletions NodeGraphQt/nodes/base_node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/python
from collections import OrderedDict

from NodeGraphQt.base.commands import NodeVisibleCmd
from NodeGraphQt.base.node import NodeObject
from NodeGraphQt.base.port import Port
from NodeGraphQt.constants import NodePropWidgetEnum, PortTypeEnum
Expand Down Expand Up @@ -68,6 +69,34 @@ def update_model(self):
for name, widget in self.view.widgets.items():
self.model.set_property(name, widget.get_value())

def set_property(self, name, value, push_undo=True):
"""
Set the value on the node custom property.
Note:
When setting the `"visible"` property to `False` all node
connections will be disconnected.
Args:
name (str): name of the property.
value (object): property data (python built in types).
push_undo (bool): register the command to the undo stack. (default: True)
"""
# prevent signals from causing a infinite loop.
if self.get_property(name) == value:
return

if name == 'visible':
if self.graph:
undo_cmd = NodeVisibleCmd(self, value)
if push_undo:
undo_stack = self.graph.undo_stack()
undo_stack.push(undo_cmd)
else:
undo_cmd.redo()
return
super(BaseNode, self).set_property(name, value, push_undo)

def set_layout_direction(self, value=0):
"""
Sets the node layout direction to either horizontal or vertical on
Expand Down
6 changes: 4 additions & 2 deletions NodeGraphQt/qgraphics/node_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,11 @@ def _draw_node_horizontal(self):

# update port text items in visibility.
for port, text in self._input_items.items():
text.setVisible(port.display_name)
if port.isVisible():
text.setVisible(port.display_name)
for port, text in self._output_items.items():
text.setVisible(port.display_name)
if port.isVisible():
text.setVisible(port.display_name)

# setup initial base size.
self._set_base_size(add_h=height)
Expand Down
15 changes: 15 additions & 0 deletions NodeGraphQt/qgraphics/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ def paint(self, painter, option, widget):
used to describe the parameters needed to draw.
widget (QtWidgets.QWidget): not used.
"""

# only draw if a port or node is visible.
is_visible = all([
self._input_port.isVisible(),
self._output_port.isVisible(),
self._input_port.node.isVisible(),
self._output_port.node.isVisible()
])
if not is_visible:
painter.save()
painter.setBrush(QtCore.Qt.NoBrush)
painter.setPen(QtCore.Qt.NoPen)
painter.restore()
return

color = QtGui.QColor(*self._color)
pen_style = PIPE_STYLES.get(self.style)
pen_width = PipeEnum.WIDTH.value
Expand Down

0 comments on commit 11aa7cf

Please sign in to comment.