Group scene objects in the hierarchy (editor only) #241

Closed
opened 2026-09-27 00:32:12 +02:00 by meleki · 3 comments
Owner

Wunsch

In der Hierarchie (Scene- und Container-Tab) Objekte zu Gruppen zusammenfassen, die sich ein- und ausklappen lassen. Beispiel: 100 verteilte Crates in eine Gruppe „Crates“ packen.

Die Gruppe ist nur Editor-Optik. Parenting, Position, Behaviors und das Spiel bleiben unberührt. Das Spiel sieht Gruppen nie.

Entwurf

Modell

  • Der Holder (Szene oder Container-Template) bekommt groups: { id, name }[], ein Objekt bekommt optional groupId.
  • Fehlt beides, lädt ein altes Projekt unverändert. Ein Objekt mit einer groupId, die es nicht (mehr) gibt, steht einfach ohne Gruppe da.
  • Gruppen gibt es nur auf oberster Ebene. Mitglieder sind Objekte ohne Parent, ihre Kinder hängen weiter unter ihnen. Hängt man ein Mitglied an einen Parent, verlässt es die Gruppe.

Hierarchie

  • Eine Gruppe ist eine eigene Zeile mit Ordner-Symbol, Name und Anzahl („Crates · 100“), Mitglieder stehen eingerückt darunter.
  • Die Gruppenzeile steht dort, wo ihr erstes Mitglied in der Geschwister-Reihenfolge steht.
  • Anlegen: Mehrere Objekte auswählen → Rechtsklick → Group (alle müssen auf oberster Ebene liegen, sonst ausgegraut). Die neue Gruppe heißt „Group“ und ist sofort zum Umbenennen offen.
  • Gruppenmenü: Rename…, Ungroup (Mitglieder bleiben, nur die Gruppe geht), Select members, Expand/Collapse all.
  • Drag & Drop: Objekt auf die Gruppenzeile = in die Gruppe, Objekt aus der Gruppe heraus = raus. Die Gruppenzeile selbst lässt sich ziehen, alle Mitglieder wandern mit.
  • Wird ein ausgewähltes Objekt in einer zugeklappten Gruppe ausgewählt (etwa per Klick in der Scene-View), klappt die Gruppe auf, wie heute bei Parents.
  • Anlegen, Umbenennen, Auflösen, Ein- und Austreten sind je ein Undo-Schritt.

