/** * rgui HTML overlays — real DOM controls glued to nodes. * * Canvas cannot host interactive form controls, so rgui owns a positioned * DOM layer above the canvas and keeps each registered element glued to its * node's screen rect every frame (drag included). Size is screen-fixed * (overlays do not scale with zoom); only position follows. * * Visibility reuses the native readability rule: an overlay hides (without * being destroyed) whenever its node is collapsed into a pseudo-node, * fully off-screen, or too small to read — so collapsed stacks show only * boundary ports + the pseudo summary, never per-node config. */ import { type Graph, type GraphNode } from "../core/graph.js"; import type { ViewTransform } from "../core/grid.js"; import type { RgRule } from "../core/rule.js"; export interface NodeHtmlOverlay { el: HTMLElement; /** where to glue relative to the node rect (default "right") */ anchor?: "right" | "below" | "over"; /** * offset from the anchor point — screen px in "fixed" mode, WORLD units * in "zoom" mode (it belongs to the node's local layout, so it scales) */ offset?: { x: number; y: number; }; /** * "fixed" (default): screen-constant size, position glued to the node. * "zoom": scales with view.k like part of the node (lay out for k=1). * "fit": rgui measures the element's natural size and applies * scale = min(maxScale, node screen area / natural size) — the control fits * the node's on-screen area, whatever the node type's size. * In zoom/fit modes, when the applied scale drops below `minScale` the * overlay hides and the native/summarized content takes over. */ scale?: "fixed" | "zoom" | "fit"; /** * zoom/fit modes: hide when the applied scale drops below this * (default 0.75) — an unreadable control yields to the summary. * Hide always wins over scaling. */ minScale?: number; /** * fit mode: cap on the applied scale (default 1 — never upscale past the * element's natural size, keeping it crisp). Raise above 1 to let a small * overlay UPSCALE to fill a larger node (it grows past natural size, so it * fills the node's screen rect instead of sitting at native size with the * node showing around it — at the cost of some blur on a bitmap/canvas child). */ maxScale?: number; /** * "node": constrain the overlay to the node's screen rect (never larger * than the node); overflowing content scrolls ("auto", default) or is * cut ("hidden"). "viewport" (default): clipped by the viewport only. */ clip?: "node" | "viewport" | "none"; overflow?: "hidden" | "auto"; /** * pointer-events mode (default true). When true, only actual CONTROLS * inside the element receive pointer events (inputs, selects, buttons, * links, [contenteditable], [data-rgui-interactive]) — the background is * click-through so node drag / canvas pan keep working underneath. * Mark custom widgets with data-rgui-interactive. */ interactive?: boolean; /** called when the overlay is unmounted (replaced, node gone, destroy) */ destroy?: () => void; } export interface OverlayManager { /** glue/refresh all overlays for the current frame */ sync(graph: Graph, visibleNodes: GraphNode[] | null, view: ViewTransform, rule: RgRule, /** * screen rects (CSS px) cut OUT of the overlay layer — canvas-native * chrome (panels) that must stay visible and clickable above HTML * overlays. Clipping also removes pointer hits, so presses over a * cutout reach the canvas. */ cutouts?: Array<{ x: number; y: number; w: number; h: number; }>): void; destroy(): void; } export declare function createOverlayManager(canvas: HTMLCanvasElement, opts?: { /** * re-dispatch wheel events here (usually the rgui canvas) so pan/zoom * keeps working over overlays instead of scrolling the page. A wheel is * NOT forwarded when an ENGAGED overlay's inner scrollable can consume it. */ forwardWheelTo?: HTMLElement; /** * is this node engaged (selected)? An overlay only captures the wheel for * its own scrolling once engaged — selected, or holding DOM focus. Merely * hovering it must not steal the wheel, or a pan that sweeps the cursor * across a node stalls mid-gesture. */ isNodeEngaged?: (nodeId: string) => boolean; /** map view-space anchor points to raw screen (viewport rotation) */ transformPoint?: (x: number, y: number) => readonly [number, number]; }): OverlayManager; //# sourceMappingURL=overlayLayer.d.ts.map