Trim needless comments and fix the picker width

Remove comments that only restate the code, keeping the section banners
and the notes that carry a reason, a measured fact or an external
contract.

ButtonOptions.width claimed to be a fixed width but only set minWidth,
so the Graph and Texture pickers grew with the name they showed. It is
now what it promises, with a separate minWidth for the buttons that have
two forms. Narrow buttons shrink their padding, otherwise a 24px icon
button had 8px left for its glyph and truncate dropped it entirely.

__gm.labelsDropped() guards that class: the overflow guard only saw text
that was too wide, never a label truncated to nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-08 15:52:05 +02:00
1 parent f16801aef3
commit 4d84231b9f
115 files changed
+707 -1564

No files matched your search

+49 -8
View File
@@ -2,10 +2,8 @@
* Labels must be shortened to fit their control, not written past it. Runs last because it
* renames assets to absurd lengths to provoke the case.
*
* `__gm.textOverflows()` is a general guard rather than a check on one widget: it walks every
* visible text and reports the ones drawn wider than the widget that owns them. It was verified
* to actually catch this class of bug – against a build without the fix it reported the graph
* picker at 106 px over, and nothing else.
* `__gm.textOverflows()` walks every visible text and reports the ones drawn wider than their
* widget; against a build without the fix it reported the graph picker at 106 px over.
*/
/** A name far wider than any 200 px picker, so a control that does not truncate must spill. */
@@ -14,6 +12,17 @@ const LONG_NAME = 'Player movement with jumping and coyote time';
export async function overflow(t) {
const { check, sleep, json, evaluate, shot, mutate } = t;
const pickerWidths = async () => {
const out = {};
for (const tab of ['graph', 'texture']) {
await evaluate(`__gm.showTab(${JSON.stringify(tab)})`);
await sleep(300);
out[tab] = await json(`__gm.${tab}.pickerWidth()`);
}
return out;
};
const before = await pickerWidths();
await mutate(`
for (const asset of __gm.state.project.assets) {
if (asset.type === 'behavior' || asset.type === 'texture') asset.name = ${JSON.stringify(LONG_NAME)};
@@ -21,8 +30,18 @@ export async function overflow(t) {
__gm.state.select(null)`);
await sleep(600);
// 21. Every tab, because each one owns a different set of controls: the two header bars with
// their pickers, the inspector's dropdowns, and the toolbar.
// 21. The pickers keep the width they were given. `width` used to set only a minimum, so a
// picker grew with whatever name it happened to show and the header reflowed on load.
const after = await pickerWidths();
for (const tab of ['graph', 'texture']) {
check(
`the ${tab} picker keeps its width when the name gets long`,
before[tab] === 200 && after[tab] === 200,
`before ${before[tab]}, after ${after[tab]}`,
);
}
// 21a. Every tab, because each one owns a different set of controls.
for (const tab of ['scene', 'graph', 'texture', 'game']) {
await evaluate(`__gm.showTab(${JSON.stringify(tab)})`);
await sleep(400);
@@ -34,7 +53,7 @@ export async function overflow(t) {
);
}
// 21a. Shortened, not simply dropped: the value must still be readable and marked as cut.
// 21b. Shortened, not simply dropped: the value must still be readable and marked as cut.
await evaluate("__gm.showTab('graph')");
await sleep(400);
const shown = (await json('__gm.textOverflows(true)')).find((e) => e.text.startsWith('Player movement'));
@@ -45,7 +64,7 @@ export async function overflow(t) {
);
await shot('36-long-labels');
// 21b. An inspector full of dropdowns – the parent row and the enum fields – with a selection
// 21c. An inspector full of dropdowns – the parent row and the enum fields – with a selection
// whose asset name is now overlong too.
await evaluate("__gm.showTab('scene')");
await sleep(300);
@@ -53,4 +72,26 @@ export async function overflow(t) {
await sleep(500);
const inspector = await json('__gm.textOverflows()');
check('no label spills in the inspector', inspector.length === 0, JSON.stringify(inspector));
// 21d. The other direction: a control narrow enough to swallow its whole label draws nothing
// at all, which the overflow walk cannot see – an empty text spills over no edge.
for (const tab of ['scene', 'graph', 'texture']) {
await evaluate(`__gm.showTab(${JSON.stringify(tab)})`);
await sleep(400);
const dropped = await json('__gm.labelsDropped()');
check(
`no button is left without its label in the ${tab} tab`,
dropped.length === 0,
JSON.stringify(dropped),
);
}
// The narrowest buttons in the editor sit on a behaviour's variable rows.
await evaluate("__gm.state.select({ kind: 'asset', assetId: 'mover' })");
await sleep(400);
const onVariables = await json('__gm.labelsDropped()');
check(
'the variable rows keep their buttons labelled',
onVariables.length === 0,
JSON.stringify(onVariables),
);
}