Fix findUsages/undo/node-lookup bugs, split Viewport and Editor, share command and inspector helpers

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-08 09:22:49 +02:00
1 parent 1eb28314cf
commit f140c2fd77
58 files changed
+1969 -1171

No files matched your search

-3
View File
@@ -37,12 +37,9 @@ export const Theme = {
accentText: 0xffffff,
text: 0xe6e8ee,
textMuted: 0x8a90a0,
textDisabled: 0x5a5f6d,
selection: 0x2b4a80,
override: 0xf0b13d,
danger: 0xe0553f,
viewport: 0x121316,
grid: 0x1f2126,
gizmo: 0x4c8dff,
/** Behavior symbols and owner links. */
behavior: 0xb066ff,
+33
View File
@@ -19,3 +19,36 @@ export function drawControlBox(g: Graphics, w: number, h: number, options: Contr
g.roundRect(x, y, w, h, radius).fill(fill);
g.roundRect(x + 0.5, y + 0.5, w - 1, h - 1, radius).stroke({ width: 1, color: border });
}
export interface GridOptions {
/** Where the origin of the drawn space sits on screen, in the same pixels as `w`/`h`. */
originX: number;
originY: number;
/** Spacing in screen pixels (world/graph step times zoom). */
step: number;
w: number;
h: number;
alpha: number;
/** Alpha of the two lines through the origin; omitted = no axes (the graph has no origin to show). */
axisAlpha?: number;
}
/**
* The background grid of the scene view and the graph editor. Drawn in white at a low alpha
* rather than in a fixed colour, so it reads on whatever background the scene sets.
* `g` is cleared by the caller, which also decides when the step is too dense to be useful.
*/
export function drawGrid(g: Graphics, options: GridOptions): void {
const { originX, originY, step, w, h, alpha, axisAlpha } = options;
const startX = ((originX % step) + step) % step;
const startY = ((originY % step) + step) % step;
for (let x = startX; x < w; x += step) g.moveTo(x, 0).lineTo(x, h);
for (let y = startY; y < h; y += step) g.moveTo(0, y).lineTo(w, y);
g.stroke({ width: 1, color: GRID_COLOR, alpha });
if (axisAlpha === undefined) return;
const axis = { width: 1, color: GRID_COLOR, alpha: axisAlpha };
if (originX >= 0 && originX <= w) g.moveTo(originX, 0).lineTo(originX, h).stroke(axis);
if (originY >= 0 && originY <= h) g.moveTo(0, originY).lineTo(w, originY).stroke(axis);
}
const GRID_COLOR = 0xffffff;
+2 -2
View File
@@ -2,8 +2,8 @@ export { Widget, Box, type Size } from './Widget';
export { HStack, VStack, Spacer, Stack, type StackOptions } from './layout/Stack';
export { Theme, textStyle, type TextStyleToken } from './Theme';
export { initUI, ui, type UIContext } from './UIContext';
export { drawControlBox, type ControlBoxOptions } from './draw';
export { clamp, centreY } from './math';
export { drawControlBox, drawGrid, type ControlBoxOptions, type GridOptions } from './draw';
export { clamp, centreY, zoomFactor } from './math';
export { Label } from './widgets/Label';
export { Button } from './widgets/Button';
export { Checkbox } from './widgets/Checkbox';
+9
View File
@@ -7,3 +7,12 @@ export function clamp(value: number, lo: number, hi: number): number {
export function centreY(containerHeight: number, itemHeight: number): number {
return Math.round((containerHeight - itemHeight) / 2);
}
/**
* Zoom multiplier for one wheel event. Exponential, so scrolling up and back down by the same
* amount lands exactly where it started. The caller clamps the result into its own range –
* the scene view and the graph editor allow very different zoom levels.
*/
export function zoomFactor(deltaY: number): number {
return Math.exp(-deltaY * 0.0015);
}