weasel API - v0.8.0
    Preparing search index...

    Interface UseGestureDispatcherOptions

    interface UseGestureDispatcherOptions {
        actions: ActionsRegistry;
        affordanceAt?: (
            worldPoint: { x: number; y: number },
        ) => AffordanceHit | null;
        ambientToolIds?: readonly string[];
        canvasRef: RefObject<HTMLCanvasElement | null>;
        classifyTarget?: (
            worldPoint: { x: number; y: number },
        ) => BodyClassification;
        clientToWorld?: (
            clientX: number,
            clientY: number,
        ) => { x: number; y: number };
        dispatcher?: Dispatcher;
        enabled?: boolean;
        getRuleCtx?: () => RuleCtx;
        keyboard?: boolean;
        onDoubleClick?: (world: { x: number; y: number }) => void;
        requestRedraw?: () => void;
        toolsById: ReadonlyMap<string, Tool<unknown>>;
    }
    Index

    Properties

    Action registry (ActionsRegistry from registry.tsx).

    affordanceAt?: (worldPoint: { x: number; y: number }) => AffordanceHit | null

    Optional affordance classifier. Called on every pointerdown with the world-space coordinates of the pointer. Returns an AffordanceHit when the pointer lands on a known affordance (resize handle, rotate handle, etc.) or null when the pointer hit open canvas.

    The hit is packed into InputEvent.pointerdown.affordance and flows through into InvocationCtx.drag.affordance. Action invokers that require a specific affordance (e.g. resizeAction requires handle:*) use this field as a guard in their start body.

    When omitted, affordance is always undefined — meaning only consumers that explicitly wire a classifier get affordance-gated behavior. <SceneCanvas> wires the full chrome→dispatcher bridge.

    ambientToolIds?: readonly string[]

    Ids (within toolsById) of always-on tools, whose bindings assemble at ambient scope. See DispatcherContext.ambientToolIds.

    canvasRef: RefObject<HTMLCanvasElement | null>

    Ref to the canvas element. Pointer/wheel/multitouch listeners attach here.

    classifyTarget?: (worldPoint: { x: number; y: number }) => BodyClassification

    Optional body classifier. Called on every pointerdown with the world-space coordinates of the pointer. Its result is packed onto the event as bodyTarget + bodyKind, which matchTarget reads to resolve the string-form TargetSpec values in Tool.bindings.

    body is 'empty' when nothing is under the pointer, 'selected-body' when the topmost hit belongs to the current selection, or 'unselected-body' when it belongs to a node that isn't selected. kind is the hit node's semantic kind, when the scene can name it.

    When omitted, every body-derived target form ('empty', 'selected-body', 'unselected-body', kind:<k>, kind:<k>:selected) never matches — bindings using those specs are silently skipped. <SceneCanvas> wires this.

    clientToWorld?: (clientX: number, clientY: number) => { x: number; y: number }

    Converts a client-space pointer position (e.g. e.clientX, e.clientY) to world-space coordinates. When supplied, every pointer/wheel event's x/y is converted before the dispatcher builds InvocationCtx.world.

    Without this, ctx.world is populated with the raw client coords, which silently breaks any action whose overlay/output uses absolute world positions (marquee, lasso polyline, world-space affordances). Actions that only read drag.delta are unaffected because client→world deltas are equal at scale 1, but as soon as a consumer pans/zooms the view the deltas diverge too.

    <SceneCanvas> always wires this via its canvas rect + current view. Tests / harnesses without a view can omit it and continue passing raw coordinates as before.

    dispatcher?: Dispatcher

    Optional pre-created Dispatcher. When provided, this hook pumps events into the supplied instance instead of creating its own. Lets a parent scope (e.g. <SceneCanvas>) share one dispatcher between the gesture mounter and other consumers (the preview-ghost layer).

    enabled?: boolean

    Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it).

    getRuleCtx?: () => RuleCtx

    Thunk returning the live RuleCtx for the current frame. When supplied, the dispatcher filters matched candidates by their declared Action.eligible rule (omitted => always eligible). <SceneCanvas> wires this; tests / harnesses without chrome-caps state can omit it.

    keyboard?: boolean

    Default true. Set false to leave the window keydown/keyup listeners unattached so keyboard-bound actions never dispatch — pointer, wheel, and contextmenu channels stay live. <SceneCanvas> wires this to enableKeybindings, so opting out of keybindings disables the modern dispatcher key path as well as the legacy useKeybindings hook.

    onDoubleClick?: (world: { x: number; y: number }) => void

    Observer fired whenever the dispatcher synthesizes a double click, in world coordinates. Runs BEFORE the event is dispatched and independently of which binding (if any) handles it.

    This is deliberately not an Action. <SceneCanvas onDoubleClick> is a notification — "the user double-clicked, here's what they hit" — and a notification must not compete with behavior for the gesture. As a binding it would lose to enterPathEdit on any body hit and silently never fire. Routing it here keeps a single definition of "double click" (the point of consolidating the kit's three detectors) without giving it first-match-wins semantics it shouldn't have.

    requestRedraw?: () => void

    Invoked once per pump event (pointermove, pointerup, pointercancel, key-held up-phase, multitouch move) when a dispatcher-side handle is in flight. Lets the host canvas schedule a redraw so dispatcher-only overlays (marquee, lasso, preview-ghost) repaint on each frame.

    Required because dispatcher actions don't go through the legacy tools.dispatcher.onGestureChange redraw bump that ambient tool drags relied on. Without it, the overlay layer's draw never runs between pointerdown and pointerup, and the chrome flashes once at gesture start and then sits frozen until the gesture ends.

    <SceneCanvas> wires this to the canvas's requestRedraw. Test harnesses can omit it; their dispatchers won't paint between events but that's already the test contract.

    toolsById: ReadonlyMap<string, Tool<unknown>>

    Tool definitions keyed by id. Typically passes an empty Map.