[ui] UIGraph: add hoveredNode property + node hovering visual feedback

* keep track of currently hovered node in UIGraph on Python side
* Node: show border on hover + make MouseArea contain everything else to always get hover events, even when cursor is over children attribute pins
This commit is contained in:
Yann Lanthony 2018-12-06 19:13:17 +01:00
parent 5b991053a8
commit 05854ed897
3 changed files with 124 additions and 104 deletions

View file

@ -202,6 +202,7 @@ class UIGraph(QObject):
self._sortedDFSChunks = QObjectListModel(parent=self) self._sortedDFSChunks = QObjectListModel(parent=self)
self._layout = GraphLayout(self) self._layout = GraphLayout(self)
self._selectedNode = None self._selectedNode = None
self._hoveredNode = None
if filepath: if filepath:
self.load(filepath) self.load(filepath)
@ -236,6 +237,7 @@ class UIGraph(QObject):
def clear(self): def clear(self):
if self._graph: if self._graph:
self.clearNodeHover()
self.clearNodeSelection() self.clearNodeSelection()
self._graph.deleteLater() self._graph.deleteLater()
self._graph = None self._graph = None
@ -472,6 +474,10 @@ class UIGraph(QObject):
""" Clear node selection. """ """ Clear node selection. """
self.selectedNode = None self.selectedNode = None
def clearNodeHover(self):
""" Reset currently hovered node to None. """
self.hoveredNode = None
undoStack = Property(QObject, lambda self: self._undoStack, constant=True) undoStack = Property(QObject, lambda self: self._undoStack, constant=True)
graphChanged = Signal() graphChanged = Signal()
graph = Property(Graph, lambda self: self._graph, notify=graphChanged) graph = Property(Graph, lambda self: self._graph, notify=graphChanged)
@ -490,3 +496,7 @@ class UIGraph(QObject):
selectedNodeChanged = Signal() selectedNodeChanged = Signal()
# Currently selected node # Currently selected node
selectedNode = makeProperty(QObject, "_selectedNode", selectedNodeChanged, clearNodeSelection) selectedNode = makeProperty(QObject, "_selectedNode", selectedNodeChanged, clearNodeSelection)
hoveredNodeChanged = Signal()
# Currently hovered node
hoveredNode = makeProperty(QObject, "_hoveredNode", hoveredNodeChanged, clearNodeHover)

View file

@ -308,6 +308,7 @@ Item {
width: uigraph.layout.nodeWidth width: uigraph.layout.nodeWidth
readOnly: root.readOnly readOnly: root.readOnly
selected: uigraph.selectedNode === node selected: uigraph.selectedNode === node
hovered: uigraph.hoveredNode === node
onSelectedChanged: if(selected) forceActiveFocus() onSelectedChanged: if(selected) forceActiveFocus()
onAttributePinCreated: registerAttributePin(attribute, pin) onAttributePinCreated: registerAttributePin(attribute, pin)
@ -331,6 +332,9 @@ Item {
onMoved: uigraph.moveNode(node, position) onMoved: uigraph.moveNode(node, position)
onEntered: uigraph.hoveredNode = node
onExited: uigraph.hoveredNode = null
Keys.onDeletePressed: uigraph.removeNode(node) Keys.onDeletePressed: uigraph.removeNode(node)
Behavior on x { Behavior on x {

View file

@ -13,14 +13,17 @@ Item {
readonly property bool isCompatibilityNode: node.hasOwnProperty("compatibilityIssue") readonly property bool isCompatibilityNode: node.hasOwnProperty("compatibilityIssue")
readonly property color defaultColor: isCompatibilityNode ? "#444" : "#607D8B" readonly property color defaultColor: isCompatibilityNode ? "#444" : "#607D8B"
property bool selected: false property bool selected: false
property bool hovered: false
signal pressed(var mouse) signal pressed(var mouse)
signal doubleClicked(var mouse) signal doubleClicked(var mouse)
signal moved(var position) signal moved(var position)
signal entered()
signal exited()
signal attributePinCreated(var attribute, var pin) signal attributePinCreated(var attribute, var pin)
signal attributePinDeleted(var attribute, var pin) signal attributePinDeleted(var attribute, var pin)
implicitHeight: body.height implicitHeight: childrenRect.height
objectName: node.name objectName: node.name
SystemPalette { id: activePalette } SystemPalette { id: activePalette }
@ -39,7 +42,8 @@ Item {
} }
MouseArea { MouseArea {
anchors.fill: parent width: parent.width
height: body.height
drag.target: parent drag.target: parent
// small drag threshold to avoid moving the node by mistake // small drag threshold to avoid moving the node by mistake
drag.threshold: 2 drag.threshold: 2
@ -47,19 +51,20 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressed: root.pressed(mouse) onPressed: root.pressed(mouse)
onDoubleClicked: root.doubleClicked(mouse) onDoubleClicked: root.doubleClicked(mouse)
onEntered: root.entered()
onExited: root.exited()
drag.onActiveChanged: { drag.onActiveChanged: {
if(!drag.active) if(!drag.active)
root.moved(Qt.point(root.x, root.y)) root.moved(Qt.point(root.x, root.y))
} }
}
// Selection border // Selection border
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.margins: -border.width anchors.margins: -border.width
visible: root.selected visible: root.selected || root.hovered
border.width: 2.5 border.width: 2.5
border.color: activePalette.highlight border.color: root.selected ? activePalette.highlight : Qt.darker(activePalette.highlight, 1.5)
opacity: 0.9 opacity: 0.9
color: "transparent" color: "transparent"
} }
@ -172,3 +177,4 @@ Item {
} }
} }
} }
}