Show lists in the inspector and variables in their own tab (#252)
game-maker / gate (push) Successful in 3m24s
game-maker / suite (push) Successful in 10m22s

The List tab could show one list at a time and was the only place to
see its items. A list now shows its items right where it lives, and a
new Variables tab shows all variables of an asset or placed object.

- InlineList draws the items of a list under its row in the inspector,
  in struct fields and in the Variables tab. A list inside a list or a
  struct field is drawn the same way, one step indented.
- The index column is the indent. Items sit under their list without an
  own margin, and the index column is 16 px wide instead of 28 px.
- Above 20 items (INLINE_LIMIT) the rest collapses into "... N more -
  open in tab". During a run the rows show the values from the game.
- ListHead puts "N items" and "+ Item" in one row. "N items" opens the
  list in a tab. A separate Open button squeezed the counter to zero
  width in the narrow inspector column.
- VariablesEditor shows every variable of a behavior asset, a variables
  asset or a placed behavior. On an asset it edits the declarations. On
  a placed object an edit only overrides that object, with the usual
  reset and push buttons.
- Opening a list inside a tab adds a new tab and keeps the open one.
  valuesKey gives each list its own document, so a list that is already
  open is shown instead of opened twice.
- Titles read "Pickup · Variables" or "Listy · nums · [3]". The tab
  closes when its asset or object is deleted.
- Lists on node inputs stay inline only, a node owns no variables.
- The List tab, ListEditor and the __gm.list hook are gone.

Tests:
- ./check.sh: 181 files, 2645 tests, CHECK EXIT 0
- GM_STEPS=1,21,22,32: ALL PASSED, 123 checks
- e2e 21 is rewritten for inline lists and the new tab, 22 and 32 are
  adapted. Sum in README: 1486 (+6 in 21, -1 in 22), counted by hand.
- Counter-probes fail as expected: sub-lists not told apart (1 unit
  test), sub-list replacing the open tab, all items drawn inline (60
  rows instead of 20), no live values (0 rows at 24 items in a run).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-09-27 21:56:21 +02:00
1 parent 92fad6b9e3
commit 4857bb75e6
26 files changed
+1203 -427

No files matched your search

+10 -3
View File
@@ -22,6 +22,7 @@ import {
type FieldHandlers,
fieldDef,
type FieldRow,
indentedBy,
MARK_WIDTH,
nameWidth,
READ_ONLY,
@@ -77,16 +78,20 @@ export function buildVariable(
const name = nameCell(def.key, 0, edit && ((next) => edit.rename(next)));
const head = gridRow(0, markLabel(def.kind), name);
let setValue: (next: PropertyValue) => void = () => {};
let below: Widget | undefined;
if (def.kind === 'struct') {
head.add(new Spacer(), 1);
if (edit) head.add(addFieldMenu(edit, []));
} else {
setValue = addValue(head, createField(host, def, value, handlers));
const field = createField(host, def, value, handlers);
setValue = addValue(head, field);
below = field.below;
}
if (keep) head.add(keepButton(keep));
if (edit) head.add(removeButton(edit.remove));
const refreshActions = actions ? attachRowActions(head, actions) : () => {};
host.body.add(head);
if (below) host.body.add(indentedBy(below, 1));
if (def.kind === 'struct') {
if (def.fields.length === 0) addNote(host, 'No fields yet.', 'small');
@@ -141,9 +146,11 @@ function structFieldRows(
continue;
}
const own = handlers.structFieldHandlers?.([...path, field.key], field) ?? READ_ONLY;
setters.set(field.key, addValue(row, createField(host, fieldDef(field), item, own)));
const sub = createField(host, fieldDef(field), item, own);
setters.set(field.key, addValue(row, sub));
if (edit) row.add(removeButton(() => edit.removeField(path, field)));
host.body.add(row);
if (sub.below) host.body.add(indentedBy(sub.below, path.length + 2));
}
return (next) => {
for (const field of fields) setters.get(field.key)?.(structFieldValue(next, field));
@@ -183,7 +190,7 @@ export function markLabel(kind: string): Widget {
}
/**
* A kind mark that can be clicked – the List tab's way of saying what an item holds. The label may
* A kind mark that can be clicked – a list's way of saying what an item holds. The label may
* take the button's whole width: the column is sized for its widest mark, and the usual inset
* would cut `Aa` to `A…`.
*/