mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-07-30 14:58:37 +02:00
[ui] GraphEditor: Added Loader for Node Delegate
The Loader allows loading Backdrop Component for backdrop nodes and Standard Node component for other nodes
This commit is contained in:
parent
fce662b7f0
commit
ce25d0087b
1 changed files with 276 additions and 114 deletions
|
@ -827,141 +827,303 @@ Item {
|
|||
property bool updateSelectionOnClick: false
|
||||
property var temporaryEdgeAboutToBeRemoved: undefined
|
||||
|
||||
delegate: Node {
|
||||
id: nodeDelegate
|
||||
delegate: Loader {
|
||||
id: nodeLoader
|
||||
Component {
|
||||
id: nodeComponent
|
||||
Node {
|
||||
id: nodeDelegate
|
||||
|
||||
node: object
|
||||
width: uigraph.layout.nodeWidth
|
||||
node: object
|
||||
width: uigraph.layout.nodeWidth
|
||||
|
||||
mainSelected: uigraph.selectedNode === node
|
||||
hovered: uigraph.hoveredNode === node
|
||||
mainSelected: uigraph.selectedNode === node
|
||||
hovered: uigraph.hoveredNode === node
|
||||
|
||||
// ItemSelectionModel.hasSelection triggers updates anytime the selectionChanged() signal is emitted.
|
||||
selected: uigraph.nodeSelection.hasSelection ? uigraph.nodeSelection.isRowSelected(index) : false
|
||||
// ItemSelectionModel.hasSelection triggers updates anytime the selectionChanged() signal is emitted.
|
||||
selected: uigraph.nodeSelection.hasSelection ? uigraph.nodeSelection.isRowSelected(index) : false
|
||||
|
||||
onAttributePinCreated: function(attribute, pin) { registerAttributePin(attribute, pin) }
|
||||
onAttributePinDeleted: function(attribute, pin) { unregisterAttributePin(attribute, pin) }
|
||||
onAttributePinCreated: function(attribute, pin) { registerAttributePin(attribute, pin) }
|
||||
onAttributePinDeleted: function(attribute, pin) { unregisterAttributePin(attribute, pin) }
|
||||
|
||||
onPressed: function(mouse) {
|
||||
nodeRepeater.updateSelectionOnClick = true;
|
||||
nodeRepeater.ongoingDrag = true;
|
||||
onPressed: function(mouse) {
|
||||
nodeRepeater.updateSelectionOnClick = true;
|
||||
nodeRepeater.ongoingDrag = true;
|
||||
|
||||
let selectionMode = ItemSelectionModel.NoUpdate;
|
||||
let selectionMode = ItemSelectionModel.NoUpdate;
|
||||
|
||||
if(!selected) {
|
||||
selectionMode = ItemSelectionModel.ClearAndSelect;
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
}
|
||||
if(mouse.modifiers & Qt.ControlModifier) {
|
||||
selectionMode = ItemSelectionModel.Toggle;
|
||||
}
|
||||
if(mouse.modifiers & Qt.AltModifier) {
|
||||
let selectFollowingMode = ItemSelectionModel.ClearAndSelect;
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectFollowingMode = ItemSelectionModel.Select;
|
||||
if(!selected) {
|
||||
selectionMode = ItemSelectionModel.ClearAndSelect;
|
||||
}
|
||||
uigraph.selectFollowing(node, selectFollowingMode);
|
||||
// Indicate selection has been dealt with by setting conservative Select mode.
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
}
|
||||
if(mouse.modifiers & Qt.ControlModifier) {
|
||||
selectionMode = ItemSelectionModel.Toggle;
|
||||
}
|
||||
if(mouse.modifiers & Qt.AltModifier) {
|
||||
let selectFollowingMode = ItemSelectionModel.ClearAndSelect;
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectFollowingMode = ItemSelectionModel.Select;
|
||||
}
|
||||
uigraph.selectFollowing(node, selectFollowingMode);
|
||||
// Indicate selection has been dealt with by setting conservative Select mode.
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
}
|
||||
}
|
||||
else if (mouse.button === Qt.RightButton) {
|
||||
if(selected) {
|
||||
// Keep the full selection when right-clicking on an already selected node.
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(selectionMode != ItemSelectionModel.NoUpdate) {
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
uigraph.selectNodeByIndex(index, selectionMode);
|
||||
}
|
||||
|
||||
// If the node is selected after this, make it the active selected node.
|
||||
if(selected) {
|
||||
uigraph.selectedNode = node;
|
||||
}
|
||||
|
||||
// Open the node context menu once selection has been updated.
|
||||
if(mouse.button == Qt.RightButton) {
|
||||
nodeMenuLoader.load(node)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (mouse.button === Qt.RightButton) {
|
||||
if(selected) {
|
||||
// Keep the full selection when right-clicking on an already selected node.
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
|
||||
onReleased: function(mouse, wasDragged) {
|
||||
nodeRepeater.ongoingDrag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(selectionMode != ItemSelectionModel.NoUpdate) {
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
uigraph.selectNodeByIndex(index, selectionMode);
|
||||
}
|
||||
|
||||
// If the node is selected after this, make it the active selected node.
|
||||
if(selected) {
|
||||
uigraph.selectedNode = node;
|
||||
}
|
||||
|
||||
// Open the node context menu once selection has been updated.
|
||||
if(mouse.button == Qt.RightButton) {
|
||||
nodeMenuLoader.load(node)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onReleased: function(mouse, wasDragged) {
|
||||
nodeRepeater.ongoingDrag = false;
|
||||
}
|
||||
|
||||
// Only called when the node has not been dragged.
|
||||
onClicked: function(mouse) {
|
||||
if(!nodeRepeater.updateSelectionOnClick) {
|
||||
return;
|
||||
}
|
||||
uigraph.selectNodeByIndex(index);
|
||||
}
|
||||
|
||||
onDoubleClicked: function(mouse) { root.nodeDoubleClicked(mouse, node) }
|
||||
|
||||
onEntered: uigraph.hoveredNode = node
|
||||
onExited: uigraph.hoveredNode = null
|
||||
|
||||
onEdgeAboutToBeRemoved: function(input) {
|
||||
/*
|
||||
* Sometimes the signals are not in the right order because of weird Qt/QML update order
|
||||
* (next DropArea entered signal before previous DropArea exited signal) so edgeAboutToBeRemoved
|
||||
* must be set to undefined before it can be set to another attribute object.
|
||||
*/
|
||||
if (input === undefined) {
|
||||
if (nodeRepeater.temporaryEdgeAboutToBeRemoved === undefined) {
|
||||
root.edgeAboutToBeRemoved = input
|
||||
} else {
|
||||
root.edgeAboutToBeRemoved = nodeRepeater.temporaryEdgeAboutToBeRemoved
|
||||
nodeRepeater.temporaryEdgeAboutToBeRemoved = undefined
|
||||
// Only called when the node has not been dragged.
|
||||
onClicked: function(mouse) {
|
||||
if(!nodeRepeater.updateSelectionOnClick) {
|
||||
return;
|
||||
}
|
||||
uigraph.selectNodeByIndex(index);
|
||||
}
|
||||
} else {
|
||||
if (root.edgeAboutToBeRemoved === undefined) {
|
||||
root.edgeAboutToBeRemoved = input
|
||||
} else {
|
||||
nodeRepeater.temporaryEdgeAboutToBeRemoved = input
|
||||
|
||||
onDoubleClicked: function(mouse) { root.nodeDoubleClicked(mouse, node) }
|
||||
|
||||
onEntered: uigraph.hoveredNode = node
|
||||
onExited: uigraph.hoveredNode = null
|
||||
|
||||
onEdgeAboutToBeRemoved: function(input) {
|
||||
/*
|
||||
* Sometimes the signals are not in the right order because of weird Qt/QML update order
|
||||
* (next DropArea entered signal before previous DropArea exited signal) so edgeAboutToBeRemoved
|
||||
* must be set to undefined before it can be set to another attribute object.
|
||||
*/
|
||||
if (input === undefined) {
|
||||
if (nodeRepeater.temporaryEdgeAboutToBeRemoved === undefined) {
|
||||
root.edgeAboutToBeRemoved = input
|
||||
} else {
|
||||
root.edgeAboutToBeRemoved = nodeRepeater.temporaryEdgeAboutToBeRemoved
|
||||
nodeRepeater.temporaryEdgeAboutToBeRemoved = undefined
|
||||
}
|
||||
} else {
|
||||
if (root.edgeAboutToBeRemoved === undefined) {
|
||||
root.edgeAboutToBeRemoved = input
|
||||
} else {
|
||||
nodeRepeater.temporaryEdgeAboutToBeRemoved = input
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Interactive dragging: move the visual delegates
|
||||
onPositionChanged: {
|
||||
if(!selected || !dragging) {
|
||||
return;
|
||||
}
|
||||
// Compute offset between the delegate and the stored node position.
|
||||
const offset = Qt.point(x - node.x, y - node.y);
|
||||
|
||||
uigraph.nodeSelection.selectedIndexes.forEach(function(idx) {
|
||||
if(idx != index) {
|
||||
const delegate = nodeRepeater.itemAt(idx.row).item;
|
||||
delegate.x = delegate.node.x + offset.x;
|
||||
delegate.y = delegate.node.y + offset.y;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// After drag: apply the final offset to all selected nodes
|
||||
onMoved: function(position) {
|
||||
const offset = Qt.point(position.x - node.x, position.y - node.y);
|
||||
uigraph.moveSelectedNodesBy(offset);
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
enabled: !nodeRepeater.ongoingDrag
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
Behavior on y {
|
||||
enabled: !nodeRepeater.ongoingDrag
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Interactive dragging: move the visual delegates
|
||||
onPositionChanged: {
|
||||
if(!selected || !dragging) {
|
||||
return;
|
||||
}
|
||||
// Compute offset between the delegate and the stored node position.
|
||||
const offset = Qt.point(x - node.x, y - node.y);
|
||||
Component {
|
||||
id: backdropComponent
|
||||
Backdrop {
|
||||
id: backdropDelegate
|
||||
|
||||
uigraph.nodeSelection.selectedIndexes.forEach(function(idx) {
|
||||
if(idx != index) {
|
||||
const delegate = nodeRepeater.itemAt(idx.row);
|
||||
delegate.x = delegate.node.x + offset.x;
|
||||
delegate.y = delegate.node.y + offset.y;
|
||||
node: object
|
||||
// The Item instantiating the delegates.
|
||||
modelInstantiator: nodeRepeater
|
||||
|
||||
property var nodes: []
|
||||
|
||||
width: uigraph.layout.nodeWidth
|
||||
|
||||
mainSelected: uigraph.selectedNode === node
|
||||
hovered: uigraph.hoveredNode === node
|
||||
|
||||
// ItemSelectionModel.hasSelection triggers updates anytime the selectionChanged() signal is emitted.
|
||||
selected: uigraph.nodeSelection.hasSelection ? uigraph.nodeSelection.isRowSelected(index) : false
|
||||
|
||||
onPressed: function(mouse) {
|
||||
nodeRepeater.updateSelectionOnClick = true;
|
||||
nodeRepeater.ongoingDrag = true;
|
||||
|
||||
let selectionMode = ItemSelectionModel.NoUpdate;
|
||||
|
||||
if(!selected) {
|
||||
selectionMode = ItemSelectionModel.ClearAndSelect;
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
}
|
||||
if(mouse.modifiers & Qt.ControlModifier) {
|
||||
selectionMode = ItemSelectionModel.Toggle;
|
||||
}
|
||||
if(mouse.modifiers & Qt.AltModifier) {
|
||||
let selectFollowingMode = ItemSelectionModel.ClearAndSelect;
|
||||
if(mouse.modifiers & Qt.ShiftModifier) {
|
||||
selectFollowingMode = ItemSelectionModel.Select;
|
||||
}
|
||||
uigraph.selectFollowing(node, selectFollowingMode);
|
||||
// Indicate selection has been dealt with by setting conservative Select mode.
|
||||
selectionMode = ItemSelectionModel.Select;
|
||||
}
|
||||
}
|
||||
else if (mouse.button === Qt.RightButton) {
|
||||
if(selected) {
|
||||
// Keep the full selection when right-clicking on an already selected node.
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(selectionMode != ItemSelectionModel.NoUpdate) {
|
||||
nodeRepeater.updateSelectionOnClick = false;
|
||||
uigraph.selectNodeByIndex(index, selectionMode);
|
||||
}
|
||||
|
||||
// If the node is selected after this, make it the active selected node.
|
||||
if(selected) {
|
||||
uigraph.selectedNode = node;
|
||||
}
|
||||
|
||||
// Open the node context menu once selection has been updated.
|
||||
if(mouse.button == Qt.RightButton) {
|
||||
nodeMenuLoader.load(node)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onReleased: function(mouse, wasDragged) {
|
||||
nodeRepeater.ongoingDrag = false;
|
||||
}
|
||||
|
||||
// Only called when the node has not been dragged.
|
||||
onClicked: function(mouse) {
|
||||
if(!nodeRepeater.updateSelectionOnClick) {
|
||||
return;
|
||||
}
|
||||
uigraph.selectNodeByIndex(index);
|
||||
}
|
||||
|
||||
onDoubleClicked: function(mouse) { root.nodeDoubleClicked(mouse, node) }
|
||||
|
||||
onResized: function(width, height) {
|
||||
uigraph.resizeNode(node, width, height);
|
||||
}
|
||||
|
||||
onEntered: uigraph.hoveredNode = node
|
||||
onExited: uigraph.hoveredNode = null
|
||||
|
||||
// Interactive dragging: move the visual delegates
|
||||
onPositionChanged: {
|
||||
if(!selected || !dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute offset between the delegate and the stored node position.
|
||||
const offset = Qt.point(x - node.x, y - node.y);
|
||||
|
||||
nodes = []
|
||||
// Get all of the current children for the backdrop
|
||||
let children = getChildrenNodes();
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
const delegate = children[i];
|
||||
|
||||
// Ignore the selected delegates as they will be iterated upon separately
|
||||
if (delegate.selected)
|
||||
continue;
|
||||
|
||||
delegate.x = delegate.node.x + offset.x;
|
||||
delegate.y = delegate.node.y + offset.y;
|
||||
|
||||
// If the delegate is not the current Node
|
||||
if (delegate !== node)
|
||||
nodes.push(delegate.node);
|
||||
}
|
||||
|
||||
uigraph.nodeSelection.selectedIndexes.forEach(function(idx) {
|
||||
if(idx != index) {
|
||||
const delegate = nodeRepeater.itemAt(idx.row).item;
|
||||
delegate.x = delegate.node.x + offset.x;
|
||||
delegate.y = delegate.node.y + offset.y;
|
||||
|
||||
// If the delegate is not the current Node
|
||||
if (delegate !== node)
|
||||
nodes.push(delegate.node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// After drag: apply the final offset to all selected nodes
|
||||
onMoved: function(position) {
|
||||
const offset = Qt.point(position.x - node.x, position.y - node.y);
|
||||
uigraph.moveNodesBy(nodes, offset);
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
enabled: !nodeRepeater.ongoingDrag && !resizing
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
Behavior on y {
|
||||
enabled: !nodeRepeater.ongoingDrag
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After drag: apply the final offset to all selected nodes
|
||||
onMoved: function(position) {
|
||||
const offset = Qt.point(position.x - node.x, position.y - node.y);
|
||||
uigraph.moveSelectedNodesBy(offset);
|
||||
}
|
||||
// Source Component for the delegate
|
||||
sourceComponent: object.isBackdrop ? backdropComponent : nodeComponent;
|
||||
|
||||
Behavior on x {
|
||||
enabled: !nodeRepeater.ongoingDrag
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
Behavior on y {
|
||||
enabled: !nodeRepeater.ongoingDrag
|
||||
NumberAnimation { duration: 100 }
|
||||
onLoaded: {
|
||||
// Node's Z-Ordering
|
||||
nodeLoader.z = nodeLoader.item.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue