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
62 changes: 31 additions & 31 deletions NodeGraphQt/base/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,16 @@

from Qt import QtCore, QtWidgets

from NodeGraphQt.base.commands import (NodeAddedCmd,
NodesRemovedCmd,
NodeMovedCmd,
PortConnectedCmd)
from NodeGraphQt.base.commands import (NodeAddedCmd, NodeMovedCmd,
NodesRemovedCmd, PortConnectedCmd)
from NodeGraphQt.base.factory import NodeFactory
from NodeGraphQt.base.menu import NodeGraphMenu, NodesMenu
from NodeGraphQt.base.model import NodeGraphModel
from NodeGraphQt.base.node import NodeObject
from NodeGraphQt.base.port import Port
from NodeGraphQt.constants import (
MIME_TYPE,
URI_SCHEME,
URN_SCHEME,
LayoutDirectionEnum,
PipeLayoutEnum,
PortTypeEnum,
ViewerEnum
)
from NodeGraphQt.constants import (MIME_TYPE, URI_SCHEME, URN_SCHEME,
LayoutDirectionEnum, PipeLayoutEnum,
PortTypeEnum, ViewerEnum)
from NodeGraphQt.errors import NodeCreationError, NodeDeletionError
from NodeGraphQt.nodes.backdrop_node import BackdropNode
from NodeGraphQt.nodes.base_node import BaseNode
Expand Down Expand Up @@ -789,8 +781,8 @@ def _deserialize_context_menu(self, menu, menu_data, anchor_path=None):
if not menu:
raise ValueError('No context menu named: "{}"'.format(menu))

import sys
import importlib.util
import sys

nodes_menu = self.get_context_menu('nodes')

Expand Down Expand Up @@ -1304,7 +1296,7 @@ def format_color(clr):

raise NodeCreationError('Can\'t find node: "{}"'.format(node_type))

def add_node(self, node, pos=None, selected=True, push_undo=True):
def add_node(self, node, pos=None, selected=True, push_undo=True, inherite_graph_style=True):
"""
Add a node into the node graph.
unlike the :meth:`NodeGraph.create_node` function this will not
Expand All @@ -1315,6 +1307,8 @@ def add_node(self, node, pos=None, selected=True, push_undo=True):
pos (list[float]): node x,y position. (optional)
selected (bool): node selected state. (optional)
push_undo (bool): register the command to the undo stack. (default: True)
inherite_graph_style (bool): when True the node will inherite the
node graph layout direction. (default: True)
"""
assert isinstance(node, NodeObject), 'node must be a Node instance.'

Expand Down Expand Up @@ -1368,7 +1362,8 @@ def add_node(self, node, pos=None, selected=True, push_undo=True):
node.model.name = node.NODE_NAME

# initial node direction layout.
node.model.layout_direction = self.layout_direction()
if inherite_graph_style:
node.model.layout_direction = self.layout_direction()

# update method must be called before it's been added to the viewer.
node.update()
Expand Down Expand Up @@ -1774,7 +1769,7 @@ def _serialize(self, nodes):

return serial_data

def _deserialize(self, data, relative_pos=False, pos=None):
def _deserialize(self, data, relative_pos=False, pos=None, adjust_graph_style=True):
"""
deserialize node data.
(used internally by the node graph)
Expand All @@ -1783,22 +1778,24 @@ def _deserialize(self, data, relative_pos=False, pos=None):
data (dict): node data.
relative_pos (bool): position node relative to the cursor.
pos (tuple or list): custom x, y position.
adjust_graph_style (bool): if true adjust the node graph properties

Returns:
list[NodeGraphQt.Nodes]: list of node instances.
"""
# update node graph properties.
for attr_name, attr_value in data.get('graph', {}).items():
if attr_name == 'layout_direction':
self.set_layout_direction(attr_value)
elif attr_name == 'acyclic':
self.set_acyclic(attr_value)
elif attr_name == 'pipe_collision':
self.set_pipe_collision(attr_value)
elif attr_name == 'pipe_slicing':
self.set_pipe_slicing(attr_value)
elif attr_name == 'pipe_style':
self.set_pipe_style(attr_value)
for attr_name, attr_value in data.get("graph", {}).items():
if adjust_graph_style:
if attr_name == "layout_direction":
self.set_layout_direction(attr_value)
elif attr_name == "acyclic":
self.set_acyclic(attr_value)
elif attr_name == "pipe_collision":
self.set_pipe_collision(attr_value)
elif attr_name == "pipe_slicing":
self.set_pipe_slicing(attr_value)
elif attr_name == "pipe_style":
self.set_pipe_style(attr_value)

