mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-08-06 10:18:42 +02:00
[ui] GraphEditor: simplify attributes connection
* make Drag/DropArea overflow on the attribute's label to be more tolerant when connecting attributes * add visual feedback when hovering interactive areas * tweak spacings between attributes
This commit is contained in:
parent
e95c88292e
commit
713ca7c6a3
2 changed files with 39 additions and 17 deletions
|
@ -21,9 +21,11 @@ RowLayout {
|
||||||
signal childPinCreated(var childAttribute, var pin)
|
signal childPinCreated(var childAttribute, var pin)
|
||||||
signal childPinDeleted(var childAttribute, var pin)
|
signal childPinDeleted(var childAttribute, var pin)
|
||||||
|
|
||||||
|
signal pressed(var mouse)
|
||||||
|
|
||||||
objectName: attribute.name + "."
|
objectName: attribute.name + "."
|
||||||
layoutDirection: attribute.isOutput ? Qt.RightToLeft : Qt.LeftToRight
|
layoutDirection: attribute.isOutput ? Qt.RightToLeft : Qt.LeftToRight
|
||||||
spacing: 1
|
spacing: 2
|
||||||
|
|
||||||
// Instantiate empty Items for each child attribute
|
// Instantiate empty Items for each child attribute
|
||||||
Repeater {
|
Repeater {
|
||||||
|
@ -39,19 +41,31 @@ RowLayout {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: edgeAnchor
|
id: edgeAnchor
|
||||||
|
|
||||||
width: 6
|
width: 7
|
||||||
height: width
|
height: width
|
||||||
radius: isList ? 0 : width/2
|
radius: isList ? 0 : width/2
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
border.color: "#3e3e3e"
|
border.color: "#3e3e3e"
|
||||||
color: (dropArea.containsDrag && dropArea.containsDrag) || attribute.isLink ? "#3e3e3e" : "white"
|
color: {
|
||||||
|
if(connectMA.containsMouse || connectMA.drag.active || (dropArea.containsDrag && dropArea.acceptableDrop))
|
||||||
|
return nameLabel.palette.highlight
|
||||||
|
else if(attribute.isLink)
|
||||||
|
return "#3e3e3e"
|
||||||
|
return "white"
|
||||||
|
}
|
||||||
|
|
||||||
DropArea {
|
DropArea {
|
||||||
id: dropArea
|
id: dropArea
|
||||||
|
|
||||||
property bool acceptableDrop: false
|
property bool acceptableDrop: false
|
||||||
|
|
||||||
|
// add negative margins for DropArea to make the connection zone easier to reach
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: -2
|
||||||
|
// add horizontal negative margins according to the current layout
|
||||||
|
anchors.leftMargin: root.layoutDirection == Qt.RightToLeft ? -root.width * 0.3 : 0
|
||||||
|
anchors.rightMargin: root.layoutDirection == Qt.LeftToRight ? -root.width * 0.3 : 0
|
||||||
|
|
||||||
keys: [dragTarget.objectName]
|
keys: [dragTarget.objectName]
|
||||||
onEntered: {
|
onEntered: {
|
||||||
// Filter drops:
|
// Filter drops:
|
||||||
|
@ -82,13 +96,20 @@ RowLayout {
|
||||||
readonly property bool isOutput: attribute.isOutput
|
readonly property bool isOutput: attribute.isOutput
|
||||||
readonly property alias isList: root.isList
|
readonly property alias isList: root.isList
|
||||||
anchors.centerIn: root.state == "Dragging" ? undefined : parent
|
anchors.centerIn: root.state == "Dragging" ? undefined : parent
|
||||||
//anchors.verticalCenter: root.verticalCenter
|
width: 4
|
||||||
width: 2
|
height: 4
|
||||||
height: 2
|
|
||||||
Drag.keys: [dragTarget.objectName]
|
Drag.keys: [dragTarget.objectName]
|
||||||
Drag.active: connectMA.drag.active
|
Drag.active: connectMA.drag.active
|
||||||
Drag.hotSpot.x: width*0.5
|
Drag.hotSpot.x: width*0.5
|
||||||
Drag.hotSpot.y: height*0.5
|
Drag.hotSpot.y: height*0.5
|
||||||
|
anchors.onCenterInChanged: {
|
||||||
|
// snap dragTarget to current mouse position in connectMA
|
||||||
|
if(anchors.centerIn == undefined) {
|
||||||
|
var pos = mapFromItem(connectMA, connectMA.mouseX, connectMA.mouseY)
|
||||||
|
x = pos.x
|
||||||
|
y = pos.y
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -97,7 +118,13 @@ RowLayout {
|
||||||
drag.threshold: 0
|
drag.threshold: 0
|
||||||
enabled: !root.readOnly
|
enabled: !root.readOnly
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
// use the same negative margins as DropArea to ease pin selection
|
||||||
|
anchors.margins: dropArea.anchors.margins
|
||||||
|
anchors.leftMargin: dropArea.anchors.leftMargin
|
||||||
|
anchors.rightMargin: dropArea.anchors.rightMargin
|
||||||
|
onPressed: root.pressed(mouse)
|
||||||
onReleased: dragTarget.Drag.drop()
|
onReleased: dragTarget.Drag.drop()
|
||||||
|
hoverEnabled: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Edge {
|
Edge {
|
||||||
|
@ -120,17 +147,8 @@ RowLayout {
|
||||||
font.pointSize: 5
|
font.pointSize: 5
|
||||||
horizontalAlignment: attribute.isOutput ? Text.AlignRight : Text.AlignLeft
|
horizontalAlignment: attribute.isOutput ? Text.AlignRight : Text.AlignLeft
|
||||||
|
|
||||||
// Extend truncated names at mouse hover
|
|
||||||
MouseArea {
|
|
||||||
id: ma
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: parent.truncated
|
|
||||||
visible: enabled
|
|
||||||
hoverEnabled: true
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
Loader {
|
Loader {
|
||||||
active: ma.containsMouse
|
active: parent.truncated && (connectMA.containsMouse || connectMA.drag.active || dropArea.containsDrag)
|
||||||
anchors.right: root.layoutDirection == Qt.LeftToRight ? undefined : nameLabel.right
|
anchors.right: root.layoutDirection == Qt.LeftToRight ? undefined : nameLabel.right
|
||||||
// Non-elided label
|
// Non-elided label
|
||||||
sourceComponent: Label {
|
sourceComponent: Label {
|
||||||
|
@ -158,7 +176,6 @@ RowLayout {
|
||||||
z: 100
|
z: 100
|
||||||
visible: true
|
visible: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ Item {
|
||||||
Column {
|
Column {
|
||||||
id: inputs
|
id: inputs
|
||||||
width: parent.width / 2
|
width: parent.width / 2
|
||||||
|
spacing: 1
|
||||||
Repeater {
|
Repeater {
|
||||||
model: node.attributes
|
model: node.attributes
|
||||||
delegate: Loader {
|
delegate: Loader {
|
||||||
|
@ -120,6 +121,7 @@ Item {
|
||||||
readOnly: root.readOnly
|
readOnly: root.readOnly
|
||||||
Component.onCompleted: attributePinCreated(attribute, inPin)
|
Component.onCompleted: attributePinCreated(attribute, inPin)
|
||||||
Component.onDestruction: attributePinDeleted(attribute, inPin)
|
Component.onDestruction: attributePinDeleted(attribute, inPin)
|
||||||
|
onPressed: root.pressed(mouse)
|
||||||
onChildPinCreated: attributePinCreated(childAttribute, inPin)
|
onChildPinCreated: attributePinCreated(childAttribute, inPin)
|
||||||
onChildPinDeleted: attributePinDeleted(childAttribute, inPin)
|
onChildPinDeleted: attributePinDeleted(childAttribute, inPin)
|
||||||
}
|
}
|
||||||
|
@ -130,6 +132,7 @@ Item {
|
||||||
id: outputs
|
id: outputs
|
||||||
width: parent.width / 2
|
width: parent.width / 2
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
spacing: 1
|
||||||
Repeater {
|
Repeater {
|
||||||
model: node.attributes
|
model: node.attributes
|
||||||
|
|
||||||
|
@ -143,7 +146,9 @@ Item {
|
||||||
nodeItem: root
|
nodeItem: root
|
||||||
attribute: object
|
attribute: object
|
||||||
readOnly: root.readOnly
|
readOnly: root.readOnly
|
||||||
|
onPressed: root.pressed(mouse)
|
||||||
Component.onCompleted: attributePinCreated(object, outPin)
|
Component.onCompleted: attributePinCreated(object, outPin)
|
||||||
|
Component.onDestruction: attributePinDeleted(attribute, outPin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue