Skip to content
Open
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
4 changes: 4 additions & 0 deletions meshroom/ui/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
QPoint,
QItemSelectionModel,
QItemSelection,
QPointF
)

from meshroom.core import sessionUid
Expand Down Expand Up @@ -1692,6 +1693,9 @@ def canSubmitNode(self, node: Node) -> bool:
selectedChunkChanged = Signal()
selectedChunk = makeProperty(QObject, "_selectedChunk", selectedChunkChanged, resetOnDestroy=True)

edgeDraggingChanged = Signal(bool)
edgeDragMousePosChanged = Signal(float, float)

nodeSelection = makeProperty(QObject, "_nodeSelection")

hoveredNodeChanged = Signal()
Expand Down
40 changes: 31 additions & 9 deletions meshroom/ui/qml/GraphEditor/AttributePin.qml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ RowLayout {
property double initialX: 0.0
property double initialY: 0.0

onClicked: function() {
root.clicked()
}

onPressed: function(mouse) {
root.pressed(mouse)
isPressed = true
Expand All @@ -329,19 +333,27 @@ RowLayout {
inputDragTarget.Drag.drop()
isPressed = false
dragTriggered = false
_currentScene.edgeDraggingChanged(false)
}

onClicked: function() {
root.clicked()
onCanceled: {
isPressed = false
dragTriggered = false
_currentScene.edgeDraggingChanged(false)
}

onPositionChanged: function(mouse) {
// 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)) {
dragTriggered = true
if (!dragTriggered) {
dragTriggered = true
_currentScene.edgeDraggingChanged(true)
}
var windowCoords = inputConnectMA.mapToItem(null, mouse.x, mouse.y) // null will map to window
_currentScene.edgeDragMousePosChanged(windowCoords.x, windowCoords.y)
}
}
}
}

Edge {
Expand Down Expand Up @@ -570,21 +582,31 @@ RowLayout {
initialY = mouse.y
}

onClicked: function() {
root.clicked()
}

onReleased: function(mouse) {
outputDragTarget.Drag.drop()
isPressed = false
dragTriggered = false
_currentScene.edgeDraggingChanged(false)
}

onClicked: function() {
root.clicked()
onCanceled: {
isPressed = false
dragTriggered = false
_currentScene.edgeDraggingChanged(false)
}

onPositionChanged: function(mouse) {
// 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)) {
dragTriggered = true
if (!dragTriggered) {
dragTriggered = true
_currentScene.edgeDraggingChanged(true)
}
var windowCoords = outputConnectMA.mapToItem(null, mouse.x, mouse.y) // null will map to window
_currentScene.edgeDragMousePosChanged(windowCoords.x, windowCoords.y)
}
}
Comment thread
Alxiice marked this conversation as resolved.
}
Expand Down
117 changes: 115 additions & 2 deletions meshroom/ui/qml/GraphEditor/GraphEditor.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects

import Controls 1.0
import MaterialIcons 2.2
Expand All @@ -18,6 +19,22 @@ Item {
property variant nodeTypesModel: null /// The list of node types that can be instantiated
property real maxZoom: 2.0
property real minZoom: 0.1

// Autoscroll properties
readonly property int autoscrollMargin: 100 // Border thickness (width in pixels)
readonly property int autoscrollSpeed: 15 // Speed factor
readonly property real maxScrollSpeed: 3.0 // Clamp scroll speed
property bool isDraggingEdge: false // Tracks whether we are dragging an AttributePin
property point dragMousePos: Qt.point(0, 0) // Position of the mouse during edge dragging

readonly property real borderHighlightOpacity: 0.05
readonly property color borderHighlightColor: Colors.blue
readonly property real borderHighlightWidth: 3
property bool highlightedBorderLeft: false
property bool highlightedBorderRight: false
property bool highlightedBorderTop: false
property bool highlightedBorderBottom: false

property var edgeAboutToBeRemoved: undefined

property var _attributeToDelegate: ({})
Expand Down Expand Up @@ -156,6 +173,102 @@ Item {
}
}

// Listen to the UIGraph edge drag infos
Connections {
target: _currentScene
ignoreUnknownSignals: true

function onEdgeDraggingChanged(dragging) {
root.isDraggingEdge = dragging
root.highlightedBorderRight=false
root.highlightedBorderLeft=false
root.highlightedBorderTop=false
root.highlightedBorderBottom=false
}

function onEdgeDragMousePosChanged(windowX, windowY) {
// Translate window coordinates into the GraphEditor coordinates
var localPos = root.mapFromItem(null, windowX, windowY)
root.dragMousePos = Qt.point(localPos.x, localPos.y)
}
}

// Add a timer to auto-scroll on the graph when edge dragging is active
Timer {
id: autoscrollTimer
interval: 20
running: root.isDraggingEdge
repeat: true

onTriggered: {
var mouseX = root.dragMousePos.x
var mouseY = root.dragMousePos.y
var deltaX = 0
var deltaY = 0

// Left
if (mouseX < root.autoscrollMargin) {
var factorX = Math.min(root.maxScrollSpeed, (root.autoscrollMargin - mouseX) / root.autoscrollMargin)
deltaX = root.autoscrollSpeed * factorX
}
// Right
else if (mouseX > root.width - root.autoscrollMargin) {
var factorX = Math.min(root.maxScrollSpeed, (mouseX - (root.width - root.autoscrollMargin)) / root.autoscrollMargin)
deltaX = -root.autoscrollSpeed * factorX
}
// Top
if (mouseY < root.autoscrollMargin) {
var factorY = Math.min(root.maxScrollSpeed, (root.autoscrollMargin - mouseY) / root.autoscrollMargin)
deltaY = root.autoscrollSpeed * factorY
}
// Bottom
else if (mouseY > root.height - root.autoscrollMargin) {
var factorY = Math.min(root.maxScrollSpeed, (mouseY - (root.height - root.autoscrollMargin)) / root.autoscrollMargin)
deltaY = -root.autoscrollSpeed * factorY
}
Comment thread
Alxiice marked this conversation as resolved.

root.highlightedBorderRight=false
root.highlightedBorderLeft=false
root.highlightedBorderTop=false
root.highlightedBorderBottom=false

// Apply scroll on workspaxe
if (deltaX !== 0 || deltaY !== 0) {
draggable.x += deltaX
draggable.y += deltaY
workspaceMoved()

if (deltaX>0) { root.highlightedBorderLeft=true }
else if (deltaX<0) { root.highlightedBorderRight=true }
if (deltaY>0) { root.highlightedBorderTop=true }
else if (deltaY<0) { root.highlightedBorderBottom=true }
}
}
}

// Display scroll direction
Rectangle {
enabled: root.isDraggingEdge
z: 100
color: "transparent"
border.color: root.borderHighlightColor
border.width: root.borderHighlightWidth

// Combine fill and margins into one anchor block
anchors {
fill: parent
leftMargin: root.highlightedBorderLeft ? 0 : -root.borderHighlightWidth
rightMargin: root.highlightedBorderRight ? 0 : -root.borderHighlightWidth
topMargin: root.highlightedBorderTop ? 0 : -root.borderHighlightWidth
bottomMargin: root.highlightedBorderBottom ? 0 : -root.borderHighlightWidth
}

Behavior on anchors.leftMargin { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
Behavior on anchors.rightMargin { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
Behavior on anchors.topMargin { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
Behavior on anchors.bottomMargin { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
}

MouseArea {
id: mouseArea
anchors.fill: parent
Expand Down Expand Up @@ -208,8 +321,8 @@ Item {
root.forceActiveFocus()
workspaceClicked()
}

onPositionChanged: {
onPositionChanged: function(mouse) {
if (drag.active)
workspaceMoved()
}
Expand Down
Loading