From 79c3b3ef53475f97baace47f7e6d746cc3e16255 Mon Sep 17 00:00:00 2001 From: meleki Date: Sun, 27 Sep 2026 00:25:59 +0200 Subject: [PATCH] Describe copy and paste of objects and nodes (#240) - Scene editing: new section on Ctrl+C/Ctrl+V, where a paste lands and under which parent. - Behaviors: a point on copying nodes and what the palette filter leaves out. - Keyboard: Ctrl+C/Ctrl+V per tab and the picture import. - Architecture: clipboard snapshot and paste commands. - Development: e2e check total 1432. Co-Authored-By: Claude Opus 5.5 --- Architecture.md | 5 ++++- Behaviors.md | 8 ++++++++ Development.md | 2 +- Keyboard.md | 5 +++-- Scene-editing.md | 23 ++++++++++++++++++++++- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Architecture.md b/Architecture.md index a1f94d4..7693cbf 100644 --- a/Architecture.md +++ b/Architecture.md @@ -141,7 +141,10 @@ src/editor/ App → Editor (layout + ticker), PlaySession (the run), snapshot may be made: only with everything saved, #231), ProjectSettingsDialog + settingsChanges (name, the start-scene switch and the collision layers in one dialog; the pure rule of what Apply has to carry out), - EditorRun (run in editor), state, actions, shortcuts, debugHook (installs `window.__gm`; + EditorRun (run in editor), state, actions, shortcuts, clipboard (#240: copy and paste of + objects and graph pieces — where a paste lands, into which parent, what a graph may take; + the snapshot is `core/model/clipboard`, the paste `core/commands/pasteCommands`), + debugHook (installs `window.__gm`; the hooks are grouped by area in debug/: ui, scene, graph, documents, pixel art, vector art, render — `tools/` sees one flat object as before), textProbe (finding widgets by their text — the ground floor of the test hook, shared with the sign-in screen), diff --git a/Behaviors.md b/Behaviors.md index 7350ee4..4521630 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -314,6 +314,14 @@ playing use the same two words. (types are checked; a data input holds one link and is replaced), drag nodes, right-click a node or port to delete/disconnect, `Delete` removes the selection, wheel zooms. Everything is undoable. +- **Copy and paste** (#240) works in every graph (behavior, state machine, shader, particles): + `Ctrl+C` or right-click → *Copy* takes the selected nodes, the links between them and the + groups and comments selected with them. `Ctrl+V` pastes under the pointer, or one grid step + beside the original when the pointer is elsewhere; the palette on empty canvas offers *Paste* + at the spot it was opened. A link to a node that was not copied stays behind. A node is pasted + only where the palette would offer it: a `State` never lands in a behavior, a behavior node + never in a shader, a second `Start`/`End` and a behavior calling itself are left out. What is + left out is named in a notice, the rest is pasted as one undo step and selected. - **Mouse and selection work as in the scene view.** The **middle button pans** from anywhere, a node under the pointer included (shift-drag on empty canvas does too); the left button never pans. Dragging on empty canvas pulls a **rubber band** instead, which selects every node it diff --git a/Development.md b/Development.md index 35c5686..f7e1ec9 100644 --- a/Development.md +++ b/Development.md @@ -15,7 +15,7 @@ npm run build # writes dist/ and regenerates index.html php tools/make-user.php [admin|user] # an account; every tool signs in (see Accounts) php tests/php/accounts.test.php # the API's account rules, no server needed (CI's gate job) php tests/php/snapshots.test.php # the snapshot store (#231), the same way -node tools/seed-e2e.mjs && node tools/e2e.mjs # 1423 editor checks, screenshots in /tmp/gm-e2e-*.png +node tools/seed-e2e.mjs && node tools/e2e.mjs # 1432 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 ./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh status # live progress, or the last run's result diff --git a/Keyboard.md b/Keyboard.md index 7a4d910..bbbfaa3 100644 --- a/Keyboard.md +++ b/Keyboard.md @@ -1,8 +1,9 @@ `Ctrl+Z` / `Ctrl+Shift+Z` / `Ctrl+Y` undo/redo (`Cmd` works wherever `Ctrl` does) · `Delete` or `Backspace` remove the selection (objects, nodes, frames, keys or a row of the Animation tab, a graph group or comment — the box only, its nodes stay, and a band that caught boxes and nodes together removes both in one step; an asset asks first) · `Ctrl+G` create container from the selection · `Ctrl+Enter` play, and pause/resume while playing · `Esc` stop · -`Ctrl+V` import an image from -the clipboard as a texture (ignored while a text field has focus) · Animation tab: `Ctrl+C` copy +`Ctrl+C` copy the selected objects or graph nodes, `Ctrl+V` paste them +under the pointer ([Scene editing](Scene-editing), [Behaviors](Behaviors)) · `Ctrl+V` import an image from +the clipboard as a texture when nothing copied fits the tab (ignored while a text field has focus) · Animation tab: `Ctrl+C` copy the picked keys, `Ctrl+V` paste them at the playhead (while keys are copied this takes `Ctrl+V` there, so an image is pasted from another tab), `Ctrl`+drag duplicate keys · `Tab` / `Shift+Tab` cycle fields · lists: `↑`/`↓` move, `←`/`→` fold, `Enter` activates · number diff --git a/Scene-editing.md b/Scene-editing.md index 0dbf752..64e330b 100644 --- a/Scene-editing.md +++ b/Scene-editing.md @@ -155,7 +155,28 @@ so they cannot drift apart. Only *Expand all* / *Collapse all* stay in the panel something. Which object the menu is for follows the rule of a press: a selected object under the pointer, hidden behind others or not, keeps the selection, and the menu acts on all of it; otherwise the topmost object there is selected first. Empty space, an empty tilemap cell -included, opens no menu. The Container tab does the same for its template. +included, opens a menu with *Paste* alone. The Container tab does the same for its template. + +**Copy and paste (#240).** `Ctrl+C` copies the selected objects, each with everything below it +(children, colliders, rigidbodies), and `Ctrl+V` pastes them into the scene or container the +visible tab shows. The object menu offers the same as *Copy* and *Paste*. The copy keeps names, +overrides and the look (rotation, scale, mirror); the editor offset stays behind. A placed +container is copied as a placed container and keeps showing its template, content picked out +of one is pasted as ordinary objects. The clipboard is the editor's own and holds ids of this +project, so it lives until another project is opened. + +- **Where it lands:** under the pointer when the pointer is over the view (the copied group + keeps its layout, centred there), else one grid step (100) down and right of the original, and + another step for every earlier paste that is still there. +- **Into which parent:** into the one selected object (from the menu: the one clicked). When that + object is an original or an earlier paste, the copy goes beside it instead, under its parent, so + pasting again and again never stacks copies inside each other. Without such an object the copy + keeps the parent it had, if this scene or container has it, else it goes to the top level. It + keeps its look under the new parent, as a re-parent does. +- **Refused:** a container pasted into its own template (or into anything it ends up inside), + with the notice a drop gets. One paste is one undo step and selects what it pasted. +- While objects are copied, `Ctrl+V` in the Scene and Container tab pastes them; an image from + the system clipboard is then pasted from another tab. With nodes copied it goes through there. **Editor offset (scene view only).** Every scene object additionally carries an `editorOffset` — an x/y shift of where it is *drawn, selected and dragged* in the Scene tab,