Open a sprite's texture or shader from the menus and inspector (#221)
A sprite's texture and shader were only reachable by hunting for them
in the asset panel. Every place that shows such a reference now leads
straight to it.
- Object menu (hierarchy and scene view): "Open texture" and "Open
shader" sit right below "Open asset" when the sprite has one. The
object's own values count, so an overridden shader opens the
override.
- Asset context menu: the same entries at the top.
- Inspector: every asset field with a value shows its label as a blue,
underlined link. One click selects the asset, a double click opens
it. An override stays gold and gets the underline too.
- The first click rebuilds the inspector, so the second one lands on a
different row. The inspector catches that second click before any
row sees it.
- New pure rule `references.ts`: the asset behind a reference field. A
frame leads to its sheet. Kinds without a tab (palette, font, sound)
get no menu entry.
- `followsPress` in `clicks.ts` keeps the double-click window and
tolerance in one place.
- `activateAsset` in `actions.ts`: opening means the same everywhere
as a double click in the asset panel, so a scene also becomes the
active one. The asset panel uses it too.
Tests:
- ./check.sh: 150 files, 2226 tests, CHECK EXIT 0 (before 148/2214).
- 12 new unit tests: 6 for the reference rule, 4 for the link in
createFieldRow, 2 for followsPress.
- 5 new e2e checks in 28l-ii: both menus, the link's look, click
selects, double click opens.
- e2e 1-16,26,28,35,39,40 on the final build: ALL PASSED, 732 checks.
- Counter-probes: no "Open ..." entries, no underline and a second
click never recognised each fail exactly at their checks.
- Check total 1341 (CI counted 1336 at fd6af84), computed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9b62d572b4
commit
1aae97b335
16 files changed
+512
-30
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import type { AssetType } from '../../core/model/AssetTypes';
|
||||
import { Button, Panel, Widget, activeDrag, currentMenu, ui } from '../../ui';
|
||||
import { Button, Label, Panel, Widget, activeDrag, currentMenu, ui } from '../../ui';
|
||||
import { Theme } from '../../ui/Theme';
|
||||
import { currentFontPicker } from '../font/FontPicker';
|
||||
import { currentSoundPicker } from '../sound/SoundPicker';
|
||||
@@ -140,6 +140,28 @@ export function uiHooks({ app, state, editor }: HookContext) {
|
||||
return (last ? hits.at(-1) : hits[0]) ?? null;
|
||||
},
|
||||
inspectorField: fieldOf,
|
||||
/**
|
||||
* The label of an inspector row as a link (#221): its centre, colour and whether it is underlined
|
||||
* and takes presses. Searched in the inspector only – the tab row says "Shader" too.
|
||||
*/
|
||||
inspectorLink: (text: string) => {
|
||||
let found: Label | null = null;
|
||||
const walk = (node: Container): void => {
|
||||
if (found || !node.visible) return;
|
||||
if (node instanceof Label && node.text === text) found = node;
|
||||
else for (const child of node.children) walk(child);
|
||||
};
|
||||
walk(inspector);
|
||||
const label = found as Label | null;
|
||||
if (!label) return null;
|
||||
const shown = label.children.find((child): child is Text => child instanceof Text);
|
||||
return {
|
||||
...centreOf(label),
|
||||
color: shown ? new Color(shown.style.fill as ColorSource).toHex() : null,
|
||||
underlined: label.underlined,
|
||||
pressable: label.eventMode === 'static',
|
||||
};
|
||||
},
|
||||
/** The inspector panel on screen – what tells whether a row of it can be clicked at all. */
|
||||
inspectorRect: () => rectOf(inspector),
|
||||
/** Where the focused widget sits on screen, or `null` – for checks on its focus border. */
|
||||
|
||||
Reference in new issue
Block a user