moveNodeDrag method
Moves nodes during a drag operation.
Call this from NodeWidget's GestureDetector.onPanUpdate. The delta is already in graph coordinates since GestureDetector is inside InteractiveViewer's transformed space - no conversion needed.
Parameters:
graphDelta: The movement delta in graph coordinates
Implementation
void moveNodeDrag(Offset graphDelta) {
final draggedNodeId = interaction.draggedNodeId.value;
if (draggedNodeId == null) return;
// Collect nodes that will be moved for event firing
final movedNodes = <Node<T>>[];
runInAction(() {
// Update node positions and visual positions
if (selectedNodeIds.contains(draggedNodeId)) {
// Move all selected nodes
for (final nodeId in selectedNodeIds) {
final node = _nodes[nodeId];
if (node != null) {
final newPosition = node.position.value + graphDelta;
node.position.value = newPosition;
// Update visual position with snapping
node.setVisualPosition(_config.snapToGridIfEnabled(newPosition));
movedNodes.add(node);
}
}
// Update drag-to-group highlight for the dragged node (Command+drag only)
final isCommandPressed = HardwareKeyboard.instance.isMetaPressed;
annotations.updateDragHighlight(draggedNodeId, isCommandPressed);
} else {
// Move single node
final node = _nodes[draggedNodeId];
if (node != null) {
final newPosition = node.position.value + graphDelta;
node.position.value = newPosition;
// Update visual position with snapping
node.setVisualPosition(_config.snapToGridIfEnabled(newPosition));
movedNodes.add(node);
// Update drag-to-group highlight (Command+drag only)
final isCommandPressed = HardwareKeyboard.instance.isMetaPressed;
annotations.updateDragHighlight(draggedNodeId, isCommandPressed);
}
}
});
// Mark moved nodes dirty for spatial index
internalMarkNodesDirty(movedNodes.map((n) => n.id));
// Fire drag event for all moved nodes
for (final node in movedNodes) {
events.node?.onDrag?.call(node);
}
}