startConnectionDrag method
Starts a connection drag from a port.
Call this from PortWidget's GestureDetector.onPanStart.
Parameters:
nodeId: The ID of the node containing the portportId: The ID of the port being dragged fromisOutput: Whether this is an output portstartPoint: The starting point in graph coordinatesnodeBounds: The bounds of the source node in graph coordinates
Returns the validation result. Check ConnectionValidationResult.allowed to determine if the drag started successfully.
Implementation
ConnectionValidationResult startConnectionDrag({
required String nodeId,
required String portId,
required bool isOutput,
required Offset startPoint,
required Rect nodeBounds,
Offset? initialScreenPosition,
}) {
// Validate source port before starting
final validationResult = canStartConnection(
nodeId: nodeId,
portId: portId,
isOutput: isOutput,
);
if (!validationResult.allowed) {
return validationResult;
}
// Fire connection start event
events.connection?.onConnectStart?.call(nodeId, portId, isOutput);
// Check if we need to remove existing connections
// (for ports that don't allow multiple connections)
final node = getNode(nodeId);
if (node != null) {
final port = node.allPorts.where((p) => p.id == portId).firstOrNull;
if (port != null && !port.multiConnections) {
// Remove existing connections from this port
final connectionsToRemove = _connections
.where(
(conn) => isOutput
? (conn.sourceNodeId == nodeId && conn.sourcePortId == portId)
: (conn.targetNodeId == nodeId &&
conn.targetPortId == portId),
)
.toList();
runInAction(() {
for (final connection in connectionsToRemove) {
removeConnection(connection.id);
}
});
}
}
// Create temporary connection
// Use the initial screen position (converted to graph) for initialCurrentPoint
// to avoid a sudden jump from port position to mouse position on first move.
// Note: initialScreenPosition is in global coordinates, so we use globalToGraph.
final initialCurrentPoint = initialScreenPosition != null
? globalToGraph(initialScreenPosition)
: startPoint;
runInAction(() {
// Disable panning during connection drag so InteractiveViewer
// doesn't steal the gesture from PortWidget's GestureDetector
interaction.panEnabled.value = false;
// Cursor is handled reactively via Observer in widget MouseRegions
interaction.temporaryConnection.value = TemporaryConnection(
startNodeId: nodeId,
startPortId: portId,
isStartFromOutput: isOutput,
startPoint: startPoint,
initialCurrentPoint: initialCurrentPoint,
startNodeBounds: nodeBounds,
);
});
return validationResult;
}