Skip to content

Commit

Permalink
Drag onto link to insert widget
Browse files Browse the repository at this point in the history
  • Loading branch information
irgolic committed Aug 1, 2018
1 parent 8989b6b commit 5909b36
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
5 changes: 5 additions & 0 deletions Orange/canvas/canvas/items/linkitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class LinkCurveItem(QGraphicsPathItem):
"""
def __init__(self, parent):
super().__init__(parent)
self.__parent = parent

self.setAcceptedMouseButtons(Qt.NoButton)
self.setAcceptHoverEvents(True)

Expand Down Expand Up @@ -91,6 +93,9 @@ def setPath(self, path):
self.__shape = None
super().setPath(path)

def parent(self):
return self.__parent

def __update(self):
shadow_enabled = self.__hover
if self.shadow.isEnabled() != shadow_enabled:
Expand Down
36 changes: 28 additions & 8 deletions Orange/canvas/document/schemeedit.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,9 @@ def removeLink(self, link):
self.__undoStack.push(command)

def insertNode(self, link, new_node):
"""
Insert a node in-between two linked nodes.
"""
command = commands.InsertNodeCommand(self.__scheme, link, new_node)
self.__undoStack.push(command)

Expand Down Expand Up @@ -1044,6 +1047,17 @@ def changeEvent(self, event):

QWidget.changeEvent(self, event)

def tryInsertNode(self, link, new_node_desc, pos):
source_node = link.source_node
sink_node = link.sink_node

if are_nodes_compatible(source_node.description, new_node_desc) and \
are_nodes_compatible(new_node_desc, sink_node.description):
new_node = self.newNodeHelper(new_node_desc, position=(pos.x(), pos.y()))
self.insertNode(link, new_node)
else:
self.createNewNode(new_node_desc, position=(pos.x(), pos.y()))

def eventFilter(self, obj, event):
# Filter the scene's drag/drop events.
if obj is self.scene():
Expand All @@ -1069,7 +1083,12 @@ def eventFilter(self, obj, event):
log.error("Unknown qualified name '%s'", qname)
else:
pos = event.scenePos()
self.createNewNode(desc, position=(pos.x(), pos.y()))
item = self.__scene.item_at(event.scenePos())
if item and isinstance(item, items.LinkCurveItem):
link = self.__scene.link_for_item(item.parent())
self.tryInsertNode(link, desc, pos)
else:
self.createNewNode(desc, position=(pos.x(), pos.y()))
return True

elif etype == QEvent.GraphicsSceneMousePress:
Expand Down Expand Up @@ -1620,16 +1639,11 @@ def __nodeInsert(self):
source_node = original_link.source_node
sink_node = original_link.sink_node

def is_compatible(source, sink):
return any(scheme.compatible_channels(output, input) \
for output in source.outputs \
for input in sink.inputs)

def filterFunc(index):
new_node_desc = index.data(QtWidgetRegistry.WIDGET_DESC_ROLE)
if isinstance(new_node_desc, WidgetDescription):
return is_compatible(source_node.description, new_node_desc) and\
is_compatible(new_node_desc, sink_node.description)
return are_nodes_compatible(source_node.description, new_node_desc) and\
are_nodes_compatible(new_node_desc, sink_node.description)
else:
return False

Expand Down Expand Up @@ -1997,6 +2011,12 @@ def node_properties(scheme):
return [dict(node.properties) for node in scheme.nodes]


def are_nodes_compatible(source, sink):
return any(scheme.compatible_channels(output, input) \
for output in source.outputs \
for input in sink.inputs)


def uniquify(item, names, pattern="{item}-{_}", start=0):
candidates = (pattern.format(item=item, _=i)
for i in itertools.count(start))
Expand Down

0 comments on commit 5909b36

Please sign in to comment.