/** * rgui panels — screen-anchored palette/panel primitive drawn on the canvas. * * Panels are viewport chrome (constant screen size, never zoom), stacked at * an edge or placed at an explicit screen position. Items support * click-to-add and drag-onto-canvas (the host receives world coordinates * and creates whatever the item stands for). */ import type { ViewTransform } from "../core/grid.js"; import { type RgTheme } from "../core/theme.js"; import { type SideCoverage } from "../core/pack.js"; export interface PanelItem { id: string; label: string; /** row dot color (e.g. a signal-kind color); default gray */ color?: string; /** * right-aligned value shown at the end of the row (e.g. a count for a status * HUD: label on the left, value on the right). The label is clipped so it * never runs under the value. */ value?: string; } export interface Panel { id: string; title: string; /** stacking edge, or an explicit screen position */ anchor?: "left" | "right" | { x: number; y: number; }; /** panel width in px (default 180) */ w?: number; items: PanelItem[]; collapsed?: boolean; /** item clicked (no drag) — e.g. add at viewport center */ onItemClick?: (item: PanelItem, screen: { x: number; y: number; }) => void; /** item dragged onto the canvas and released */ onItemDrop?: (item: PanelItem, at: { world: { x: number; y: number; }; screen: { x: number; y: number; }; }) => void; } export declare const PANEL: { headerH: number; rowH: number; pad: number; gap: number; margin: number; defaultW: number; }; export interface PanelRect { panel: Panel; x: number; y: number; w: number; h: number; /** y of first item row (absolute screen px) */ itemsY: number; } /** screen rects for all panels (stacked per edge, explicit anchors as-is) */ export declare function panelLayout(panels: Panel[], size: { width: number; height: number; }): PanelRect[]; /** * Flush contact between panel rects: shared edge segments, per panel and * side. Fused boundaries dissolve exactly like snapped nodes (辺界消融) — * the shared border is not drawn and the touching corners square off, so * a snapped pair reads as one continuous card. */ export declare function panelCoverage(rects: PanelRect[]): Map; /** * Snap a dragged panel to the viewport margins and to other panels — edge * alignment and FLUSH contact, the same snap language as nodes (the flush * boundary then dissolves via panelCoverage). Per-axis nearest candidate * within `threshold` px; panel-relative candidates apply only when the * rects actually meet on the orthogonal axis. */ export declare function panelSnap(x: number, y: number, w: number, h: number, others: PanelRect[], size: { width: number; height: number; }, threshold?: number): { x: number; y: number; }; export declare function drawPanels(ctx: CanvasRenderingContext2D, rects: PanelRect[], theme?: RgTheme): void; export type PanelHit = { type: "header"; rect: PanelRect; } | { type: "item"; rect: PanelRect; item: PanelItem; } | { type: "body"; rect: PanelRect; }; export declare function panelHitAt(rects: PanelRect[], sx: number, sy: number): PanelHit | null; /** ghost chip drawn at the cursor while dragging a palette item */ export declare function drawPanelDragGhost(ctx: CanvasRenderingContext2D, _t: ViewTransform, item: PanelItem, sx: number, sy: number, theme?: RgTheme): void; //# sourceMappingURL=panelLayer.d.ts.map