# connection constrains.
elif attr_name == 'accept_connection_types':
Expand Down Expand Up @@ -1829,7 +1826,7 @@ def _deserialize(self, data, relative_pos=False, pos=None):
node.view.widgets[prop].set_value(val)

nodes[n_id] = node
self.add_node(node, n_data.get('pos'))
self.add_node(node, n_data.get('pos'), inherite_graph_style=adjust_graph_style)

if n_data.get('port_deletion_allowed', None):
node.set_ports({
Expand Down Expand Up @@ -2057,10 +2054,13 @@ def cut_nodes(self, nodes=None):
self._undo_stack.push(NodesRemovedCmd(self, nodes))
self._undo_stack.endMacro()

def paste_nodes(self):
def paste_nodes(self, adjust_graph_style=True):
"""
Pastes nodes copied from the clipboard.

Args:
adjust_graph_style (bool): if true adjust the node graph properties
other wise only the nodes are pasted.
Returns:
list[NodeGraphQt.BaseNode]: list of pasted node instances.
"""
Expand All @@ -2078,7 +2078,7 @@ def paste_nodes(self):

self._undo_stack.beginMacro('pasted nodes')
self.clear_selection()
nodes = self._deserialize(serial_data, relative_pos=True)
nodes = self._deserialize(serial_data, relative_pos=True, adjust_graph_style=adjust_graph_style)
[n.set_selected(True) for n in nodes]
self._undo_stack.endMacro()
return nodes
Expand Down
45 changes: 30 additions & 15 deletions examples/basic_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@

from Qt import QtCore, QtWidgets

# import example nodes from the "nodes" sub-package
from examples.nodes import basic_nodes, custom_ports_node, group_node, widget_nodes
from NodeGraphQt import (
NodeGraph,
PropertiesBinWidget,
NodesPaletteWidget,
NodesTreeWidget,
NodesPaletteWidget
PropertiesBinWidget,
)

# import example nodes from the "nodes" sub-package
from examples.nodes import basic_nodes, custom_ports_node, group_node, widget_nodes
from NodeGraphQt.constants import LayoutDirectionEnum

BASE_PATH = Path(__file__).parent.resolve()


def main():
# handle SIGINT to make the app terminate on CTRL+C
signal.signal(signal.SIGINT, signal.SIG_DFL)
Expand All @@ -31,27 +32,38 @@ def main():
graph.set_context_menu_from_file(hotkey_path, 'graph')

# registered example nodes.
graph.register_nodes([
basic_nodes.BasicNodeA,
basic_nodes.BasicNodeB,
basic_nodes.CircleNode,
custom_ports_node.CustomPortsNode,
group_node.MyGroupNode,
widget_nodes.DropdownMenuNode,
widget_nodes.TextInputNode,
widget_nodes.CheckboxNode
])
graph.register_nodes(
[
basic_nodes.BasicNodeA,
basic_nodes.BasicNodeB,
basic_nodes.CircleNode,
custom_ports_node.CustomPortsNode,
group_node.MyGroupNode,
widget_nodes.DropdownMenuNode,
widget_nodes.TextInputNode,
widget_nodes.CheckboxNode,
]
)

# show the node graph widget.
graph_widget = graph.widget
graph_widget.resize(1100, 800)
graph_widget.setWindowTitle("NodeGraphQt Example")
graph_widget.show()

# create node with custom text color and disable it.
n_basic_a = graph.create_node(
'nodes.basic.BasicNodeA', text_color='#feab20')
n_basic_a.set_disabled(True)

# create node with vertial alignment
n_basic_a_vertical = graph.create_node(
"nodes.basic.BasicNodeA", name="Vertical Node", text_color="#feab20"
)

# adjust layout of node to be vertical
n_basic_a_vertical.set_layout_direction(1)

# create node and set a custom icon.
n_basic_b = graph.create_node(
'nodes.basic.BasicNodeB', name='custom icon')
Expand Down Expand Up @@ -106,6 +118,9 @@ def main():
graph.clear_selection()
graph.fit_to_selection()

# adjust layout of node to be vertical (for all nodes).
# graph.set_layout_direction(LayoutDirectionEnum.VERTICAL.value)

# Custom builtin widgets from NodeGraphQt
# ---------------------------------------

Expand Down
5 changes: 4 additions & 1 deletion examples/hotkeys/hotkey_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ def paste_nodes(graph):
"""
Pastes nodes copied from the clipboard.
"""
graph.paste_nodes()
# by default the graph will inherite the global style
# from the graph when pasting nodes.
# to disable this behaviour set `adjust_graph_style` to False.
graph.paste_nodes(adjust_graph_style=False)


def delete_nodes(graph):
Expand Down