A selected vector shape has its own inspector rows (#129)
game-maker / gate (push) Successful in 2m12s
game-maker / suite (push) Successful in 7m45s

Stage 4 of #129. Until now the inspector showed the rows of the asset
when a shape was selected, so there was no way to give a shape a colour,
an outline or a place in the drawing order without editing the project
file. The rows for a shape now sit where every other selection puts its
rows.

- SHAPES lists every shape of the asset, topmost row drawn last, the
  same way a layer list reads. Selecting the asset itself shows the same
  list below its own rows, with no shape selected.
- Each row paints its shape with the commands the rasterizer uses
  (shapeDrawing plus paintDrawing) into a 22 px swatch, the whole canvas
  scaled in, so the row also says where on the canvas the shape sits.
- The four order buttons from the issue (forward, to front, backward, to
  back) sit in two rows of two, and a row can be dragged to another
  place with a marker line. They are disabled when there is nothing to
  move.
- VECTOR SHAPE carries name, fill, opacity and an outline checkbox, the
  checkbox adding and removing the stroke instead of hiding it; line
  colour and width appear with it. A dragged colour slider is one undo
  step, the style rows going through previewingHandlers like every other
  row.
- A line width of 0 is no stroke, which the command rejects, so the row
  clamps at 0.1.

Findings:

- locate('Outline') aims beside the control, because it gives the centre
  of the label text and a wider label pushes a fixed offset out of the
  field. __gm.inspectorField(label) knows the centre of the control.
- A click into a text field sets the cursor and selects nothing, so a
  typed hex landed appended to the old one and parseHex returned null
  without anything failing - typeText only checks that the text is
  contained. A Ctrl+A goes first now.
- Four buttons side by side cut "Backward" to "Backw...", which only the
  screenshot showed. Two rows of two now, as in the tilemap panel.

Tests: ./check.sh 128 files, 1897 tests (was 127/1883). Full e2e suite
locally instead of only CI because the change sits in the inspector and
touches every selection: ALL PASSED - 1179 checks (was 1172), module 47
at 24 checks (was 17). Three counter-checks hold: not reversing the list
fails 1 unit test and 2 e2e checks, dropping the gap correction when
dropping a row fails 2 unit tests and the drag check, and a constant
signature kills module 47 because the outline rows never appear.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-20 22:29:40 +02:00
1 parent 3a68067079
commit 78595ec80f
9 files changed
+958 -8

No files matched your search

+8
View File
@@ -32,6 +32,7 @@ import { currentNodePalette } from './graph/NodePalette';
import { currentSoundPicker } from './sound/SoundPicker';
import { currentImagePicker } from './texture/ImagePicker';
import { currentTilemapWidgets } from './panels/TilemapPanel';
import { currentShapeList } from './inspector/shapeSection';
import type { EditorState, TilemapTool } from './state';
import { rectOf, textProbe } from './textProbe';
@@ -466,6 +467,7 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
name: shape.name,
fill: shape.fill,
opacity: shape.opacity,
stroke: shape.stroke ? { ...shape.stroke } : null,
rings: shape.rings.map((ring) => ({
closed: ring.closed,
points: ring.points.map((point) => ({
@@ -478,6 +480,12 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
}));
},
selected: () => (state.selection?.kind === 'shape' ? state.selection.shapeId : ''),
/**
* The shape list in the inspector (#129, stage 4): the order it shows, top first, and where a
* row sits. A row carries a name that also stands in the tab, so a check cannot click it by text.
*/
shapeRows: () => currentShapeList()?.shownIds ?? null,
shapeRowAt: (shapeId: string) => currentShapeList()?.rowGlobal(shapeId) ?? null,
},
animation: {
current: () => editor.animationEditor.currentAssetId,