Browse Source

Delete highlighted connections.

main
Ben Niemann 9 months ago
parent
commit
9ade76a9c8
  1. 44
      noisicaa/ui/qml/GraphView.py
  2. 20
      noisicaa/ui/qml/GraphView.qml
  3. 8
      noisicaa/ui/ui_base.py

44
noisicaa/ui/qml/GraphView.py

@ -79,7 +79,9 @@ class ObjectList(QtCore.QAbstractListModel):
return obj
class GraphView(ui_base.ProjectMixin, QtCore.QObject):
class GraphView(ui_base.ProjectMixin, ui_base.PropertyContainer, QtCore.QObject):
highlightedConnection, highlightedConnectionChanged = ui_base.Property('highlightedConnection', GraphConnectionWrapper)
def __init__(self, **kwargs):
super().__init__(**kwargs)
@ -192,37 +194,6 @@ class GraphView(ui_base.ProjectMixin, QtCore.QObject):
node = self.__nodes.data(index)
node.rect = node.rect.translated(delta)
@QtCore.Slot()
def showContextMenu(self):
clickPos = QtGui.QCursor.pos()
scenePos = self.mapFromGlobal(QtCore.QPointF(clickPos))
menu = QtWidgets.QMenu(self.__view)
highlightedConnections = [conn for conn in self.__connections if conn.highlighted]
if highlightedConnections:
assert len(highlightedConnections) == 1
remove_connection_action = menu.addAction("Delete connection")
remove_connection_action.triggered.connect(functools.partial(
self.deleteConnection, highlightedConnections[0]))
else:
select_all_action = menu.addAction("Select all")
select_all_action.triggered.connect(self.__selectAll)
select_none_action = menu.addAction("Select none")
select_none_action.setEnabled(self.hasSelection)
select_none_action.triggered.connect(self.clearSelection)
insert_node_menu = menu.addMenu("Insert node")
insert_node_action = SelectNodeAction(parent=menu, context=self.context)
insert_node_action.nodeSelected.connect(lambda uri: self.__insertNode(uri, scenePos))
insert_node_menu.addAction(insert_node_action)
if not menu.isEmpty():
menu.popup(clickPos)
@QtCore.Slot(GraphNodePort, result=list)
def getTargetPorts(self, src: GraphNodePort) -> None:
if src.portDesc.direction == engine.PortDirection.OUTPUT:
@ -254,6 +225,12 @@ class GraphView(ui_base.ProjectMixin, QtCore.QObject):
def highlightConnection(self, conn: GraphConnectionWrapper) -> None:
for c in self.__connections:
c.highlighted = c is conn
self.highlightedConnection = conn
@QtCore.Slot(GraphConnectionWrapper)
def unhighlightConnection(self, conn: GraphConnectionWrapper) -> None:
if conn is self.highlightedConnection:
self.highlightedConnection = None
@QtCore.Slot(GraphNodePort, GraphNodePort)
def connectPorts(self, src: GraphNodePort, dest: GraphNodePort) -> None:
@ -273,7 +250,8 @@ class GraphView(ui_base.ProjectMixin, QtCore.QObject):
destNodeId=destNode.id, destPort=destPort)
self.project.connections.append(conn)
def deleteConnection(self, wrapper: GraphConnectionWrapper):
@QtCore.Slot(GraphConnectionWrapper)
def disconnectPorts(self, wrapper: GraphConnectionWrapper):
conn = wrapper.connection
with self.project.captureChanges("Disconnect '{}:{}' from '{}:{}'".format(
wrapper.srcNode.node.title, conn.srcPort, wrapper.destNode.node.title, conn.destPort)):

20
noisicaa/ui/qml/GraphView.qml

@ -59,6 +59,17 @@ Control {
}
}
Menu {
id: connectionContextMenu
property QtObject conn
Action {
text: "Disconnect"
onTriggered: d.disconnectPorts(connectionContextMenu.conn);
}
}
function openCreateNodeDialog(pos) {
createNodeDialog.pos = pos;
createNodeDialog.open();
@ -106,7 +117,12 @@ Control {
movex = mouse.x - d.offset.x;
movey = mouse.y - d.offset.y;
} else if (mouse.button == Qt.RightButton) {
contextMenu.popupAt(mapToItem(root, Qt.point(mouse.x, mouse.y)));
if (d.highlightedConnection != null) {
connectionContextMenu.conn = d.highlightedConnection;
connectionContextMenu.popup();
} else {
contextMenu.popupAt(mapToItem(root, Qt.point(mouse.x, mouse.y)));
}
}
}
onPositionChanged: {
@ -217,6 +233,8 @@ Control {
onHoveredChanged: function (hovered) {
if (hovered) {
root.d.highlightConnection(d)
} else {
root.d.unhighlightConnection(d)
}
}
}

8
noisicaa/ui/ui_base.py

@ -67,16 +67,18 @@ def ConstProperty(pytype, qtype=None):
return decorator
def Property(name, pytype, qtype=None, *, default=None, validate=None):
def Property(name, pytype, qtype=None, *, default=None, validate=None, allowNone=None):
if qtype is None:
qtype = pytype
if default is None:
if allowNone is None:
allowNone = issubclass(qtype, QtCore.QObject)
if not allowNone and default is None:
default = pytype()
sig = QtCore.Signal(qtype)
def setter(self, value):
if validate is not None:
if value is not None and validate is not None:
validate(self, value)
old_value = self._ui_property_values.get(name, default)
if value != old_value:

Loading…
Cancel
Save