Skip to content

Commit 3382159

Browse files
authored
Merge pull request #165 from ArnoChenFx/master
Add Undo View
2 parents 29f58f9 + 1290ac8 commit 3382159

File tree

19 files changed

+161
-146
lines changed

19 files changed

+161
-146
lines changed

NodeGraphQt/base/graph.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ def __init__(self, parent=None):
137137
super(NodeGraph, self).__init__(parent)
138138
self.setObjectName('NodeGraphQt')
139139
self._widget = None
140+
self._undo_view = None
140141
self._model = NodeGraphModel()
141142
self._viewer = NodeViewer()
142143
self._node_factory = NodeFactory()
@@ -387,6 +388,19 @@ def widget(self):
387388
layout.addWidget(self._viewer)
388389
return self._widget
389390

391+
@property
392+
def undo_view(self):
393+
"""
394+
Returns node graph undo view.
395+
396+
Returns:
397+
PySide2.QtWidgets.QUndoView: node graph undo view.
398+
"""
399+
if self._undo_view is None:
400+
self._undo_view = QtWidgets.QUndoView(self._undo_stack)
401+
self._undo_view.setWindowTitle("Undo View")
402+
return self._undo_view
403+
390404
@property
391405
def auto_update(self):
392406
"""
@@ -1358,9 +1372,11 @@ def cut_nodes(self, nodes=None):
13581372
Args:
13591373
nodes (list[NodeGraphQt.BaseNode]): list of nodes (default: selected nodes).
13601374
"""
1375+
self._undo_stack.beginMacro('cut nodes')
13611376
nodes = nodes or self.selected_nodes()
13621377
self.copy_nodes(nodes)
13631378
self.delete_nodes(nodes)
1379+
self._undo_stack.endMacro()
13641380

13651381
def paste_nodes(self):
13661382
"""

NodeGraphQt/base/node.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,12 +1088,6 @@ def run(self):
10881088
"""
10891089
return
10901090

1091-
def when_disabled(self):
1092-
"""
1093-
Node evaluation logic when node has been disabled.
1094-
"""
1095-
return
1096-
10971091
def set_editable(self, state):
10981092
"""
10991093
Returns whether the node view widgets is editable.
@@ -1104,6 +1098,16 @@ def set_editable(self, state):
11041098
[wid.setEnabled(state) for wid in self.view._widgets.values()]
11051099
self.view.text_item.setEnabled(state)
11061100

1101+
def set_dynamic_port(self, state):
1102+
"""
1103+
Set whether the node will delete/add port after node has been created.
1104+
1105+
Args:
1106+
state(bool): If True, all port data will be serialized with the node,
1107+
when the node is been deserialized, all ports will restore.
1108+
"""
1109+
self.model.dynamic_port = state
1110+
11071111

11081112
class BackdropNode(NodeObject):
11091113
"""

NodeGraphQt/base/port.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,6 @@ def data_type(self):
221221
def data_type(self, data_type):
222222
self.__model.data_type = data_type
223223

224-
225224
@property
226225
def border_color(self):
227226
return self.__view.border_color

NodeGraphQt/base/utils.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def setup_context_menu(graph):
6666

6767
edit_menu.add_separator()
6868
edit_menu.add_command('Clear Undo History', _clear_undo)
69+
edit_menu.add_command('Show Undo View', _show_undo_view)
6970
edit_menu.add_separator()
7071

7172
edit_menu.add_command('Copy', _copy_nodes, QtGui.QKeySequence.Copy)
@@ -270,6 +271,10 @@ def _jump_out(graph):
270271
graph.set_node_space(node.parent())
271272

272273

274+
def _show_undo_view(graph):
275+
graph.undo_view.show()
276+
277+
273278
def _curved_pipe(graph):
274279
graph.set_pipe_style(PIPE_LAYOUT_CURVED)
275280

