Groups and comments say what a part of a graph is for (#38)

admin committed 2026-09-16 11:24:38 +02:00
1 parent eacf87e582
commit b0d0e016d3
3 files changed
+31 -4

No files matched your search

+27
@@ -262,6 +262,33 @@ shown on the node and editable in the inspector.
its ports are out of sight: its ports are out of sight:
*Set 2 variables* when more than one is written, else *Get 2 variables* when more than one is *Set 2 variables* when more than one is written, else *Get 2 variables* when more than one is
only read, else *Set speed* / *Get speed*, and *No variables* when it has none. only read, else *Set speed* / *Get speed*, and *No variables* when it has none.
- **Groups and comments** put words on a graph that has grown. They are two separate things,
because they mean two different things (#38):
- A **group** is a titled box drawn behind the nodes. It **carries what it encloses**: dragging
its title bar moves every node whose *centre* lies inside, and any group or comment centred in
it as well — with, in turn, whatever those carry. The centre, not an overlap, because a group
and the node beside it always touch a little; membership is worked out fresh each time the box
is grabbed, so a node dragged out of it is simply out, with nothing to "ungroup".
- A **comment** is a card of free text. It frames nothing and moves alone.
- Both are created from the **right-click palette** (*Add group*, *Add comment*, listed above the
nodes); a selection of nodes can be boxed directly with right-click → *Group these 3 nodes*.
The search finds them under "group" or "comment", deliberately **not** under "add" — that is
the word you type to find the `Add` node.
- **A group is grabbed by its title bar only.** Its body stays transparent to the pointer, or a
rubber band could never be drawn across the nodes it holds. The corner at the bottom right
resizes it, and resizing moves nothing: what the box ends up around is what it carries next
time. With **Snap** on, the corner being dragged lands on the grid — the far one, since the near
corner is exactly what a resize must leave alone. A comment, framing nothing, is grabbed anywhere
on it.
- **Deleting one takes the box and nothing else.** The nodes stay exactly where they were — a box
that silently deleted ten nodes with it would be the most expensive surprise in the editor.
- Title, text and colour are edited in the **inspector**. The colour is a free picker, and the
text on it is drawn **black or white, whichever reads better** (relative luminance, `ui/color.ts`)
— that is what makes a free picker safe on a dark canvas. *Use the default color* takes a box
back to the theme's.
- All of it is drawing only: `groups` and `notes` on the graph, saved with the project, read by
no interpreter. A graph that has neither stores neither array, so an old document means exactly
what it says. Every graph tab has them — behaviors, state machines, shaders, particles.
- **Header bar** (the same one the Texture and Container tabs have): the behavior picker, - **Header bar** (the same one the Texture and Container tabs have): the behavior picker,
**Fit** (which zooms out far enough to hold every node, measuring each by its own drawn **Fit** (which zooms out far enough to hold every node, measuring each by its own drawn
height — `editor/framing.ts`), and the size of the graph as "N nodes · M links". height — `editor/framing.ts`), and the size of the graph as "N nodes · M links".
+3 -3
@@ -12,7 +12,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
# code is lost (tail's is reported), so a red run reads as green # code is lost (tail's is reported), so a red run reads as green
npm run build # writes dist/ and regenerates index.html npm run build # writes dist/ and regenerates index.html
./build.sh # the same under `set -o pipefail`, for callers that pipe the output ./build.sh # the same under `set -o pipefail`, for callers that pipe the output
node tools/seed-e2e.mjs && node tools/e2e.mjs # 932 editor checks, screenshots in /tmp/gm-e2e-*.png node tools/seed-e2e.mjs && node tools/e2e.mjs # 945 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result ./e2e.sh status # live progress, or the last run's result
@@ -64,7 +64,7 @@ The e2e run is a list of steps in `tools/e2e/` (hierarchy, inspector, play, asse
graph, parenting, colliders, containers, text/enabled, menus, textures, frames, overflow, aspect, graph, parenting, colliders, containers, text/enabled, menus, textures, frames, overflow, aspect,
container tab, run-in-editor, pause, nested behaviors, key repeat, list tab, struct variable, container tab, run-in-editor, pause, nested behaviors, key repeat, list tab, struct variable,
variable nodes, property nodes, animations, state machines, console, shaders, transforms, fonts, variable nodes, property nodes, animations, state machines, console, shaders, transforms, fonts,
particles, shared scope, render on change, sounds, load scene) that build on each other's particles, shared scope, render on change, sounds, load scene, graph groups) that build on each other's
scene state and share the CDP driver in `tools/lib/harness.mjs` — `press`, `undo`, `play`, scene state and share the CDP driver in `tools/lib/harness.mjs` — `press`, `undo`, `play`,
`object(id)`, `world()`, `mutate(js)` and friends, so a check reads like the interaction it `object(id)`, `world()`, `mutate(js)` and friends, so a check reads like the interaction it
exercises. exercises.
@@ -232,4 +232,4 @@ widths to find click points. The **render device is not in this repo** — `/dev
and a 1 GB `/dev/shm` come from `container.options` in the runner's own `config.yaml`, which and a 1 GB `/dev/shm` come from `container.options` in the runner's own `config.yaml`, which
applies to every job on that runner. Without them chromium falls back to llvmpipe, which gets applies to every job on that runner. Without them chromium falls back to llvmpipe, which gets
WebGL 1.0 only. Measured in the job container: `ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`, WebGL 1.0 only. Measured in the job container: `ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`,
WebGL 2.0, and the same 932 checks as here. WebGL 2.0, and the same 945 checks as here.
+1 -1
@@ -1,5 +1,5 @@
`Ctrl+Z` / `Ctrl+Shift+Z` / `Ctrl+Y` undo/redo (`Cmd` works wherever `Ctrl` does) · `Delete` or `Ctrl+Z` / `Ctrl+Shift+Z` / `Ctrl+Y` undo/redo (`Cmd` works wherever `Ctrl` does) · `Delete` or
`Backspace` remove the selection (objects, nodes, frames, a tile of the Animation tab; an asset asks first) · `Ctrl+G` create `Backspace` remove the selection (objects, nodes, frames, a tile of the Animation tab, a graph group or comment — the box only, its nodes stay; an asset asks first) · `Ctrl+G` create
container from the selection · `Ctrl+Enter` play, and pause/resume while playing · `Esc` stop · container from the selection · `Ctrl+Enter` play, and pause/resume while playing · `Esc` stop ·
`Ctrl+V` import an image from `Ctrl+V` import an image from
the clipboard as a texture (ignored while a text field has focus) · `Tab` / `Shift+Tab` cycle fields · lists: `↑`/`↓` move, the clipboard as a texture (ignored while a text field has focus) · `Tab` / `Shift+Tab` cycle fields · lists: `↑`/`↓` move,