debugHook.ts had grown to 1097 lines of unrelated test hooks. They now live in seven files under src/editor/debug/, grouped by topic. debugHook.ts only assembles them and is down to 86 lines. - The shape of window.__gm is unchanged for tools/. Measured in the browser before and after: 120 top-level keys and 313 leaves with their arity, byte-identical JSON. - The Text import is explicit in the helpers. Without it the name fell back to the DOM type and instanceof would never have matched. Findings: - The comment for vectorArt sat above pixelArt. It is back in place. - An orphaned duplicate comment on assetRow is gone. Tests: - ./check.sh: 145 files, 2192 tests, CHECK EXIT 0 (unchanged) - e2e 1-16,37,39-43,47,48: ALL PASSED, 734 checks - The shape probe turns red against a deliberately misnested hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
90 lines
5.2 KiB
TypeScript
90 lines
5.2 KiB
TypeScript
import { findAsset, findAssetOf } from '../../core/model/Project';
|
||
import { previewObjectId } from '../../core/model/animationPreview';
|
||
import { currentFramesDialog } from '../animation/FramesDialog';
|
||
import { currentRowDialog } from '../animation/RowDialog';
|
||
import { centreOf, type HookContext } from './hookHelpers';
|
||
|
||
/** The Texture, Animation, Tile and List tabs. */
|
||
export function documentHooks({ state, editor }: HookContext) {
|
||
const { textureEditor } = editor;
|
||
return {
|
||
texture: {
|
||
current: () => textureEditor.currentAssetId,
|
||
/** 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),
|
||
rect: () => textureEditor.canvasRect(),
|
||
/** Whether a press edits the selected frame's collision outline (#141). */
|
||
collisionMode: () => textureEditor.canvas.collisionMode,
|
||
/** The open "Generate collision…" dialog (#161), or null. */
|
||
generateDialog: () => textureEditor.generateDialog.current()?.info ?? null,
|
||
},
|
||
animation: {
|
||
current: () => editor.animationEditor.currentAssetId,
|
||
info: () => editor.animationEditor.shownInfo,
|
||
rootPickerAt: () => centreOf(editor.animationEditor.rootPicker),
|
||
addRowAt: () => centreOf(editor.animationEditor.addRowButton),
|
||
playAt: () => ({
|
||
...centreOf(editor.animationEditor.playButton),
|
||
text: editor.animationEditor.playButton.text,
|
||
}),
|
||
/** Where a cell, a row's header and a frame on the ruler sit – no text names a cell. */
|
||
cellAt: (trackId: string, frame: number) => editor.animationEditor.canvas.cellGlobal(trackId, frame),
|
||
headerAt: (trackId: string) => editor.animationEditor.canvas.headerGlobal(trackId),
|
||
rulerAt: (frame: number) => editor.animationEditor.canvas.rulerGlobal(frame),
|
||
keys: () => editor.animationEditor.canvas.keysDrawn(),
|
||
rows: () => editor.animationEditor.canvas.rowsDrawn(),
|
||
view: () => editor.animationEditor.canvas.viewInfo(),
|
||
scrub: (frame: number) => editor.animationEditor.canvas.scrub(frame),
|
||
/** The open row dialog: what it offers and holds, and a way to pick without clicking through menus. */
|
||
rowDialog: () => currentRowDialog()?.debugInfo() ?? null,
|
||
rowDialogPick: (target: string, property: string) => currentRowDialog()?.pick(target, property),
|
||
/** Copy/paste and frames (#102): what the clipboard holds, and the open frames dialog. */
|
||
clipboard: () => structuredClone(state.keyClipboard),
|
||
framesDialog: () => currentFramesDialog()?.debugInfo() ?? null,
|
||
framesDialogCount: (count: number) => currentFramesDialog()?.setCount(count),
|
||
framesDialogConfirm: () => {
|
||
const dialog = currentFramesDialog();
|
||
if (!dialog) return null;
|
||
const g = dialog.confirm.getGlobalPosition();
|
||
return { x: g.x + dialog.confirm.w / 2, y: g.y + dialog.confirm.h / 2 };
|
||
},
|
||
/** The preview above the timeline (#99): where a row's target is drawn and with which values. */
|
||
preview: {
|
||
/** The id the preview draws a row's target under (`''` = the root itself). */
|
||
objectId: (target: string) => {
|
||
const asset = findAssetOf(state.project, editor.animationEditor.currentAssetId, 'animation');
|
||
return previewObjectId(asset && findAsset(state.project, asset.root), target);
|
||
},
|
||
rect: (objectId: string) => editor.animationEditor.preview.objectRect(objectId),
|
||
item: (objectId: string) => editor.animationEditor.preview.itemDrawn(objectId),
|
||
info: () => editor.animationEditor.preview.debugInfo(),
|
||
fitAt: () => centreOf(editor.animationEditor.fitButton),
|
||
},
|
||
},
|
||
tile: {
|
||
current: () => editor.tileEditor.currentAssetId,
|
||
info: () => editor.tileEditor.shownInfo,
|
||
/** What the board drew: tiles, the picture it is showing and what stands in the way. */
|
||
board: () => editor.tileEditor.canvas.debugInfo(),
|
||
pictures: () => editor.tileEditor.strip.debugInfo(),
|
||
/** A tile of the board: its quarters and where each of them is drawn. */
|
||
tile: (index: number) => editor.tileEditor.canvas.tileDrawn(index),
|
||
/** Which board tile a cell of the sample map became – `-1` when that cell is empty. */
|
||
sampleTile: (row: number, column: number) => editor.tileEditor.canvas.sampleTile(row, column),
|
||
kindPickerAt: () => centreOf(editor.tileEditor.kindPicker),
|
||
addPictureAt: () => centreOf(editor.tileEditor.strip.addButton),
|
||
removePictureAt: () => centreOf(editor.tileEditor.strip.removeButton),
|
||
pictureRowAt: (index: number) => editor.tileEditor.strip.list.rowGlobal(String(index)),
|
||
fitAt: () => centreOf(editor.tileEditor.fitButton),
|
||
},
|
||
list: {
|
||
info: () => editor.listEditor.debugInfo(),
|
||
/** Where an item's widget sits, so a check can click it – a number field has no findable text. */
|
||
fieldAt: (index: number, field = '') => editor.listEditor.fieldAt(index, field),
|
||
/** The kind mark of a row, or of one field of a struct item – both are pickers. */
|
||
markAt: (index: number, field = '') => editor.listEditor.markAt(index, field),
|
||
nameAt: (index: number, field: string) => editor.listEditor.nameAt(index, field),
|
||
},
|
||
};
|
||
}
|