Import it from @grafloria/renderer.
tsclass SelectionToolsController
Methods
constructor(config: Partial<SelectionToolsConfig> = {})getConfig(): SelectionToolsConfigupdateConfig(patch: Partial<SelectionToolsConfig>): voidisActive(): boolean— True while a resize / rotate / vertex drag owns the pointer.activeGesture(): 'resize' | 'rotate' | 'vertex' | null— The kind of gesture in flight (nullwhen idle) — hosts branch on it.activeGestureNodeId(): string | null— The node the in-flight gesture is acting on (nullwhen idle). Lets a host exclude it from a snap's sibling set — a box must not snap to itself.computeLayer(engine: DiagramEngine, zoom = 1): SelectionToolLayer— Compute the tool layer for the CURRENT selection.hitTest(layer: SelectionToolLayer, worldX: number, worldY: number): ToolHandle | null— Which tool (if any) is under a world point.hitTestResize( layer: SelectionToolLayer, worldX: number, worldY: number, slop = 0 ): ToolHandle | null— resize-ux: the RESIZE handle under a world point, with optional extra grab slop (world units). One entry point for the mouse ladder (slop 0) and the touch ladder (finger-sized slop), so bands and dots grow identically.beginResize( handle: ToolHandle, engine: DiagramEngine, worldX: number, worldY: number ): boolean— Arm a resize. Returns false when the handle/node is not resizable.updateResize( engine: DiagramEngine, worldX: number, worldY: number, modifiers: ToolModifierState = {}, snap?: (box: Rectangle) => Rectangle ): boolean— Live-resize the node (direct model mutation, like the drag tool: smooth, no command churn — the single undo entry is minted at {@link endGesture}).snapoptionally quantises the resulting box (grid / alignment) — the host passes the SnapController's hook so snapping composes with resizing.beginRotate(handle: ToolHandle, engine: DiagramEngine, worldX: number, worldY: number): booleanupdateRotate( engine: DiagramEngine, worldX: number, worldY: number, modifiers: ToolModifierState = {} ): boolean— Live-rotate; Shift snaps torotationSnapDegrees.beginVertexDrag(handle: ToolHandle, engine: DiagramEngine): booleanupdateVertexDrag( engine: DiagramEngine, worldX: number, worldY: number, snapPoint?: (p: Point) => Point ): booleanendGesture(engine: DiagramEngine): Command | null— End the active gesture and return the ONE command that makes it undoable (null for a no-op gesture). The model already sits at its final state — the command re-applies it (a no-op) and records the inverse, exactly like the node-drag commit.cancelGesture(engine: DiagramEngine): void— Abandon the gesture, restoring the model to its pre-gesture state.addVertexCommand(handle: ToolHandle, engine: DiagramEngine): Command | null— Insert a vertex at the clicked segment midpoint. Undoable.removeVertexCommand(handle: ToolHandle, engine: DiagramEngine): Command | null— Remove the vertex under the tool. Undoable.removeSelectionCommand(engine: DiagramEngine): Command | null— The command behind a remove button / halodelete: drop the whole selection (every selected node AND link) in ONE undo step.cloneNodeCommand( engine: DiagramEngine, nodeId: string, offset: Point = { x: 40, y: 40 } ): Command | null— Haloclone: a copy of the node, offset, as one undoable AddNodeCommand. Ports get fresh ids (via the engine's shared {@link remapNodePortIds}) so the clone never shares port identity with its source — the bug paste/duplicate already learned.forkNodeCommand( engine: DiagramEngine, nodeId: string, offset: Point = { x: 160, y: 0 } ): Command | null— Halofork: clone the node AND link the original to the clone — one undo step (MacroCommand). The link runs from an output-capable port on the source to an input-capable port on the clone; null when either side has no usable port.
Was this page helpful?