Three follow-ups to the hierarchy groups. Dragging a row that belonged
to a multi-selection moved only that one row. The group dialog could
only create a new group. The group row drew its folder in front of the
label, unlike every other row in the hierarchy.
- Dragging a selected row moves every selected object. This holds for
reordering, dropping into a group or between its members, dragging
out of a group and dropping onto an object as new parent.
- The moved objects land side by side in hierarchy order, whichever
row was grabbed. The whole move is one undo step.
- A selected child of a selected object travels with its parent, not
on its own. Dropping the selection onto its own rows does nothing.
- Dragging a row that is not selected still moves only that row.
- hierarchyDrop.moveObjects replaces the single-object rule. One object
is the case with one element, so the old drop tests hold unchanged.
- The group dialog has a "Group" dropdown: New group or an existing
group. Picking a group greys out the name and turns the button into
"Add". A group that holds all chosen objects already is not offered.
- Rename keeps using the dialog without the dropdown.
- ListRow draws an end icon at the very right and the hint left of it.
Only the hierarchy uses iconAtEnd, so other lists do not change.
- New test hook __gm.hierarchyHint() gives the centre of a row's hint.
Not clicked in the browser: dragging a selection in the container tab
and onto an object as parent. Only the unit tests cover these.
Tests:
- ./check.sh: 178 files, 2564 tests, CHECK EXIT 0
- e2e 1 + 52: ALL PASSED, 27 checks
- 7 new unit tests in hierarchy-drop.test.ts, 4 new e2e checks in
52i and 52j with real clicks and a real drag
- 4 counter-probes bite: drop rule ignores the selection (5 unit tests
fail), icon column not kept free, dialog ignores the picked group,
panel ignores the selection (only o2 lands in the group)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A scene with a hundred crates fills the hierarchy with a hundred rows.
Groups bundle top-level objects under one folder row that folds away.
They exist for the editor only. Parenting, positions and the game do
not see them.
- Model: a scene or container template holds a list of groups, an
object may carry a groupId. Old projects load unchanged. Loading
drops empty groups and members that are no longer top level.
- Only top-level objects can join a group. Parenting a member takes it
out of the group, and Undo puts it back. There are no groups in
groups.
- Order: treeOrder lists the members together, where the first one
stands. The same order decides drawing at equal z, in the editor and
in the game, so the hierarchy and the picture cannot disagree. The
stored object list stays untouched when grouping.
- Hierarchy: a group row shows a folder icon, the name and the member
count. Clicking it selects all members and keeps it folded. Selecting
a single member elsewhere unfolds it. Folding lasts for the session.
- Create with "Group..." in the object menu. A name dialog asks first,
so creating is one Undo step and Cancel creates nothing.
- The group menu has Select members, Rename... and Ungroup. The object
menu adds "Remove from group".
- Drag and drop: onto the group row appends, into a gap between members
inserts there, next to a row outside leaves the group. Dragging the
group row moves all members as a block. The drop rules live in
hierarchyDrop.ts as a pure function.
- Copy and paste keeps a top-level copy in the group of its original.
A container built from group members takes their place in the group.
- Clicking an object that is already selected together with others now
keeps only that object selected. ListView narrows the selection on
release, so a drag starting on such a row keeps the selection.
Not checked in the browser: groups in the container tab, "Remove from
group", Ctrl-click on a group row and a drag out of a multi-selection.
The code path covers them.
Tests:
- check.sh: 177 files, 2552 tests, CHECK EXIT 0
- e2e 1, 51, 52: ALL PASSED, 31 checks (new module 52)
- 19 new unit tests in object-groups.test.ts and hierarchy-drop.test.ts
- 9 counter-probes, all fail as expected (7 unit, 2 in the browser)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>