Meshroom/meshroom/ui/qml/GraphEditor/AttributePin.qml

160 lines
4.8 KiB
QML
Executable file

import QtQuick 2.9
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
/**
The representation of an Attribute on a Node.
*/
RowLayout {
id: root
property var nodeItem
property var attribute
property bool readOnly: false
// position of the anchor for attaching and edge to this attribute pin
readonly property point edgeAnchorPos: Qt.point(edgeAnchor.x + edgeAnchor.width/2,
edgeAnchor.y + edgeAnchor.height/2)
readonly property bool isList: attribute.type == "ListAttribute"
signal childPinCreated(var childAttribute, var pin)
signal childPinDeleted(var childAttribute, var pin)
objectName: attribute.name + "."
layoutDirection: attribute.isOutput ? Qt.RightToLeft : Qt.LeftToRight
spacing: 1
// Instantiate empty Items for each child attribute
Repeater {
model: isList ? attribute.value : ""
onItemAdded: {childPinCreated(item.childAttribute, item)}
onItemRemoved: {childPinDeleted(item.childAttribute, item)}
delegate: Item {
property var childAttribute: object
}
}
Rectangle {
id: edgeAnchor
width: 6
height: width
radius: isList ? 0 : width/2
anchors.verticalCenter: parent.verticalCenter
border.color: "#3e3e3e"
color: (dropArea.containsDrag && dropArea.containsDrag) || attribute.isLink ? "#3e3e3e" : "white"
DropArea {
id: dropArea
property bool acceptableDrop: false
anchors.fill: parent
onEntered: {
// Filter drops:
if( drag.source.objectName != dragTarget.objectName // not an edge connector
|| drag.source.nodeItem == dragTarget.nodeItem // connection between attributes of the same node
|| dragTarget.isOutput // connection on an output
|| dragTarget.attribute.isLink) // already connected attribute
{
drag.accepted = false
}
dropArea.acceptableDrop = drag.accepted
}
onExited: acceptableDrop = false
onDropped: {
_reconstruction.addEdge(drag.source.attribute, dragTarget.attribute)
}
}
Item {
id: dragTarget
objectName: "edgeConnector"
readonly property alias attribute: root.attribute
readonly property alias nodeItem: root.nodeItem
readonly property bool isOutput: attribute.isOutput
readonly property alias isList: root.isList
anchors.centerIn: root.state == "Dragging" ? undefined : parent
//anchors.verticalCenter: root.verticalCenter
width: 2
height: 2
Drag.active: connectMA.drag.active
Drag.hotSpot.x: width*0.5
Drag.hotSpot.y: height*0.5
}
MouseArea {
id: connectMA
drag.target: dragTarget
drag.threshold: 0
enabled: !root.readOnly
anchors.fill: parent
onReleased: dragTarget.Drag.drop()
}
Edge {
id: connectEdge
visible: false
point1x: parent.width / 2
point1y: parent.width / 2
point2x: dragTarget.x + dragTarget.width/2
point2y: dragTarget.y + dragTarget.height/2
color: nameLabel.palette.text
}
}
// Attribute name
Label {
id: nameLabel
text: attribute.name
elide: Text.ElideMiddle
Layout.fillWidth: true
font.pointSize: 5
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 {
active: ma.containsMouse
anchors.right: root.layoutDirection == Qt.LeftToRight ? undefined : nameLabel.right
// Non-elided label
sourceComponent: Label {
leftPadding: root.layoutDirection == Qt.LeftToRight ? 0 : 1
rightPadding: root.layoutDirection == Qt.LeftToRight ? 1 : 0
text: attribute.name
background: Rectangle {
color: palette.window
}
}
}
}
state: connectMA.pressed ? "Dragging" : ""
states: [
State {
name: ""
},
State {
name: "Dragging"
PropertyChanges {
target: connectEdge
z: 100
visible: true
}
}
]
}