Skip to content

Commit 0ae9dc4

Browse files
committed
implemented port locking.
1 parent 749c8db commit 0ae9dc4

File tree

6 files changed

+74
-11
lines changed

6 files changed

+74
-11
lines changed

NodeGraphQt/base/model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(self, node):
1919
self.display_name = True
2020
self.multi_connection = False
2121
self.visible = True
22+
self.locked = False
2223
self.connected_ports = defaultdict(list)
2324
self.data_type = 'NoneType'
2425

NodeGraphQt/base/node.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,8 @@ def add_checkbox(self, name, label='', text='', state=False, tab=None):
798798
self.view.add_widget(widget)
799799

800800
def add_input(self, name='input', multi_input=False, display_name=True,
801-
color=None, data_type='NoneType', painter_func=None):
801+
color=None, data_type='NoneType', locked=False,
802+
painter_func=None):
802803
"""
803804
Add input :class:`Port` to node.
804805
@@ -808,6 +809,7 @@ def add_input(self, name='input', multi_input=False, display_name=True,
808809
display_name (bool): display the port name on the node.
809810
color (tuple): initial port color (r, g, b) ``0-255``.
810811
data_type (str): port data type name.
812+
locked (bool): locked state see :meth:`Port.set_locked`
811813
painter_func (function): custom function to override the drawing
812814
of the port shape see example: :ref:`Creating Custom Shapes`
813815
@@ -818,7 +820,7 @@ def add_input(self, name='input', multi_input=False, display_name=True,
818820
raise PortRegistrationError(
819821
'port name "{}" already registered.'.format(name))
820822

821-
port_args = [name, multi_input, display_name]
823+
port_args = [name, multi_input, display_name, locked]
822824
if painter_func and callable(painter_func):
823825
port_args.append(painter_func)
824826
view = self.view.add_input(*port_args)
@@ -833,12 +835,14 @@ def add_input(self, name='input', multi_input=False, display_name=True,
833835
port.model.display_name = display_name
834836
port.model.multi_connection = multi_input
835837
port.model.data_type = data_type
838+
port.model.locked = locked
836839
self._inputs.append(port)
837840
self.model.inputs[port.name()] = port.model
838841
return port
839842

840843
def add_output(self, name='output', multi_output=True, display_name=True,
841-
color=None, data_type='NoneType', painter_func=None):
844+
color=None, data_type='NoneType', locked=False,
845+
painter_func=None):
842846
"""
843847
Add output :class:`Port` to node.
844848
@@ -848,6 +852,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
848852
display_name (bool): display the port name on the node.
849853
color (tuple): initial port color (r, g, b) ``0-255``.
850854
data_type(str): port data type name.
855+
locked (bool): locked state see :meth:`Port.set_locked`
851856
painter_func (function): custom function to override the drawing
852857
of the port shape see example: :ref:`Creating Custom Shapes`
853858
@@ -858,7 +863,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
858863
raise PortRegistrationError(
859864
'port name "{}" already registered.'.format(name))
860865

861-
port_args = [name, multi_output, display_name]
866+
port_args = [name, multi_output, display_name, locked]
862867
if painter_func and callable(painter_func):
863868
port_args.append(painter_func)
864869
view = self.view.add_output(*port_args)
@@ -872,6 +877,7 @@ def add_output(self, name='output', multi_output=True, display_name=True,
872877
port.model.display_name = display_name
873878
port.model.multi_connection = multi_output
874879
port.model.data_type = data_type
880+
port.model.locked = locked
875881
self._outputs.append(port)
876882
self.model.outputs[port.name()] = port.model
877883
return port

NodeGraphQt/base/port.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ def visible(self):
102102
"""
103103
return self.model.visible
104104

105+
def locked(self):
106+
"""
107+
Port locked state.
108+
109+
Returns:
110+
bool: true if visible.
111+
"""
112+
return self.model.locked
113+
105114
def set_visible(self, visible=True):
106115
"""
107116
Sets weather the port should be visible or not.
@@ -120,6 +129,21 @@ def set_visible(self, visible=True):
120129
undo_stack.push(PortVisibleCmd(self))
121130
undo_stack.endMacro()
122131

132+
def set_locked(self, locked=False):
133+
"""
134+
Sets the port locked state when locked new pipe connections can't be
135+
connected or disconnected from the node graph gui.
136+
137+
Note:
138+
pipes can still be connected/disconnected to locked ports through
139+
the api.
140+
141+
Args:
142+
locked (Bool): true if locked.
143+
"""
144+
self.model.locked = locked
145+
self.__view.locked = locked
146+
123147
def connected_ports(self):
124148
"""
125149
Returns all connected ports.

NodeGraphQt/qgraphics/node_base.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ def _add_port(self, port):
692692
return port
693693

694694
def add_input(self, name='input', multi_port=False, display_name=True,
695-
painter_func=None):
695+
locked=False, painter_func=None):
696696
"""
697697
Adds a port qgraphics item into the node with the "port_type" set as
698698
IN_PORT.
@@ -701,6 +701,7 @@ def add_input(self, name='input', multi_port=False, display_name=True,
701701
name (str): name for the port.
702702
multi_port (bool): allow multiple connections.
703703
display_name (bool): display the port name.
704+
locked (bool): locked state.
704705
painter_func (function): custom paint function.
705706
706707
Returns:
@@ -714,10 +715,11 @@ def add_input(self, name='input', multi_port=False, display_name=True,
714715
port.port_type = IN_PORT
715716
port.multi_connection = multi_port
716717
port.display_name = display_name
718+
port.locked = locked
717719
return self._add_port(port)
718720

719721
def add_output(self, name='output', multi_port=False, display_name=True,
720-
painter_func=None):
722+
locked=False, painter_func=None):
721723
"""
722724
Adds a port qgraphics item into the node with the "port_type" set as
723725
OUT_PORT.
@@ -726,6 +728,7 @@ def add_output(self, name='output', multi_port=False, display_name=True,
726728
name (str): name for the port.
727729
multi_port (bool): allow multiple connections.
728730
display_name (bool): display the port name.
731+
locked (bool): locked state.
729732
painter_func (function): custom paint function.
730733
731734
Returns:
@@ -739,6 +742,7 @@ def add_output(self, name='output', multi_port=False, display_name=True,
739742
port.port_type = OUT_PORT
740743
port.multi_connection = multi_port
741744
port.display_name = display_name
745+
port.locked = locked
742746
return self._add_port(port)
743747

744748
def _delete_port(self, port, text):

NodeGraphQt/qgraphics/port.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def __init__(self, parent=None):
3737
self._border_size = 1
3838
self._port_type = None
3939
self._multi_connection = False
40+
self._locked = False
4041

4142
self.setCacheMode(ITEM_CACHE_MODE)
4243

@@ -222,6 +223,19 @@ def border_size(self):
222223
def border_size(self, size=2):
223224
self._border_size = size
224225

226+
@property
227+
def locked(self):
228+
return self._locked
229+
230+
@locked.setter
231+
def locked(self, value=False):
232+
self._locked = value
233+
conn_type = 'multi' if self.multi_connection else 'single'
234+
tooltip = '{}: ({})'.format(self.name, conn_type)
235+
if value:
236+
tooltip += ' (L)'
237+
self.setToolTip(tooltip)
238+
225239
@property
226240
def multi_connection(self):
227241
return self._multi_connection

NodeGraphQt/widgets/viewer.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,13 @@ def _on_search_submitted(self, node_type):
186186
self.search_triggered.emit(node_type, (pos.x(), pos.y()))
187187

188188
def _on_pipes_sliced(self, path):
189-
self.connection_sliced.emit([
190-
[i.input_port, i.output_port]
191-
for i in self.scene().items(path)
192-
if isinstance(i, Pipe) and i != self._LIVE_PIPE
193-
])
189+
ports = []
190+
for i in self.scene().items(path):
191+
if isinstance(i, Pipe) and i != self._LIVE_PIPE:
192+
if any([i.input_port.locked, i.output_port.locked]):
193+
continue
194+
ports.append([i.input_port, i.output_port])
195+
self.connection_sliced.emit(ports)
194196

195197
# --- reimplemented events ---
196198

@@ -534,9 +536,11 @@ def sceneMousePressEvent(self, event):
534536
# pipe slicer enabled.
535537
if self.ALT_state and self.SHIFT_state:
536538
return
539+
537540
# viewer pan mode.
538541
if self.ALT_state:
539542
return
543+
540544
if self._LIVE_PIPE.isVisible():
541545
self.apply_live_connection(event)
542546
return
@@ -545,6 +549,10 @@ def sceneMousePressEvent(self, event):
545549
port_items = self._items_near(pos, PortItem, 5, 5)
546550
if port_items and self.editable:
547551
port = port_items[0]
552+
553+
if port.locked:
554+
return
555+
548556
if not port.multi_connection and port.connected_ports:
549557
self._detached_port = port.connected_ports[0]
550558
self.start_live_connection(port)
@@ -573,6 +581,10 @@ def sceneMousePressEvent(self, event):
573581
return
574582
pipe = pipe_items[0]
575583
from_port = pipe.port_from_pos(pos, True)
584+
585+
if from_port.locked:
586+
return
587+
576588
from_port.hovered = True
577589

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

649661
# restore connection check.
650662
restore_connection = any([
663+
# if the end port is locked.
664+
end_port.locked,
651665
# if same port type.
652666
end_port.port_type == self._start_port.port_type,
653667
# if connection to itself.

0 commit comments

Comments
 (0)