Rest

  • Objekte löschen: Eine Gruppe, die dadurch leer wird, verschwindet mit (im selben Undo-Schritt).
  • Copy & Paste (#240): Die Kopie landet in derselben Gruppe, wenn es die Gruppe im Ziel gibt und die Kopie auf oberster Ebene landet. Sonst ohne Gruppe.
  • Szene-View, Laufzeit, Export: keine Änderung.

Entscheidungen

Siehe Kommentar: nur oberste Ebene, Mitglieder rücken zusammen, keine Gruppen in Gruppen, Aufklappen nur für die Sitzung, Klick auf die Gruppe wählt alle Mitglieder.

## Wunsch In der Hierarchie (Scene- und Container-Tab) Objekte zu **Gruppen** zusammenfassen, die sich ein- und ausklappen lassen. Beispiel: 100 verteilte Crates in eine Gruppe „Crates“ packen. Die Gruppe ist **nur Editor-Optik**. Parenting, Position, Behaviors und das Spiel bleiben unberührt. Das Spiel sieht Gruppen nie. ## Entwurf **Modell** - Der Holder (Szene oder Container-Template) bekommt `groups: { id, name }[]`, ein Objekt bekommt optional `groupId`. - Fehlt beides, lädt ein altes Projekt unverändert. Ein Objekt mit einer `groupId`, die es nicht (mehr) gibt, steht einfach ohne Gruppe da. - Gruppen gibt es nur auf oberster Ebene. Mitglieder sind Objekte ohne Parent, ihre Kinder hängen weiter unter ihnen. Hängt man ein Mitglied an einen Parent, verlässt es die Gruppe. **Hierarchie** - Eine Gruppe ist eine eigene Zeile mit Ordner-Symbol, Name und Anzahl („Crates · 100“), Mitglieder stehen eingerückt darunter. - Die Gruppenzeile steht dort, wo ihr erstes Mitglied in der Geschwister-Reihenfolge steht. - **Anlegen:** Mehrere Objekte auswählen → Rechtsklick → **Group** (alle müssen auf oberster Ebene liegen, sonst ausgegraut). Die neue Gruppe heißt „Group“ und ist sofort zum Umbenennen offen. - **Gruppenmenü:** Rename…, Ungroup (Mitglieder bleiben, nur die Gruppe geht), Select members, Expand/Collapse all. - **Drag & Drop:** Objekt auf die Gruppenzeile = in die Gruppe, Objekt aus der Gruppe heraus = raus. Die Gruppenzeile selbst lässt sich ziehen, alle Mitglieder wandern mit. - Wird ein ausgewähltes Objekt in einer zugeklappten Gruppe ausgewählt (etwa per Klick in der Scene-View), klappt die Gruppe auf, wie heute bei Parents. - Anlegen, Umbenennen, Auflösen, Ein- und Austreten sind je ein Undo-Schritt. **Rest** - Objekte löschen: Eine Gruppe, die dadurch leer wird, verschwindet mit (im selben Undo-Schritt). - Copy & Paste (#240): Die Kopie landet in derselben Gruppe, wenn es die Gruppe im Ziel gibt und die Kopie auf oberster Ebene landet. Sonst ohne Gruppe. - Szene-View, Laufzeit, Export: keine Änderung. ## Entscheidungen Siehe Kommentar: nur oberste Ebene, Mitglieder rücken zusammen, keine Gruppen in Gruppen, Aufklappen nur für die Sitzung, Klick auf die Gruppe wählt alle Mitglieder.
Author
Owner

Entscheidungen (im Chat geklärt, 2026-09-27)

  1. Ebenen: Gruppen gibt es nur auf oberster Ebene (root). Nur Objekte ohne Parent können in eine Gruppe. Die Kinder eines Mitglieds bleiben unter ihrem Parent und stehen damit in der Gruppe eine Stufe tiefer eingerückt. Wer ein Mitglied an einen Parent hängt, nimmt es aus der Gruppe. Group ist ausgegraut, sobald ein ausgewähltes Objekt einen Parent hat. Im Container-Template gilt dasselbe für seine oberste Ebene.
  2. Reihenfolge: z entscheidet wie bisher. Bei gleichem z entscheidet die Reihenfolge in der Hierarchie. Beim Gruppieren rücken die Mitglieder zusammen, die Hierarchie zeigt also immer die Reihenfolge, in der auch gezeichnet wird.
  3. Gruppen in Gruppen: nein.
  4. Auf-/Zugeklappt: nur für die Sitzung, nicht im Projekt.
  5. Klick auf die Gruppenzeile: wählt alle Mitglieder aus.

Die Beschreibung ist entsprechend angepasst (Gruppe ohne parentId).

## Entscheidungen (im Chat geklärt, 2026-09-27) 1. **Ebenen:** Gruppen gibt es **nur auf oberster Ebene** (root). Nur Objekte ohne Parent können in eine Gruppe. Die Kinder eines Mitglieds bleiben unter ihrem Parent und stehen damit in der Gruppe eine Stufe tiefer eingerückt. Wer ein Mitglied an einen Parent hängt, nimmt es aus der Gruppe. **Group** ist ausgegraut, sobald ein ausgewähltes Objekt einen Parent hat. Im Container-Template gilt dasselbe für seine oberste Ebene. 2. **Reihenfolge:** `z` entscheidet wie bisher. Bei gleichem `z` entscheidet die Reihenfolge in der Hierarchie. Beim Gruppieren rücken die Mitglieder zusammen, die Hierarchie zeigt also immer die Reihenfolge, in der auch gezeichnet wird. 3. **Gruppen in Gruppen:** nein. 4. **Auf-/Zugeklappt:** nur für die Sitzung, nicht im Projekt. 5. **Klick auf die Gruppenzeile:** wählt alle Mitglieder aus. Die Beschreibung ist entsprechend angepasst (Gruppe ohne `parentId`).
Author
Owner

Done in 53fa634 (groups, click fix) and 893b81f (shift-click range). Wiki: 2b69437, 1106c93.

Behavior

  • Group… in the object menu groups the selected top-level objects. The name is asked first, so creating is one undo step and Cancel creates nothing. Disabled when a selected object has a parent.
  • The group row shows a folder icon, the name and the member count. Members are indented below it, their children one step deeper.
  • Clicking the group row selects all members and keeps the group collapsed. Selecting a single member elsewhere expands the group.
  • Dragging: 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.
  • Group menu: Select members, Rename…, Ungroup. Object menu: Remove from group.
  • Parenting a member removes it from the group. Paste of a top-level copy in the same scene lands in the original's group. A container made from group members takes their place in the group. Container templates can group their top level too.
  • Draw order at equal z follows treeOrder, where members sit together at the first member's place. Hierarchy and drawing cannot drift apart. The stored object list is not reordered.
  • Expanded state is per session only.

Follow-ups from review

  • Clicking an already selected object in a multi-selection now keeps only that object (narrowed on release, so a drag keeps the selection).
  • Shift-click selects all visible rows between the anchor and the clicked row. The anchor is the last row clicked without shift. Ctrl+shift adds the range. A collapsed group in the range brings all members; children under a collapsed parent stay out.

Tests

  • ./check.sh: 178 files, 2557 tests, CHECK EXIT 0
  • e2e 1, 51, 52 green (new module 52, checks 52a-52h with real clicks, keys and a drag)
  • 24 new unit tests (object-groups, hierarchy-drop, hierarchy-range)
  • 10 counter-checks, all failing as expected

Not checked in the browser

Groups in the container tab, Remove from group, ctrl-click on the group row, ctrl+shift-click, the shift anchor taken from the scene view, and dragging out of a multi-selection. Only the code path covers these.

Done in `53fa634` (groups, click fix) and `893b81f` (shift-click range). Wiki: `2b69437`, `1106c93`. ## Behavior - **Group…** in the object menu groups the selected top-level objects. The name is asked first, so creating is one undo step and Cancel creates nothing. Disabled when a selected object has a parent. - The group row shows a folder icon, the name and the member count. Members are indented below it, their children one step deeper. - Clicking the group row selects all members and keeps the group collapsed. Selecting a single member elsewhere expands the group. - Dragging: 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. - Group menu: Select members, Rename…, Ungroup. Object menu: Remove from group. - Parenting a member removes it from the group. Paste of a top-level copy in the same scene lands in the original's group. A container made from group members takes their place in the group. Container templates can group their top level too. - Draw order at equal `z` follows `treeOrder`, where members sit together at the first member's place. Hierarchy and drawing cannot drift apart. The stored object list is not reordered. - Expanded state is per session only. ## Follow-ups from review - Clicking an already selected object in a multi-selection now keeps only that object (narrowed on release, so a drag keeps the selection). - Shift-click selects all visible rows between the anchor and the clicked row. The anchor is the last row clicked without shift. Ctrl+shift adds the range. A collapsed group in the range brings all members; children under a collapsed parent stay out. ## Tests - `./check.sh`: 178 files, 2557 tests, CHECK EXIT 0 - e2e 1, 51, 52 green (new module 52, checks 52a-52h with real clicks, keys and a drag) - 24 new unit tests (`object-groups`, `hierarchy-drop`, `hierarchy-range`) - 10 counter-checks, all failing as expected ## Not checked in the browser Groups in the container tab, Remove from group, ctrl-click on the group row, ctrl+shift-click, the shift anchor taken from the scene view, and dragging out of a multi-selection. Only the code path covers these.
Author
Owner

Nachtrag in 2eeabf7 (Wiki 0063a7a):

  • Ziehen einer Mehrfachauswahl: Wer eine ausgewählte Zeile zieht, nimmt die ganze Auswahl mit, beim Umsortieren, in eine Gruppe hinein, aus einer Gruppe heraus und auf ein Objekt als Parent. Die Objekte landen nebeneinander in Hierarchie-Reihenfolge. Alles ist ein Undo-Schritt. Ein ausgewähltes Kind wandert mit seinem Parent.
  • Dialog: "Group n objects" hat ein Dropdown New group / vorhandene Gruppen. Mit einer vorhandenen Gruppe wird der Name grau und der Knopf heißt Add.
  • Ordner-Symbol steht jetzt rechts in der Icon-Spalte wie bei Objekten, die Anzahl links daneben.

Tests: ./check.sh 178 Dateien, 2564 Tests, grün. e2e 1 + 52: 27 Checks, grün. 7 neue Unit-Tests, 4 neue e2e-Checks (52i, 52j), 4 Gegenproben greifen.

Nicht im Browser geprüft: Mehrfach-Ziehen im Container-Tab und auf ein Objekt als Parent, das decken nur Unit-Tests ab.

Nachtrag in `2eeabf7` (Wiki `0063a7a`): - **Ziehen einer Mehrfachauswahl:** Wer eine ausgewählte Zeile zieht, nimmt die ganze Auswahl mit, beim Umsortieren, in eine Gruppe hinein, aus einer Gruppe heraus und auf ein Objekt als Parent. Die Objekte landen nebeneinander in Hierarchie-Reihenfolge. Alles ist ein Undo-Schritt. Ein ausgewähltes Kind wandert mit seinem Parent. - **Dialog:** "Group n objects" hat ein Dropdown *New group* / vorhandene Gruppen. Mit einer vorhandenen Gruppe wird der Name grau und der Knopf heißt **Add**. - **Ordner-Symbol** steht jetzt rechts in der Icon-Spalte wie bei Objekten, die Anzahl links daneben. Tests: `./check.sh` 178 Dateien, 2564 Tests, grün. e2e 1 + 52: 27 Checks, grün. 7 neue Unit-Tests, 4 neue e2e-Checks (52i, 52j), 4 Gegenproben greifen. Nicht im Browser geprüft: Mehrfach-Ziehen im Container-Tab und auf ein Objekt als Parent, das decken nur Unit-Tests ab.
admin added this to the Development project 2026-09-27 11:28:31 +02:00
admin moved this to Done in Development on 2026-09-27 11:29:22 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#241