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
1 change: 1 addition & 0 deletions NodeGraphQt/base/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def __init__(self, node):
self.display_name = True
self.multi_connection = False
self.visible = True
self.locked = False
self.connected_ports = defaultdict(list)
self.data_type = 'NoneType'

Expand Down
14 changes: 10 additions & 4 deletions NodeGraphQt/base/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,8 @@ def add_checkbox(self, name, label='', text='', state=False, tab=None):
self.view.add_widget(widget)

def add_input(self, name='input', multi_input=False, display_name=True,
color=None, data_type='NoneType', painter_func=None):
color=None, data_type='NoneType', locked=False,
painter_func=None):
"""
Add input :class:`Port` to node.

Expand All @@ -808,6 +809,7 @@ def add_input(self, name='input', multi_input=False, display_name=True,
display_name (bool): display the port name on the node.
color (tuple): initial port color (r, g, b) ``0-255``.
data_type (str): port data type name.
locked (bool): locked state see :meth:`Port.set_locked`
painter_func (function): custom function to override the drawing
of the port shape see example: :ref:`Creating Custom Shapes`

Expand All @@ -818,7 +820,7 @@ def add_input(self, name='input', multi_input=False, display_name=True,
raise PortRegistrationError(
'port name "{}" already registered.'.format(name))

port_args = [name, multi_input, display_name]
port_args = [name, multi_input, display_name, locked]
if painter_func and callable(painter_func):
port_args.append(painter_func)
view = self.view.add_input(*port_args)
Expand All @@ -833,12 +835,14 @@ def add_input(self, name='input', multi_input=False, display_name=True,
port.model.display_name = display_name
port.model.multi_connection = multi_input
port.model.data_type = data_type
port.model.locked = locked
self._inputs.append(port)
self.model.inputs[port.name()] = port.model
return port

def add_output(self, name='output', multi_output=True, display_name=True,
color=None, data_type='NoneType', painter_func=None):
color=None, data_type='NoneType', locked=False,
painter_func=None):
"""
Add output :class:`Port` to node.

Expand All @@ -848,6 +852,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
display_name (bool): display the port name on the node.
color (tuple): initial port color (r, g, b) ``0-255``.
data_type(str): port data type name.
locked (bool): locked state see :meth:`Port.set_locked`
painter_func (function): custom function to override the drawing
of the port shape see example: :ref:`Creating Custom Shapes`

Expand All @@ -858,7 +863,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
raise PortRegistrationError(
'port name "{}" already registered.'.format(name))

port_args = [name, multi_output, display_name]
port_args = [name, multi_output, display_name, locked]
if painter_func and callable(painter_func):
port_args.append(painter_func)
view = self.view.add_output(*port_args)
Expand All @@ -872,6 +877,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
port.model.display_name = display_name
port.model.multi_connection = multi_output
port.model.data_type = data_type
port.model.locked = locked
self._outputs.append(port)
self.model.outputs[port.name()] = port.model
return port
Expand Down
24 changes: 24 additions & 0 deletions NodeGraphQt/base/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ def visible(self):
"""
return self.model.visible

def locked(self):
"""
Port locked state.

Returns:
bool: true if visible.
"""
return self.model.locked

def set_visible(self, visible=True):
"""
Sets weather the port should be visible or not.
Expand All @@ -120,6 +129,21 @@ def set_visible(self, visible=True):
undo_stack.push(PortVisibleCmd(self))
undo_stack.endMacro()

def set_locked(self, locked=False):
"""
Sets the port locked state when locked new pipe connections can't be
connected or disconnected from the node graph gui.

Note:
pipes can still be connected/disconnected to locked ports through
the api.

Args:
locked (Bool): true if locked.
"""
self.model.locked = locked
self.__view.locked = locked

