Add Get/Set properties nodes and a breadcrumb for opened sub-behaviors
Get properties / Set properties work like their variable counterparts:
one port per chosen property, an unconnected input writes its inline
value. A port chosen from the built-in list keeps that property's field
and default (height starts at 100, color is a colour field). "object" is
reserved for the fixed input, checked by the command and on load.
The property picker names the owning type ("Sprite width"), and text
fields can now carry a suggestion list; Get/Set property use it.
Double-clicking a call node shows the path of opened behaviors under the
graph header. Clicking an entry jumps back and trims the path; choosing
a behavior any other way hides it. Reopening a behavior already on the
path steps back to it instead of repeating it. The bar shows before the
graph switches, otherwise it clips the graph that was just fitted.
The "Add node..." header button is gone; nodes come from the context menu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e9fa592078
commit
854ae2e756
35 files changed
+1044
-101
No files matched your search
+17
-14
@@ -18,24 +18,24 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
const p = widget.getGlobalPosition();
|
||||
return { x: p.x + widget.w / 2, y: p.y + widget.h / 2 };
|
||||
};
|
||||
/** Centre of the first (or, with `last`, the topmost/last-drawn) visible text equal to `text`. */
|
||||
const locate = (text: string, last = false): { x: number; y: number } | null => {
|
||||
let found: Text | null = null;
|
||||
/** Centres of every visible text equal to `text`, in drawing order (the topmost last). */
|
||||
const locateAll = (text: string): { x: number; y: number }[] => {
|
||||
const hits: { x: number; y: number }[] = [];
|
||||
const walk = (node: Container): void => {
|
||||
if ((found && !last) || !node.visible) return;
|
||||
if (!node.visible) return;
|
||||
if (node instanceof Text && node.text === text) {
|
||||
found = node;
|
||||
const p = node.getGlobalPosition();
|
||||
hits.push({ x: p.x + node.width / 2, y: p.y + node.height / 2 });
|
||||
return;
|
||||
}
|
||||
for (const child of node.children) walk(child);
|
||||
};
|
||||
walk(app.stage);
|
||||
// TypeScript does not track the assignment inside `walk`, hence the disable and the cast.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (!found) return null;
|
||||
const node = found as Text;
|
||||
const p = node.getGlobalPosition();
|
||||
return { x: p.x + node.width / 2, y: p.y + node.height / 2 };
|
||||
return hits;
|
||||
};
|
||||
const locate = (text: string, last = false): { x: number; y: number } | null => {
|
||||
const hits = locateAll(text);
|
||||
return (last ? hits.at(-1) : hits[0]) ?? null;
|
||||
};
|
||||
/** Fill colour of a visible text, as `#rrggbb` – what tells an override label from a plain one. */
|
||||
const textColor = (text: string): string | null => {
|
||||
@@ -160,6 +160,7 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
objectsOf,
|
||||
sceneObjects: () => (state.activeScene ? objectsOf(state.activeScene.id) : []),
|
||||
locate,
|
||||
locateAll,
|
||||
inspectorField: fieldOf,
|
||||
inspectorInfo: () => inspector.debugInfo(),
|
||||
textColor,
|
||||
@@ -207,21 +208,23 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
// The canvas, not the whole tab: a centre measured through the header sits above the
|
||||
// drawing area.
|
||||
center: () => centreOf(graphEditor.canvas),
|
||||
pickerWidth: () => graphEditor.pickerWidth,
|
||||
pickerWidth: () => graphEditor.picker.w,
|
||||
pickerAt: () => centreOf(graphEditor.picker),
|
||||
snapping: () => graphEditor.canvas.snapEnabled,
|
||||
crumbs: () => graphEditor.breadcrumb.crumbsDrawn(),
|
||||
},
|
||||
/** The open image picker: what it offers, what is picked, and where a tile sits. */
|
||||
imagePicker: () => currentImagePicker()?.debugInfo() ?? null,
|
||||
imagePickerTile: (file: string) => currentImagePicker()?.tileGlobal(file) ?? null,
|
||||
texture: {
|
||||
current: () => textureEditor.currentAssetId,
|
||||
pickerWidth: () => textureEditor.pickerWidth,
|
||||
pickerWidth: () => textureEditor.picker.w,
|
||||
/** Where an image pixel of the shown sheet sits on screen (frames are dragged in image coordinates). */
|
||||
pointAt: (x: number, y: number) => textureEditor.imageToScreen(x, y),
|
||||
},
|
||||
container: {
|
||||
current: () => containerEditor.currentAssetId,
|
||||
pickerWidth: () => containerEditor.pickerWidth,
|
||||
pickerWidth: () => containerEditor.picker.w,
|
||||
center: () => centreOf(containerEditor),
|
||||
rect: () => containerEditor.canvasRect(),
|
||||
/** Where a template object is drawn, so a check can click or sample it. */
|
||||
|
||||
Reference in new issue
Block a user