129 lines
5.1 KiB
Markdown
129 lines
5.1 KiB
Markdown
# selection-manipulation Specification
|
|
|
|
## Purpose
|
|
Node selection and direct manipulation. Click/shift/marquee select, move by drag, resize handles, rotation with snapping, duplicate, nudge, delete, and select-all.
|
|
## Requirements
|
|
### Requirement: Click to select
|
|
Clicking on a node SHALL select it (deselecting all others). Clicking empty canvas SHALL deselect all.
|
|
|
|
#### Scenario: Select a single node
|
|
- **WHEN** user clicks on a rectangle
|
|
- **THEN** the rectangle is selected and all other nodes are deselected
|
|
|
|
### Requirement: Multi-select with shift
|
|
Shift+clicking a node SHALL toggle it in the current selection.
|
|
|
|
#### Scenario: Add to selection
|
|
- **WHEN** user shift+clicks a second node while one is already selected
|
|
- **THEN** both nodes are in the selection
|
|
|
|
### Requirement: Marquee selection
|
|
Dragging on empty canvas SHALL create a selection rectangle. All nodes intersecting the rectangle SHALL be selected on release.
|
|
|
|
#### Scenario: Marquee drag
|
|
- **WHEN** user drags from empty canvas across three nodes
|
|
- **THEN** all three nodes are selected when the drag ends
|
|
|
|
### Requirement: Move by dragging
|
|
Dragging a selected node SHALL move it (and all other selected nodes) by the drag delta.
|
|
|
|
#### Scenario: Drag to move
|
|
- **WHEN** user drags a selected node by 50px right
|
|
- **THEN** the node's X position increases by 50
|
|
|
|
### Requirement: Resize handles
|
|
Selected nodes SHALL display 8 resize handles (4 corners + 4 edge midpoints). Dragging a handle SHALL resize the node. Shift constrains proportions.
|
|
|
|
#### Scenario: Resize from corner
|
|
- **WHEN** user drags the bottom-right corner handle outward
|
|
- **THEN** the node's width and height increase
|
|
|
|
### Requirement: Rotation
|
|
Hovering just outside a corner handle SHALL show a rotation cursor. Dragging SHALL rotate the node. Shift SHALL snap to 15° increments.
|
|
|
|
#### Scenario: Rotate with snap
|
|
- **WHEN** user drags the rotation handle while holding shift
|
|
- **THEN** the rotation snaps to the nearest 15° increment
|
|
|
|
### Requirement: Duplicate
|
|
Alt+drag SHALL duplicate the selected node and move the duplicate. ⌘D SHALL duplicate in place.
|
|
|
|
#### Scenario: Alt+drag duplicate
|
|
- **WHEN** user alt+drags a selected rectangle
|
|
- **THEN** a copy of the rectangle is created at the drag position
|
|
|
|
### Requirement: Constrained drawing
|
|
Holding shift while drawing a shape SHALL constrain to square/circle.
|
|
|
|
#### Scenario: Shift+drag rectangle
|
|
- **WHEN** user draws a rectangle while holding shift
|
|
- **THEN** the rectangle is constrained to a square (equal width and height)
|
|
|
|
### Requirement: Nudge with arrows
|
|
Arrow keys SHALL move selected nodes by 1px. Shift+arrow SHALL move by 10px.
|
|
|
|
#### Scenario: Arrow nudge
|
|
- **WHEN** user presses the right arrow key with a node selected
|
|
- **THEN** the node moves 1px to the right
|
|
|
|
### Requirement: Delete selection
|
|
Backspace/Delete SHALL remove all selected nodes.
|
|
|
|
#### Scenario: Delete node
|
|
- **WHEN** user presses backspace with a node selected
|
|
- **THEN** the node is removed from the scene graph
|
|
|
|
### Requirement: Select all
|
|
⌘A SHALL select all nodes on the current canvas.
|
|
|
|
#### Scenario: Select all
|
|
- **WHEN** user presses ⌘A
|
|
- **THEN** all nodes on the canvas are selected
|
|
|
|
### Requirement: Section creation with auto-adopt
|
|
Creating a section on the canvas SHALL automatically reparent overlapping sibling nodes into the section. Only nodes fully or partially within the section bounds are adopted.
|
|
|
|
#### Scenario: Draw section over existing nodes
|
|
- **WHEN** user draws a section that overlaps two rectangles
|
|
- **THEN** the two rectangles become children of the new section
|
|
|
|
|
|
### Requirement: Z-order manipulation
|
|
The editor SHALL support bringing selected nodes to front (]) and sending to back ([). Bring to front moves node to end of parent's childIds; send to back moves to start.
|
|
|
|
#### Scenario: Bring to front
|
|
- **WHEN** user selects a node and presses ]
|
|
- **THEN** the node moves to the top of its sibling z-order
|
|
|
|
#### Scenario: Send to back
|
|
- **WHEN** user selects a node and presses [
|
|
- **THEN** the node moves to the bottom of its sibling z-order
|
|
|
|
### Requirement: Toggle visibility
|
|
The editor SHALL support toggling node visibility (⇧⌘H). Hidden nodes are not rendered but remain in the scene graph and layers panel.
|
|
|
|
#### Scenario: Hide node
|
|
- **WHEN** user selects a visible node and presses ⇧⌘H
|
|
- **THEN** the node's `visible` property becomes false
|
|
|
|
### Requirement: Toggle lock
|
|
The editor SHALL support toggling node lock state (⇧⌘L). Locked nodes cannot be selected or moved via canvas interaction.
|
|
|
|
#### Scenario: Lock node
|
|
- **WHEN** user selects a node and presses ⇧⌘L
|
|
- **THEN** the node's `locked` property becomes true
|
|
|
|
### Requirement: Move to page
|
|
The editor SHALL support moving selected nodes to a different page, reparenting them under the target page's CANVAS node.
|
|
|
|
#### Scenario: Move selection to another page
|
|
- **WHEN** user moves a node to Page 2 via context menu
|
|
- **THEN** the node is reparented under Page 2's CANVAS node and removed from the current page
|
|
|
|
### Requirement: Rename node
|
|
The editor SHALL support renaming nodes programmatically via `renameNode(id, name)`.
|
|
|
|
#### Scenario: Rename a layer
|
|
- **WHEN** `renameNode` is called with a new name
|
|
- **THEN** the node's name property is updated
|