def connected_ports(self):
"""
Returns all connected ports.
Expand Down
8 changes: 6 additions & 2 deletions NodeGraphQt/qgraphics/node_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ def _add_port(self, port):
return port

def add_input(self, name='input', multi_port=False, display_name=True,
painter_func=None):
locked=False, painter_func=None):
"""
Adds a port qgraphics item into the node with the "port_type" set as
IN_PORT.
Expand All @@ -701,6 +701,7 @@ def add_input(self, name='input', multi_port=False, display_name=True,
name (str): name for the port.
multi_port (bool): allow multiple connections.
display_name (bool): display the port name.
locked (bool): locked state.
painter_func (function): custom paint function.

Returns:
Expand All @@ -714,10 +715,11 @@ def add_input(self, name='input', multi_port=False, display_name=True,
port.port_type = IN_PORT
port.multi_connection = multi_port
port.display_name = display_name
port.locked = locked
return self._add_port(port)

def add_output(self, name='output', multi_port=False, display_name=True,
painter_func=None):
locked=False, painter_func=None):
"""
Adds a port qgraphics item into the node with the "port_type" set as
OUT_PORT.
Expand All @@ -726,6 +728,7 @@ def add_output(self, name='output', multi_port=False, display_name=True,
name (str): name for the port.
multi_port (bool): allow multiple connections.
display_name (bool): display the port name.
locked (bool): locked state.
painter_func (function): custom paint function.

Returns:
Expand All @@ -739,6 +742,7 @@ def add_output(self, name='output', multi_port=False, display_name=True,
port.port_type = OUT_PORT
port.multi_connection = multi_port
port.display_name = display_name
port.locked = locked
return self._add_port(port)

def _delete_port(self, port, text):
Expand Down
14 changes: 14 additions & 0 deletions NodeGraphQt/qgraphics/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def __init__(self, parent=None):
self._border_size = 1
self._port_type = None
self._multi_connection = False
self._locked = False

self.setCacheMode(ITEM_CACHE_MODE)

Expand Down Expand Up @@ -222,6 +223,19 @@ def border_size(self):
def border_size(self, size=2):
self._border_size = size

@property
def locked(self):
return self._locked

@locked.setter
def locked(self, value=False):
self._locked = value
conn_type = 'multi' if self.multi_connection else 'single'
tooltip = '{}: ({})'.format(self.name, conn_type)
if value:
tooltip += ' (L)'
self.setToolTip(tooltip)

@property
def multi_connection(self):
return self._multi_connection
Expand Down
24 changes: 19 additions & 5 deletions NodeGraphQt/widgets/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,13 @@ def _on_search_submitted(self, node_type):
self.search_triggered.emit(node_type, (pos.x(), pos.y()))

def _on_pipes_sliced(self, path):
self.connection_sliced.emit([
[i.input_port, i.output_port]
for i in self.scene().items(path)
if isinstance(i, Pipe) and i != self._LIVE_PIPE
])
ports = []
for i in self.scene().items(path):
if isinstance(i, Pipe) and i != self._LIVE_PIPE:
if any([i.input_port.locked, i.output_port.locked]):
continue
ports.append([i.input_port, i.output_port])
self.connection_sliced.emit(ports)

# --- reimplemented events ---

Expand Down Expand Up @@ -534,9 +536,11 @@ def sceneMousePressEvent(self, event):
# pipe slicer enabled.
if self.ALT_state and self.SHIFT_state:
return

# viewer pan mode.
if self.ALT_state:
return

if self._LIVE_PIPE.isVisible():
self.apply_live_connection(event)
return
Expand All @@ -545,6 +549,10 @@ def sceneMousePressEvent(self, event):
port_items = self._items_near(pos, PortItem, 5, 5)
if port_items and self.editable:
port = port_items[0]

if port.locked:
return

if not port.multi_connection and port.connected_ports:
self._detached_port = port.connected_ports[0]
self.start_live_connection(port)
Expand Down Expand Up @@ -573,6 +581,10 @@ def sceneMousePressEvent(self, event):
return
pipe = pipe_items[0]
from_port = pipe.port_from_pos(pos, True)

if from_port.locked:
return

from_port.hovered = True

attr = {IN_PORT: 'output_port', OUT_PORT: 'input_port'}
Expand Down Expand Up @@ -648,6 +660,8 @@ def apply_live_connection(self, event):

# restore connection check.
restore_connection = any([
# if the end port is locked.
end_port.locked,
# if same port type.
end_port.port_type == self._start_port.port_type,
# if connection to itself.
Expand Down