controlGesture method
DiagramToolGesture
controlGesture(
- String id,
- String nodeId,
- DiagramPathControl control, {
- required DiagramPoint pointerOrigin,
- bool splitSegment = false,
Implementation
DiagramToolGesture controlGesture(
String id,
String nodeId,
DiagramPathControl control, {
required DiagramPoint pointerOrigin,
bool splitSegment = false,
}) {
final source = _store.state.document.elementById(id) as ShapeElement;
final resolved = _store.scene.shapeById(id)!;
final outline = resolved.editablePath!;
final key = resolved.definition.pathValue!;
final path = _pathOf(id)!;
var targetId = nodeId;
final index = _index(path, nodeId);
final node = outline.nodes[index];
final localOrigin = splitSegment
? outline.segmentMidpoints[index]
: node.position +
switch (control) {
DiagramPathControl.anchor => DiagramPoint.zero,
DiagramPathControl.incoming => node.incoming,
DiagramPathControl.outgoing => node.outgoing,
};
final worldOrigin = resolved.localToWorld(localOrigin);
// Positions normalize against the frame the path has once split, as
// adding the point reframes it before the point moves.
var edited = source;
if (splitSegment) {
var suffix = path.nodes.length;
while (path.nodes.any((n) => n.id == 'node-$suffix')) {
suffix++;
}
targetId = 'node-$suffix';
edited = reframe(source, key, split(path, nodeId, newNodeId: targetId));
}
return DiagramToolGesture(
label: 'Edit path',
preview: (start, pointer) {
if (!splitSegment && pointer.world == pointerOrigin) {
return DiagramGesturePreview.none;
}
var target = worldOrigin + pointer.world - pointerOrigin;
if (pointer.shiftPressed &&
!splitSegment &&
!path.closed &&
control == DiagramPathControl.anchor &&
(index == 0 || index == path.nodes.length - 1)) {
final neighbor = outline.nodes[index == 0 ? 1 : index - 1];
target = DiagramSnapPolicy.endpoint(
resolved.localToWorld(neighbor.position),
target,
_store.state.options.snaps.rotationSnap,
);
}
final frame = edited.frame;
final local = target.rotateAround(frame.center, -edited.rotation);
final normalized = DiagramPoint(
(local.x - frame.left) / frame.width,
(local.y - frame.top) / frame.height,
);
return DiagramGesturePreview(
verbs: [
if (splitSegment)
DiagramVerbInvocation(
[id],
'addPathPoint',
{'after': nodeId, 'id': targetId},
),
DiagramVerbInvocation(
[id],
'movePathControl',
{'node': targetId, 'control': control, 'position': normalized},
),
],
);
},
);
}