@@ -560,11 +565,10 @@ def _update_nodes(nodes):
560565
nodes (list[NodeGraphQt.BaseNode]): nodes to be run.
561566
"""
562567
for node in nodes:
568+
if node.disabled():
569+
continue
563570
try:
564-
if node.disabled():
565-
node.when_disabled()
566-
else:
567-
node.run()
571+
node.run()
568572
except Exception as error:
569573
print("Error Update Node : {}\n{}" .format(node, str(error)))
570574
break

example_auto_nodes.py

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
3-
import example_auto_nodes
4-
from NodeGraphQt import NodeGraph, setup_context_menu
5-
from NodeGraphQt import QtWidgets, QtCore, PropertiesBinWidget, \
6-
NodeTreeWidget, BackdropNode, NodePublishWidget
7-
import os
8-
import sys
9-
import inspect
3+
from NodeGraphQt import NodeGraph, setup_context_menu, \
4+
QtWidgets, QtCore, PropertiesBinWidget, BackdropNode
5+
from example_auto_nodes import Publish, RootNode, update_nodes, setup_node_menu
106
import importlib
11-
from example_auto_nodes import AutoNode, ModuleNode, \
12-
SubGraphNode, Publish, RootNode, update_nodes
7+
import inspect
8+
import sys
9+
import os
1310

1411

1512
def get_nodes_from_folder(folder_path):
@@ -49,58 +46,16 @@ def get_published_nodes_from_folder(folder_path):
4946
return nodes
5047

5148

52-
def cook_node(graph, node):
53-
node.update_stream(forceCook=True)
54-
55-
56-
def print_functions(graph, node):
57-
for func in node.module_functions:
58-
print(func)
59-
60-
61-
def toggle_auto_cook(graph, node):
62-
node.auto_cook = not node.auto_cook
63-
64-
65-
def enter_node(graph, node):
66-
graph.set_node_space(node)
67-
68-
69-
def allow_edit(graph, node):
70-
node.set_property('published', False)
71-
72-
73-
def print_path(graph, node):
74-
print(node.path())
75-
76-
77-
def find_node_by_path(graph, node):
78-
print(graph.get_node_by_path(node.path()))
79-
80-
81-
def print_children(graph, node):
82-
children = node.children()
83-
print(len(children), children)
84-
85-
86-
def publish_node(graph, node):
87-
wid = NodePublishWidget(node=node)
88-
wid.show()
89-
90-
91-
def cook_nodes(nodes):
92-
update_nodes(nodes)
93-
94-
9549
if __name__ == '__main__':
96-
app = QtWidgets.QApplication([])
50+
app = QtWidgets.QApplication()
9751

9852
# create node graph.
9953
graph = NodeGraph()
10054
graph.use_OpenGL()
10155

10256
# set up default menu and commands.
10357
setup_context_menu(graph)
58+
setup_node_menu(graph, Publish)
10459

10560
# show the properties bin when a node is "double clicked" in the graph.
10661
properties_bin = PropertiesBinWidget(node_graph=graph)
@@ -111,40 +66,20 @@ def show_prop_bin(node):
11166
properties_bin.show()
11267
graph.node_double_clicked.connect(show_prop_bin)
11368

114-
# show the nodes list when a node is "double clicked" in the graph.
115-
node_tree = NodeTreeWidget(node_graph=graph)
116-
117-
def show_nodes_list(node):
118-
if not node_tree.isVisible():
119-
node_tree.update()
120-
node_tree.show()
121-
graph.node_double_clicked.connect(show_nodes_list)
122-
12369
# register nodes
12470
reg_nodes = get_nodes_from_folder(os.getcwd() + "/example_auto_nodes")
12571
BackdropNode.__identifier__ = 'Utility::Backdrop'
12672
reg_nodes.append(BackdropNode)
12773
reg_nodes.extend(get_published_nodes_from_folder(os.getcwd() + "/example_auto_nodes/published_nodes"))
12874
[graph.register_node(n) for n in reg_nodes]
12975

130-
# setup node menu
131-
node_menu = graph.context_nodes_menu()
132-
node_menu.add_command('Allow Edit', allow_edit, node_class=Publish)
133-
node_menu.add_command('Enter Node', enter_node, node_class=SubGraphNode)
134-
node_menu.add_command('Publish Node', publish_node, node_class=SubGraphNode)
135-
node_menu.add_command('Print Children', print_children, node_class=SubGraphNode)
136-
node_menu.add_command('Print Functions', print_functions, node_class=ModuleNode)
137-
node_menu.add_command('Cook Node', cook_node, node_class=AutoNode)
138-
node_menu.add_command('Toggle Auto Cook', toggle_auto_cook, node_class=AutoNode)
139-
node_menu.add_command('Print Path', print_path, node_class=AutoNode)
140-
node_menu.add_command('Find Node By Path', find_node_by_path, node_class=AutoNode)
141-
14276
# create root node
77+
# if we want to use sub graph system, root node is must.
14378
graph.add_node(RootNode())
14479

14580
# create test nodes
14681
graph.load_session(r'example_auto_nodes/networks/example_SubGraph.json')
147-
cook_nodes(graph.root_node().children())
82+
update_nodes(graph.root_node().children())
14883

14984
# widget used for the node graph.
15085
graph_widget = graph.widget

example_auto_nodes/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from .node_base.auto_node import AutoNode
2-
from .node_base.module_node import ModuleNode
3-
from .node_base.subgraph_node import SubGraphNode, RootNode
1+
from .node_base import AutoNode, ModuleNode, SubGraphNode, RootNode
42
from .subgraph_nodes import Publish
5-
from .node_base.utils import update_node_down_stream, update_nodes
3+
from .node_base.utils import update_node_down_stream, update_nodes, setup_node_menu

example_auto_nodes/basic_nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .node_base.auto_node import AutoNode
1+
from .node_base import AutoNode
22

33

44
class FooNode(AutoNode):

example_auto_nodes/data_node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
3-
from .node_base.auto_node import AutoNode
3+
from .node_base import AutoNode
44

55

66
class VectorSplit(AutoNode):

example_auto_nodes/input_nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
NODE_PROP_VECTOR3,
44
NODE_PROP_VECTOR4)
55

6-
from .node_base.auto_node import AutoNode
6+
from .node_base import AutoNode
77
import os
88

99

example_auto_nodes/logic_nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .basic_nodes import AutoNode
1+
from .node_base import AutoNode
22

33

44
class IfNode(AutoNode):

0 commit comments

Comments
 (0)