Skip to content

Commit 8446a52

Browse files
committed
port connection updates.
1 parent bd431af commit 8446a52

File tree

5 files changed

+120
-44
lines changed

5 files changed

+120
-44
lines changed

NodeGraphQt/base/commands.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,60 @@ def redo(self):
163163
self.node.view.delete()
164164

165165

166+
class NodeInputConnectedCmd(QtWidgets.QUndoCommand):
167+
"""
168+
"BaseNode.on_input_connected()" command.
169+
170+
Args:
171+
src_port (NodeGraphQt.Port): source port.
172+
trg_port (NodeGraphQt.Port): target port.
173+
"""
174+
175+
def __init__(self, src_port, trg_port):
176+
QtWidgets.QUndoCommand.__init__(self)
177+
if src_port.type_() == IN_PORT:
178+
self.source = src_port
179+
self.target = trg_port
180+
else:
181+
self.source = trg_port
182+
self.target = src_port
183+
184+
def undo(self):
185+
node = self.source.node()
186+
node.on_input_disconnected(self.source, self.target)
187+
188+
def redo(self):
189+
node = self.source.node()
190+
node.on_input_connected(self.source, self.target)
191+
192+
193+
class NodeInputDisconnectedCmd(QtWidgets.QUndoCommand):
194+
"""
195+
Node "on_input_disconnected()" command.
196+
197+
Args:
198+
src_port (NodeGraphQt.Port): source port.
199+
trg_port (NodeGraphQt.Port): target port.
200+
"""
201+
202+
def __init__(self, src_port, trg_port):
203+
QtWidgets.QUndoCommand.__init__(self)
204+
if src_port.type_() == IN_PORT:
205+
self.source = src_port
206+
self.target = trg_port
207+
else:
208+
self.source = trg_port
209+
self.target = src_port
210+
211+
def undo(self):
212+
node = self.source.node()
213+
node.on_input_connected(self.source, self.target)
214+
215+
def redo(self):
216+
node = self.source.node()
217+
node.on_input_disconnected(self.source, self.target)
218+
219+
166220
class PortConnectedCmd(QtWidgets.QUndoCommand):
167221
"""
168222
Port connected command.

NodeGraphQt/base/graph.py

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@ class NodeGraph(QtCore.QObject):
2727
base node graph controller.
2828
"""
2929

30-
#: (signal) emits the node object when a node is created in the node graph.
30+
#:QtCore.Signal: emits the node object when a node is created in the node graph.
3131
node_created = QtCore.Signal(NodeObject)
32-
#: (signal) emits a list of node ids from the deleted nodes.
32+
#:QtCore.Signal: emits a ``list[str]`` of node ids from the deleted nodes.
3333
nodes_deleted = QtCore.Signal(list)
34-
#: (signal) emits the node object when selected in the node graph.
34+
#:QtCore.Signal: emits the node object when selected in the node graph.
3535
node_selected = QtCore.Signal(NodeObject)
36-
#: (signal) triggered when a node is double clicked and emits the node.
36+
#:QtCore.Signal: triggered when a node is double clicked and emits the node.
3737
node_double_clicked = QtCore.Signal(NodeObject)
38-
#: (signal) for when a node has been connected emits (source port, target port).
38+
#:QtCore.Signal: for when a node has been connected emits (``input port``, ``output port``).
3939
port_connected = QtCore.Signal(Port, Port)
40-
#: (signal) for when a node has been disconnected emits (source port, target port).
40+
#:QtCore.Signal: for when a node has been disconnected emits (``input port``, ``output port``).
4141
port_disconnected = QtCore.Signal(Port, Port)
42-
#: (signal) for when a node property has changed emits (node, property name, property value).
42+
#:QtCore.Signal: for when a node property has changed emits (``node``, ``property name``, ``property value``).
4343
property_changed = QtCore.Signal(NodeObject, str, object)
44-
#: (signal) for when drop data has been added to the graph.
44+
#:QtCore.Signal: for when drop data has been added to the graph.
4545
data_dropped = QtCore.Signal(QtCore.QMimeData, QtCore.QPoint)
4646

4747
def __init__(self, parent=None):
@@ -75,9 +75,6 @@ def _wire_signals(self):
7575
self._viewer.node_selected.connect(self._on_node_selected)
7676
self._viewer.data_dropped.connect(self._on_node_data_dropped)
7777

