Object tree: groups and the drawing order
Deploy web Studio / deploy (push) Successful in 1m5s

Groups: objects of type "group" draw nothing; members carry the group's id
in a new `group` field (groups nest). A hidden group hides everything in it
(Doc::hidden_in_groups, skipped by the driver), a locked one locks it in
the Studio. Removing a group moves its members up into its parent group.
isokit check warns about members of missing groups. New `order` op: the
whole object order at once (each id once), one undo step.

Studio object list as a tree in the document order, front first: each
group sits just after its members, so it draws as one block, and ground
pieces higher in the list lie on top. Groups fold open and shut; every row
has an eye and a lock (shown on hover or when set); a click on a group
selects all of it, so a drag on the map moves it all. Group / Ungroup
(Ctrl+G, Ctrl+Shift+G), Order up/down (Ctrl+] Ctrl+[, with Shift to the
front / back), drag rows above, below or into a group. Group panel: name,
zoom, ungroup, to front / back, lock, hide, delete with contents.

MCP: group field in the object schema, order op, guidance.

Tests: Rust 81 (ops: groups, order, removal; driver: nested hidden
groups), Studio 131, web 100.
This commit is contained in:
grabowski committed 2026-10-25 18:06:04 +07:00
1 parent 5ec164a633
commit 540b37020c
15 files changed
+573 -30

No files matched your search

+15
View File
@@ -54,6 +54,21 @@ input[type=checkbox] { accent-color: var(--accent); }
.st-objects li span { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-objects li small { color: var(--mute); }
.st-objects li.st-hidden span { opacity: .5; text-decoration: line-through; }
/* the object tree: groups indent what is in them; a hide and a lock toggle per row, shown on hover or when set */
.st-objects li { padding-left: calc(2px + var(--d, 0) * 14px); }
.st-objects li .st-tw { width: 12px; flex: none; font-weight: normal; color: var(--mute); text-align: center; cursor: pointer; }
.st-objects li.st-group > span { font-weight: 600; }
.st-objects li.st-inh span { text-decoration: none; }
.st-objects li button { flex: none; border: 0; background: none; padding: 0 2px; min-width: 18px; color: var(--mute); cursor: pointer; font-size: 12px; line-height: 1; opacity: 0; }
.st-objects li:hover button, .st-objects li button.st-on, .st-objects li button:focus-visible { opacity: 1; }
.st-objects li button:hover { color: var(--fg); }
.st-objects li.st-drop-above { box-shadow: inset 0 2px 0 var(--accent); }
.st-objects li.st-drop-below { box-shadow: inset 0 -2px 0 var(--accent); }
.st-objects li.st-drop-in { outline: 2px solid var(--accent); outline-offset: -2px; }
body.st-listdrag, body.st-listdrag * { cursor: grabbing !important; }
.st-otools { display: flex; align-items: center; gap: 4px; margin: 4px 0 2px; font-size: 12px; }
.st-otools button { padding: 2px 7px; font-size: 12px; }
.st-otools span { margin-left: auto; color: var(--mute); cursor: help; }
.st-centre { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.st-centre > #view { flex: 1 1 auto; min-height: 0; }