Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions meshroom/ui/qml/GraphEditor/AttributePin.qml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ RowLayout {
signal pressed(var mouse)
signal edgeAboutToBeRemoved(var input)
signal clicked()
/// Emitted when the user pans with the middle mouse button while dragging an edge.
/// dx and dy are delta values in screen pixel coordinates.
signal panRequested(real dx, real dy)

objectName: attribute ? attribute.name + "." : ""
layoutDirection: Qt.LeftToRight
Expand Down Expand Up @@ -184,6 +187,8 @@ RowLayout {
enabled: !root.readOnly
anchors.fill: parent
hoverEnabled: root.visible
// Also accept middle button to handle graph panning without releasing the edge drag
acceptedButtons: Qt.LeftButton | Qt.MiddleButton

// Use the same negative margins as DropArea to ease pin selection
anchors.margins: inputDropArea.anchors.margins
Expand All @@ -194,16 +199,34 @@ RowLayout {
property bool isPressed: false // The mouse has been pressed but not released yet
property double initialX: 0.0
property double initialY: 0.0
property point lastPanPos: Qt.point(0, 0) // Last global position for middle-button panning

onPressed: function(mouse) {
if (mouse.button === Qt.MiddleButton) {
lastPanPos = mapToGlobal(mouse.x, mouse.y)
return
}
root.pressed(mouse)
isPressed = true
initialX = mouse.x
initialY = mouse.y
}

onReleased: {
inputDragTarget.Drag.drop()
onReleased: function(mouse) {
if (mouse.button === Qt.MiddleButton) {
return
}
if (mouse.button === Qt.LeftButton) {
inputDragTarget.Drag.drop()
} else {
inputDragTarget.Drag.cancel()
}
isPressed = false
dragTriggered = false
}

onCanceled: {
inputDragTarget.Drag.cancel()
isPressed = false
dragTriggered = false
}
Expand All @@ -213,6 +236,12 @@ RowLayout {
}

onPositionChanged: function(mouse) {
if (pressedButtons & Qt.MiddleButton) {
var globalPos = mapToGlobal(mouse.x, mouse.y)
root.panRequested(globalPos.x - lastPanPos.x, globalPos.y - lastPanPos.y)
lastPanPos = globalPos
return
}
// If there has been a significant move (5px along the -X or -Y axis) while the
// mouse is being pressed, then we can consider being in the dragging state
if (isPressed && (Math.abs(mouse.x - initialX) >= 5.0 || Math.abs(mouse.y - initialY) >= 5.0)) {
Expand Down Expand Up @@ -421,21 +450,41 @@ RowLayout {
anchors.rightMargin: outputDropArea.anchors.rightMargin

hoverEnabled: root.visible
// Also accept middle button to handle graph panning without releasing the edge drag
acceptedButtons: Qt.LeftButton | Qt.MiddleButton

property bool dragTriggered: false // An edge is being dragged from the output connector
property bool isPressed: false // The mouse has been pressed but not released yet
property double initialX: 0.0
property double initialY: 0.0
property point lastPanPos: Qt.point(0, 0) // Last global position for middle-button panning

onPressed: function(mouse) {
if (mouse.button === Qt.MiddleButton) {
lastPanPos = mapToGlobal(mouse.x, mouse.y)
return
}
root.pressed(mouse)
isPressed = true
initialX = mouse.x
initialY = mouse.y
}

onReleased: function(mouse) {
outputDragTarget.Drag.drop()
if (mouse.button === Qt.MiddleButton) {
return
}
if (mouse.button === Qt.LeftButton) {
outputDragTarget.Drag.drop()
} else {
outputDragTarget.Drag.cancel()
}
isPressed = false
dragTriggered = false
}

onCanceled: {
outputDragTarget.Drag.cancel()
isPressed = false
dragTriggered = false
}
Expand All @@ -445,6 +494,12 @@ RowLayout {
}

onPositionChanged: function(mouse) {
if (pressedButtons & Qt.MiddleButton) {
var globalPos = mapToGlobal(mouse.x, mouse.y)
root.panRequested(globalPos.x - lastPanPos.x, globalPos.y - lastPanPos.y)
lastPanPos = globalPos
return
}
// If there's been a significant move (5px along the -X or -Y axis) while the mouse is being
// pressed, then we can consider being in the dragging state.
if (isPressed && (Math.abs(mouse.x - initialX) >= 5.0 || Math.abs(mouse.y - initialY) >= 5.0)) {
Expand Down
6 changes: 6 additions & 0 deletions meshroom/ui/qml/GraphEditor/GraphEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,12 @@ Item {
}
}

onPanRequested: function(dx, dy) {
draggable.x += dx
draggable.y += dy
workspaceMoved()
}

// Interactive dragging: move the visual delegates
onPositionChanged: {
if (!selected || !dragging) {
Expand Down
9 changes: 9 additions & 0 deletions meshroom/ui/qml/GraphEditor/Node.qml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ Item {
// Already connected attribute with another edge in DropArea
signal edgeAboutToBeRemoved(var input)

/// Emitted when an attribute pin requests graph panning during edge drag (middle mouse button).
signal panRequested(real dx, real dy)

/// Emitted when child attribute pins are created
signal attributePinCreated(var attribute, var pin)
/// Emitted when child attribute pins are deleted
Expand Down Expand Up @@ -661,6 +664,8 @@ Item {
root.edgeAboutToBeRemoved(input)
}

onPanRequested: function(dx, dy) { root.panRequested(dx, dy) }

Component.onCompleted: attributePinCreated(attribute, outPin)
onChildPinCreated: attributePinCreated(childAttribute, outPin)
Component.onDestruction: attributePinDeleted(attribute, outPin)
Expand Down Expand Up @@ -739,6 +744,8 @@ Item {
root.edgeAboutToBeRemoved(input)
}

onPanRequested: function(dx, dy) { root.panRequested(dx, dy) }

onChildPinCreated: function(childAttribute, inPin) { attributePinCreated(childAttribute, inPin) }
onChildPinDeleted: function(childAttribute, inPin) { attributePinDeleted(childAttribute, inPin) }
}
Expand Down Expand Up @@ -849,6 +856,8 @@ Item {
root.edgeAboutToBeRemoved(input)
}

onPanRequested: function(dx, dy) { root.panRequested(dx, dy) }

onChildPinCreated: function(childAttribute, inParamsPin) { attributePinCreated(childAttribute, inParamsPin) }
onChildPinDeleted: function(childAttribute, inParamsPin) { attributePinDeleted(childAttribute, inParamsPin) }
}
Expand Down