78-
# node events.
79-
self.port_connected.connect(self._on_port_connected)
80-
8178
def _toggle_tab_search(self):
8279
"""
8380
toggle the tab search widget.
@@ -101,22 +98,6 @@ def _on_property_bin_changed(self, node_id, prop_name, prop_value):
10198
if node.get_property(prop_name) != prop_value:
10299
node.set_property(prop_name, prop_value)
103100

104-
def _on_port_connected(self, src_port, tgt_port):
105-
"""
106-
called when a port connection has been made.
107-
(executes the "on_input_connected" method on the node.)
108-
109-
Args:
110-
src_port (NodeGraphQt.Port): source port.
111-
tgt_port (NodeGraphQt.Port): target port.
112-
"""
113-
if tgt_port.type_() == IN_PORT:
114-
node = tgt_port.node()
115-
node.on_input_connected(tgt_port, src_port)
116-
elif tgt_port.type_() == OUT_PORT:
117-
node = src_port.node()
118-
node.on_input_connected(src_port, tgt_port)
119-
120101
def _on_node_double_clicked(self, node_id):
121102
"""
122103
called when a node in the viewer is double click.
@@ -263,14 +244,14 @@ def widget(self):
263244
def show(self):
264245
"""
265246
Show node graph widget this is just a convenience
266-
function to :meth:`NodeGraphQt.NodeGraph.widget.show()`.
247+
function to :meth:`NodeGraph.widget().show()`.
267248
"""
268249
self._widget.show()
269250

270251
def close(self):
271252
"""
272253
Close node graph NodeViewer widget this is just a convenience
273-
function to :meth:`NodeGraphQt.NodeGraph.widget.close()`.
254+
function to :meth:`NodeGraph.widget().close()`.
274255
"""
275256
self._widget.close()
276257

@@ -377,7 +358,7 @@ def clear_undo_stack(self):
377358
378359
Note:
379360
Convenience function to
380-
:meth:`NodeGraphQt.NodeGraph.undo_stack().clear`
361+
:meth:`NodeGraph.undo_stack().clear()`
381362
382363
See Also:
383364
:meth:`NodeGraph.begin_undo()`,
@@ -793,14 +774,16 @@ def _serialize(self, nodes):
793774
for pname, conn_data in inputs.items():
794775
for conn_id, prt_names in conn_data.items():
795776
for conn_prt in prt_names:
796-
pipe = {'in': [n_id, pname], 'out': [conn_id, conn_prt]}
777+
pipe = {IN_PORT: [n_id, pname],
778+
OUT_PORT: [conn_id, conn_prt]}
797779
if pipe not in serial_data['connections']:
798780
serial_data['connections'].append(pipe)
799781

800782
for pname, conn_data in outputs.items():
801783
for conn_id, prt_names in conn_data.items():
802784
for conn_prt in prt_names:
803-
pipe = {'out': [n_id, pname], 'in': [conn_id, conn_prt]}
785+
pipe = {OUT_PORT: [n_id, pname],
786+
IN_PORT: [conn_id, conn_prt]}
804787
if pipe not in serial_data['connections']:
805788
serial_data['connections'].append(pipe)
806789

NodeGraphQt/base/node.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ class NodeObject(object):
3333
qgraphics_item (AbstractNodeItem): graphic item used for drawing.
3434
"""
3535

36-
#: (str) unique node identifier domain. (default: "nodeGraphQt.nodes")
36+
#:str: unique node identifier domain.
3737
__identifier__ = 'nodeGraphQt.nodes'
3838

39-
#: (str) base node name.
39+
#:str: base node name.
4040
NODE_NAME = None
4141

4242
def __init__(self, qgraphics_item=None):
@@ -261,7 +261,7 @@ def get_property(self, name):
261261
object: property data.
262262
"""
263263
if self.graph and name == 'selected':
264-
self.model.set_property(self.view.selected)
264+
self.model.set_property(name, self.view.selected)
265265

266266
return self.model.get_property(name)
267267

@@ -628,15 +628,36 @@ def connected_output_nodes(self):
628628

629629
def on_input_connected(self, in_port, out_port):
630630
"""
631-
Callback function that is triggered when a OUTPUT port from another
632-
node has connected to a INPUT port for this node.
631+
Callback triggered when a new pipe connection is made.
632+
633+
*The default of this function does nothing re-implement if you require
634+
logic to run for this event.*
635+
636+
Note:
637+
to work with undo & redo for this method re-implement
638+
:meth:`BaseNode.on_input_disconnected` with the reverse logic.
639+
640+
Args:
641+
in_port (NodeGraphQt.Port): source input port from this node.
642+
out_port (NodeGraphQt.Port): output port that connected to this node.
643+
"""
644+
return
645+
646+
def on_input_disconnected(self, in_port, out_port):
647+
"""
648+
Callback triggered when a pipe connection has been disconnected
649+
from a INPUT port.
650+
651+
*The default of this function does nothing re-implement if you require
652+
logic to run for this event.*
633653
634654
Note:
635-
re-implement this function if you require logic to run for this event.
655+
to work with undo & redo for this method re-implement
656+
:meth:`BaseNode.on_input_connected` with the reverse logic.
636657
637658
Args:
638-
in_port (NodeGraphQt.Port): input port from this node.
639-
out_port (NodeGraphQt.Port): output port connecting to this node.
659+
in_port (NodeGraphQt.Port): source input port from this node.
660+
out_port (NodeGraphQt.Port): output port that was disconnected.
640661
"""
641662
return
642663

NodeGraphQt/base/port.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/python
22
from NodeGraphQt.base.commands import (PortConnectedCmd,
33
PortDisconnectedCmd,
4-
PortVisibleCmd)
4+
PortVisibleCmd,
5+
NodeInputConnectedCmd,
6+
NodeInputDisconnectedCmd)
57
from NodeGraphQt.base.model import PortModel
68
from NodeGraphQt.constants import IN_PORT, OUT_PORT
79

@@ -138,8 +140,8 @@ def connect_to(self, port=None):
138140

139141
graph = self.node().graph
140142
viewer = graph.viewer()
141-
undo_stack = graph.undo_stack()
142143

144+
undo_stack = graph.undo_stack()
143145
undo_stack.beginMacro('connect port')
144146

145147
pre_conn_port = None
@@ -149,26 +151,33 @@ def connect_to(self, port=None):
149151

150152
if not port:
151153
if pre_conn_port:
154+
undo_stack.push(NodeInputDisconnectedCmd(self, port))
152155
undo_stack.push(PortDisconnectedCmd(self, port))
153156
return
154157

155158
if graph.acyclic() and viewer.acyclic_check(self.view, port.view):
156159
if pre_conn_port:
160+
undo_stack.push(NodeInputDisconnectedCmd(self, pre_conn_port))
157161
undo_stack.push(PortDisconnectedCmd(self, pre_conn_port))
158162
return
159163

160164
trg_conn_ports = port.connected_ports()
161165
if not port.multi_connection() and trg_conn_ports:
162166
dettached_port = trg_conn_ports[0]
167+
undo_stack.push(NodeInputDisconnectedCmd(port, dettached_port))
163168
undo_stack.push(PortDisconnectedCmd(port, dettached_port))
164169
if pre_conn_port:
170+
undo_stack.push(NodeInputDisconnectedCmd(self, pre_conn_port))
165171
undo_stack.push(PortDisconnectedCmd(self, pre_conn_port))
166172

173+
undo_stack.push(NodeInputConnectedCmd(self, port))
167174
undo_stack.push(PortConnectedCmd(self, port))
175+
168176
undo_stack.endMacro()
169177

170178
# emit "port_connected" signal from the parent graph.
171-
graph.port_connected.emit(self, port)
179+
ports = {p.type_(): p for p in [self, port]}
180+
graph.port_connected.emit(ports[IN_PORT], ports[OUT_PORT])
172181

173182
def disconnect_from(self, port=None):
174183
"""
@@ -181,7 +190,11 @@ def disconnect_from(self, port=None):
181190
if not port:
182191
return
183192
graph = self.node().graph
193+
graph.undo_stack().beginMacro('disconnect port')
194+
graph.undo_stack().push(NodeInputDisconnectedCmd(self, port))
184195
graph.undo_stack().push(PortDisconnectedCmd(self, port))
196+
graph.undo_stack().endMacro()
185197

186198
# emit "port_disconnected" signal from the parent graph.
187-
graph.port_disconnected.emit(self, port)
199+
ports = {p.type_(): p for p in [self, port]}
200+
graph.port_disconnected.emit(ports[IN_PORT], ports[OUT_PORT])

docs/_static/ngqt.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ code span.pre {
4242
color: #5cafb9;
4343
}
4444

45+
/* properties */
46+
em.property {
47+
color: #5d86c3;
48+
}
49+
4550
/* tables */
4651
table.docutils td,
4752
table.docutils th {

0 commit comments

Comments
 (0)