- Added specifications for Phase 10a, introducing permanent size changes to `.prop` documents and reversible uniform instance scaling in Sandbox EDIT mode. - Updated `PropCanvas`, `PropAnchorData`, `PropEditor`, `StageGizmos`, `SandboxStage`, and `StageSelection` classes to support new scaling features. - Implemented document transactions for scaling, including normalization to a 96 px maximum dimension. - Introduced a new **Transform Whole Prop** tool in the Prop Editor for moving, rotating, and resizing props. - Created unit tests for the new scaling functionality, validating shape scaling, anchor transformations, and whole-prop interactions. - Ensured compatibility with existing prop formats and maintained the integrity of the document structure during scaling operations.
640 lines
29 KiB
Markdown
640 lines
29 KiB
Markdown
# Prop Editor User Guide
|
||
|
||
The Prop Editor is a standalone tool for making vector props and saving them as
|
||
`.prop` files. It is separate from the main Stickman Editor and Sandbox Stage.
|
||
This guide describes the current controls and provides a complete manual test
|
||
checklist.
|
||
|
||
## Start the editor
|
||
|
||
1. Open `res://scenes/prop_editor.tscn` in the Godot editor.
|
||
2. Press **F6** to run the current scene.
|
||
|
||
The Prop Editor is not the project's configured main scene. If F6 runs a
|
||
different scene, open `prop_editor.tscn` first.
|
||
|
||
## Layout
|
||
|
||
The window is divided into these areas:
|
||
|
||
| Area | Purpose |
|
||
| --- | --- |
|
||
| `📁 File` and `👁️ View` | File operations and canvas view reset |
|
||
| `Grid` and `Snap` | Shared grid spacing and snapping settings |
|
||
| `Prop Name` | The name stored in the `.prop` file |
|
||
| Mode bar | Switch between `🖐️ Arrange`, `✏️ Reshape`, and `📌 Attach` |
|
||
| Arrange controls | Whole-prop transform, normalization, centering, and the stickman guide |
|
||
| Authoring canvas | Draw, select, transform, and reshape the prop |
|
||
| Inspector | Material, shape, primitive, and anchor controls |
|
||
| Holding Preview | A private stickman-and-prop preview shown in Attach mode |
|
||
| Status bar | Current prop/preset/dirty state and cursor coordinates |
|
||
|
||
There are two adjustable splitters:
|
||
|
||
- Drag the main splitter between the canvas and Inspector to make the Inspector
|
||
wider or narrower.
|
||
- In Attach mode, drag the splitter between the authoring canvas and Holding
|
||
Preview in either direction. The preview keeps a minimum width so its
|
||
controls remain usable.
|
||
|
||
The Inspector starts at its minimum usable width so the canvas has room to
|
||
work. Drag the canvas/Inspector splitter to widen it when labels or controls
|
||
need more space. Its background is the theme color `#262C39`, intentionally
|
||
darker than the canvas; the Inspector also scrolls vertically on smaller
|
||
windows.
|
||
|
||
The Inspector scrolls vertically. On a small window, widen the Inspector or
|
||
scroll it rather than expecting every section to fit at once.
|
||
|
||
## File and View menus
|
||
|
||
### `📁 File`
|
||
|
||
| Command | What it does |
|
||
| --- | --- |
|
||
| `🆕 New` | Clears the current prop and starts a new document. If the current document is dirty, asks whether to save first. |
|
||
| `💾 Save` | Saves to the current path. If the prop has never been saved, opens Save As. |
|
||
| `📄 Save As...` | Opens the save dialog and changes the current path to the new file. |
|
||
| `📂 Load...` | Opens a `.prop` file. A successful load replaces the current document. |
|
||
| `🕑 Recent` | Shows up to five most-recently saved or loaded prop paths. Missing files are removed from this list. |
|
||
|
||
Save dialogs use the `.prop` filter. Save As normalizes a filename so it ends
|
||
in `.prop` even if that extension was omitted. Keeping authored props under
|
||
`res://props/` is recommended.
|
||
|
||
### `👁️ View`
|
||
|
||
| Command | What it does |
|
||
| --- | --- |
|
||
| `🔍 Reset View` | Resets the authoring canvas zoom and pan to 1x, with the local origin centered in view. It does not reset anchor values or the Holding Preview camera. |
|
||
|
||
The Holding Preview has its own `Reset View` button; see [Holding Preview](#holding-preview).
|
||
|
||
### Top-right canvas controls
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Grid` | Sets the visible grid spacing and the snap increment, from 1 to 512. |
|
||
| `Snap` | Enables or disables snapping for shape transforms and anchor movement. |
|
||
|
||
## Prop name and modes
|
||
|
||
### Prop Name
|
||
|
||
Type a name in the `Prop Name` field. The name is saved in the file and marks
|
||
the document dirty as soon as it changes. An empty name is displayed as
|
||
`Unnamed Prop` in the window title/status, and as `Untitled` in the generated
|
||
window title when no name is present.
|
||
|
||
### `🖐️ Arrange`
|
||
|
||
Arrange is the mode for selecting, moving, rotating, scaling, mirroring, and
|
||
ordering complete shapes. The Add Shape inspector and the shape Erase button
|
||
are available in this mode.
|
||
|
||
#### Arrange controls
|
||
|
||
The Arrange mode top bar keeps the whole-prop actions in this order:
|
||
|
||
1. `✥ Transform Whole Prop`
|
||
2. `📏 Normalize Size`
|
||
3. `🎯 Center Prop`
|
||
4. `Show Stickman Guide`
|
||
|
||
The scale textbox and Apply Scale button are not part of the editor. Use
|
||
Normalize Size for the standard document size, or use Transform Whole Prop for
|
||
direct canvas manipulation. Normalize Size fits the shape-point bounds to a
|
||
96 px maximum dimension while preserving the fixed origin and proportional
|
||
anchor offsets. Center Prop separately moves the shape bounds and editable
|
||
anchors around the canonical origin. It is a deliberate one-time command: the
|
||
editor does not recenter automatically after drawing, reshaping, or moving a
|
||
shape, and empty or already centered props are unchanged.
|
||
|
||
With Transform Whole Prop enabled, drag visible shape geometry to move the
|
||
whole prop, drag the dot below the union bounds to rotate it around the
|
||
canonical origin, or drag a corner cross to resize it uniformly. Snap rounds
|
||
the move delta to the current grid. Hold **Ctrl** while rotating to snap to
|
||
15-degree increments. Grip and other editable anchor markers follow each
|
||
operation. The tool previews from the starting document and commits once when
|
||
the gesture is released; **Esc** cancels the active preview. The canonical
|
||
origin itself does not move.
|
||
|
||
Transform Whole Prop and Normalize Size are hidden in Reshape and Attach.
|
||
Center Prop and Show Stickman Guide remain available in those modes. Turning
|
||
Transform Whole Prop off restores the selected shape and normal per-shape
|
||
Arrange gizmos.
|
||
|
||
When a shape is selected, the canvas draws:
|
||
|
||
- a two-tone selection outline and bounding box;
|
||
- a small rotation dot below the bounding-box center;
|
||
- four corner scale crosses.
|
||
|
||
Drag the shape body to translate it. Drag the rotation dot to rotate it. Hold
|
||
**Ctrl** while rotating to snap to 15-degree increments. Drag a corner cross
|
||
to scale. Hold **Ctrl** while scaling to keep the aspect ratio.
|
||
|
||
Clicking a shape selects the frontmost shape under the cursor. With the canvas
|
||
selected (rather than a text field), **Delete** or **Backspace** also removes
|
||
the selected shape.
|
||
|
||
### `✏️ Reshape`
|
||
|
||
Reshape is for editing individual vertices. It does not move the whole shape
|
||
and does not show the Add Shape section, Erase Shape button, Normalize Size,
|
||
or Transform Whole Prop. Center Prop and Show Stickman Guide remain available.
|
||
When the canvas
|
||
is empty, it does not show the Arrange-only “Right-click to add a shape” hint.
|
||
|
||
- Original vertices are filled circles.
|
||
- User-created vertices are hollow rectangles.
|
||
- Drag a vertex to reshape the outline.
|
||
- A vertex drag, insertion, or removal marks the shape as reshaped.
|
||
- Releasing a vertex drag sanitizes polygon/line points (including grid snap
|
||
when enabled, collinear cleanup, and winding cleanup).
|
||
- A reshaped circle hides its Radius control and shows `✏️ This shape was
|
||
reshaped`. Choosing a new radius regenerates a clean circle and clears that
|
||
reshaped state.
|
||
|
||
### `📌 Attach`
|
||
|
||
Attach is for authoring named anchors and checking a selected grip on the
|
||
private stickman Holding Preview. It does not add gameplay attachment or
|
||
physics behavior to Sandbox Stage.
|
||
|
||
Attach mode shows the Attach toolbar and the Anchors inspector. Shape editing
|
||
controls are hidden, as are Normalize Size and Transform Whole Prop. Center Prop
|
||
and Show Stickman Guide remain available, and the prop remains visible on the
|
||
authoring canvas.
|
||
|
||
## Grid, Snap, and canvas navigation
|
||
|
||
The top-right `Grid:` SpinBox accepts values from 1 to 512. It controls the
|
||
drawn grid spacing and the snap increment. The `Snap` checkbox enables or
|
||
disables snapping for canvas transforms and anchor movement.
|
||
|
||
In Attach mode, the top `Snap` checkbox also controls anchor movement. There is
|
||
no separate anchor snapping control. The grid is still available while
|
||
snapping is off; it is only a visual guide in that state.
|
||
|
||
The authoring canvas supports these gestures in every mode:
|
||
|
||
| Gesture | Result |
|
||
| --- | --- |
|
||
| Mouse wheel up/down | Cursor-centered zoom in/out, clamped to 0.3x–3.0x |
|
||
| Pinch/magnify gesture | Cursor-centered zoom |
|
||
| Middle-mouse drag | Pan the canvas |
|
||
| Two-finger pan gesture | Pan the canvas |
|
||
| Left-click | Mode-dependent selection or editing |
|
||
| Right-click | Mode-dependent context menu |
|
||
|
||
The bottom-right status text shows `X` and `Y` world coordinates while the
|
||
cursor is over the authoring canvas. It shows dashes elsewhere.
|
||
|
||
## Authoring canvas context menus
|
||
|
||
### Arrange right-click menu
|
||
|
||
Right-clicking a shape selects the frontmost shape under the cursor and shows:
|
||
|
||
| Action | Result |
|
||
| --- | --- |
|
||
| `Copy` | Copies the selected shape into the editor clipboard. |
|
||
| `Paste` | Appears when the clipboard contains a shape; inserts a copy offset from the cursor. |
|
||
| `Erase` | Removes the selected shape. |
|
||
| `Flip Left-Right` | Mirrors the shape around its own bounding-box center horizontally. |
|
||
| `Flip Up-Down` | Mirrors the shape around its own bounding-box center vertically. |
|
||
| `Bring Forward` | Moves the shape one step toward the front of the drawing stack. |
|
||
| `Send Back` | Moves the shape one step toward the back of the drawing stack. |
|
||
|
||
Right-clicking empty canvas shows:
|
||
|
||
`Add Box`, `Add Plank`, `Add Triangle`, `Add Line`, and `Add Circle`.
|
||
|
||
`Paste` is also available there when the clipboard is populated. New shapes
|
||
are placed at the clicked world position and become selected.
|
||
|
||
### Reshape right-click menu
|
||
|
||
Reshape intentionally has a smaller menu:
|
||
|
||
| Where you right-click | Result |
|
||
| --- | --- |
|
||
| A vertex | `Remove Point` |
|
||
| Near an outline segment | `Create Point`; the new point is inserted at the cursor's projection onto that segment and flashes briefly in yellow |
|
||
| Inside a closed shape | Selects the shape; no menu is shown |
|
||
| Empty canvas | Nothing; shapes cannot be added from this mode |
|
||
|
||
Removing a point from a shape with fewer than two remaining vertices removes
|
||
the shape. A two-point polygon becomes an open line.
|
||
|
||
### Attach right-click behavior
|
||
|
||
Right-click does not open a shape menu in Attach mode. Select and edit anchors
|
||
with left-click, the Attach inspector, or the anchor presets.
|
||
|
||
## Material and shape Inspector
|
||
|
||
The Inspector is scrollable and changes with the active mode and selection.
|
||
|
||
### Material
|
||
|
||
The Material section is hidden in Attach mode to keep the anchor controls and
|
||
Holding Preview readable. Return to Arrange or Reshape to edit the material.
|
||
|
||
The material preset dropdown contains `None`, `Wood`, `Rubber`, `Cardboard`,
|
||
and `Metal`. The preset chooses the default colors used when a new primitive
|
||
is added and displays read-only physics information:
|
||
|
||
- `Mass`
|
||
- `Friction`
|
||
- `Bounce`
|
||
|
||
These readouts come from the prop physics tables. They are informational in
|
||
the Prop Editor; changing the dropdown does not turn the authoring canvas into
|
||
a physics simulation. Save after changing the preset so the new material is
|
||
stored in the `.prop` file. The current implementation updates the preset and
|
||
readouts immediately; a preset-only change may not show `• Modified` until
|
||
another dirty-tracked edit is made.
|
||
|
||
### Selected Shape
|
||
|
||
This section appears when a shape is selected in Arrange or Reshape mode.
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Fill` color picker | Changes the selected shape's fill color live. |
|
||
| `Outline` color picker | Changes the selected shape's outline color live. |
|
||
| `Width` SpinBox | Changes outline width. |
|
||
| `Radius` SpinBox | Changes a clean circle's radius and regenerates its points. |
|
||
| `Vertices` | Read-only count of the selected shape's points. |
|
||
| `Erase Shape` | Deletes the selected shape. It is hidden in Reshape mode. |
|
||
|
||
The Radius row is only shown for a circle that has not been reshaped. Editing
|
||
circle vertices or scaling it non-uniformly changes it into a freeform shape;
|
||
the muted reshaped note explains why Radius is unavailable.
|
||
|
||
### Add Shape
|
||
|
||
The Add Shape section is available in Arrange mode. Choose a primitive from
|
||
the dropdown, adjust its parameters, then press `Add a Shape`.
|
||
|
||
| Primitive | Parameters |
|
||
| --- | --- |
|
||
| `Box` | `Size X`, `Size Y` |
|
||
| `Plank` | `Length`, `Thickness` |
|
||
| `Triangle` | `Base`, `Height` |
|
||
| `Line` | `Length` |
|
||
| `Circle` | `Radius` |
|
||
|
||
The new primitive uses the current material's default fill/outline tint and
|
||
outline width. `Ball` is not shown in the current menu; Circle is the supported
|
||
round primitive in the user interface.
|
||
|
||
## Anchors and Attach mode
|
||
|
||
### Anchor concepts
|
||
|
||
An anchor is a named point in prop-local coordinates. Anchors are saved with
|
||
the `.prop` file alongside the shape stack.
|
||
|
||
Every prop always has one fixed anchor named `origin`:
|
||
|
||
- role: `pivot`;
|
||
- position: `(0, 0)`;
|
||
- rotation: `0` degrees;
|
||
- Z offset: `0`;
|
||
- allowed hands: `both`.
|
||
|
||
Origin cannot be moved, rotated, renamed, or deleted, and it is not listed as
|
||
an editable anchor. A subtle, non-interactive center marker is drawn at the
|
||
fixed local origin in Arrange, Reshape, and Attach. It is a canvas reference,
|
||
not an anchor gizmo that can be selected.
|
||
|
||
If an older `.prop` file has no `anchors` section, the loader synthesizes this
|
||
origin automatically. Saving that file writes the anchor section back out.
|
||
|
||
### Attach toolbar
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Show Stickman Preview` | Shows or hides the private Holding Preview pane. |
|
||
| `Show Other Markers` | Shows or hides the passive origin marker and unselected anchor markers. The selected anchor remains visible. |
|
||
|
||
The Holding Preview is enabled by default when Attach mode is entered.
|
||
|
||
### Anchors list and buttons
|
||
|
||
The list shows every editable custom anchor. `origin` is intentionally hidden
|
||
from this list because it is fixed and cannot be edited.
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Add Anchor` | Creates a normalized ID such as `anchor`, places it at the current shape bounds center, and gives it role `custom` with both hands allowed. |
|
||
| `Rename` | Opens a text-entry dialog. Type a new name, then click `Rename` or press **Enter** to confirm; click Cancel or close the dialog to leave the name unchanged. |
|
||
| `Delete` | Deletes the selected editable anchor. |
|
||
|
||
Anchor IDs are lower-case, normalized to identifier-safe characters, limited
|
||
to 32 characters, and made unique with a suffix such as `_2` when necessary.
|
||
The name is committed only after the rename dialog is confirmed.
|
||
|
||
### Anchor fields
|
||
|
||
| Field | Values and behavior |
|
||
| --- | --- |
|
||
| `Role` | `grip`, `emitter`, `impact`, `mount`, or `custom`. `pivot` is reserved for the hidden fixed origin and is not offered for editable anchors. |
|
||
| `Allowed Hands` | `both`, `left_only`, or `right_only`. This affects Holding Preview compatibility. |
|
||
| `X`, `Y` | Anchor position in prop-local coordinates. |
|
||
| `Rotation` | Anchor rotation in degrees, wrapped to the range -180 through 179. |
|
||
| `Z Offset` | Draw-order offset from -5 through 5. |
|
||
|
||
The X/Y fields can also be edited by dragging the selected marker. For grip
|
||
and emitter anchors, the selected marker has a small rotation dot underneath
|
||
it. Drag that dot to rotate the anchor; hold **Ctrl** to snap rotation to
|
||
15-degree increments. The origin has no rotation dot.
|
||
|
||
Anchor marker colors identify roles: cyan for grip, red for emitter, pink
|
||
diamond for impact, purple for mount, and light gray for custom. The selected
|
||
marker has an additional yellow selection ring. The fixed origin uses its own
|
||
subtle center marker rather than an editable anchor marker.
|
||
|
||
### Anchor presets
|
||
|
||
Presets replace the current non-origin anchor layout and select the first
|
||
editable grip:
|
||
|
||
| Preset | Anchors created |
|
||
| --- | --- |
|
||
| `One-Handed` | One `primary_grip` |
|
||
| `Two-Handed` | `primary_grip` and `secondary_grip` |
|
||
| `Tool / Nozzle` | `primary_grip` and `emitter` |
|
||
| `Melee Edge` | `primary_grip` and `impact` |
|
||
|
||
Preset positions are derived from the current shape bounds. Applying a preset
|
||
is an edit and must be saved like any other change.
|
||
|
||
## Holding Preview
|
||
|
||
Holding Preview appears in Attach mode when `Show Stickman Preview` is on. It
|
||
uses a private visual-only rig and displays the complete authored multi-shape
|
||
prop when the selected anchor is a grip compatible with the selected hand. The
|
||
preview pane is borderless and visually separated from the Inspector by the
|
||
layout splitters.
|
||
|
||
If the selected anchor is not a compatible grip, the prop is hidden and the
|
||
hint explains that a compatible grip must be selected. Select a grip in the
|
||
Anchors list to see the prop held.
|
||
|
||
### Preview header controls
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Left Hand` / `Right Hand` | Chooses which hand holds the selected grip. A left-only or right-only grip disables the incompatible choice and forces the compatible hand. |
|
||
| `Front Pose` / `Walk Left` / `Walk Right` | Chooses the still front-facing pose or an in-place walking direction. Walking mirrors the preview as needed without changing saved anchor data. |
|
||
|
||
### Preview footer controls
|
||
|
||
| Control | What it does |
|
||
| --- | --- |
|
||
| `Pause Walk` / `Resume Walk` | Pauses or resumes the selected walking animation. The button is disabled for Front Pose. |
|
||
| `Reset Arm` | Pauses walking and resets the selected arm's manual IK override. In Front Pose, it returns both preview hand targets to their rest positions. |
|
||
| `Reset View` | Reframes the camera around the complete stickman and visible prop. |
|
||
|
||
### Pose and camera gestures
|
||
|
||
- Drag the cyan diamond target in the preview viewport to pose the selected
|
||
arm. Dragging automatically pauses walking; use Resume Walk to return to the
|
||
walk animation.
|
||
- The target is clamped to the arm's reachable range, so the IK solver does
|
||
not request an impossible wrist position.
|
||
- The prop follows the solved wrist and selected grip anchor, including the
|
||
anchor's rotation and Z offset.
|
||
- Mouse wheel zooms the preview camera around the cursor.
|
||
- Middle-mouse drag pans the preview camera.
|
||
|
||
The preview is for visual authoring only. It does not create a gameplay
|
||
`PropBlock`, collision bodies, physics, Sandbox actions, or runtime attachment
|
||
state. It currently previews one selected grip and one hand; secondary grips
|
||
are saved, but they do not drive a second-hand IK solver.
|
||
|
||
## Saving, dirty state, and recovery
|
||
|
||
### Saving an off-origin prop
|
||
|
||
The editor does not silently recenter a prop. On an explicit Save or Save As,
|
||
it warns when the combined shape-bounds center is farther from the origin than
|
||
`max(1024 px, 2 × bounds diagonal)`. Choose one of:
|
||
|
||
| Choice | Result |
|
||
| --- | --- |
|
||
| `🎯 Center & Save` | Translates all shapes and non-origin anchors together, keeps the fixed origin at `(0, 0)`, focuses the canvas on it, then saves. |
|
||
| `💾 Save Anyway` | Saves the current positions unchanged. |
|
||
| `❌ Cancel` | Leaves the document and save flow unchanged. |
|
||
|
||
Autosaves never show this warning and never recenter the prop.
|
||
|
||
The editor marks the document dirty after changes to the name, shapes, or
|
||
anchors. Save after changing the material preset as well; a preset-only change
|
||
updates the current model but may not show `• Modified` until another
|
||
dirty-tracked edit is made. The status bar shows:
|
||
|
||
`Prop Name — Material • Modified`
|
||
|
||
The window title also adds `*` while dirty and includes the current filename
|
||
when one exists.
|
||
|
||
After about one second without further edits, a dirty document is written to
|
||
`user://prop_editor_autosave.prop`. This is an internal recovery file, not the
|
||
normal saved prop path.
|
||
|
||
- A successful Save, Load, New, or discard clears the autosave.
|
||
- If the editor starts with a usable unsaved autosave, it asks whether to
|
||
`🔄 Restore` or `🗑️ Discard` it.
|
||
- Restoring keeps the document dirty so it still requires an intentional Save.
|
||
- An autosave is silently discarded when its saved source file is already
|
||
newer or equal.
|
||
- The recent list is stored in
|
||
`user://prop_editor_settings.json` and contains at most five paths,
|
||
newest first.
|
||
|
||
Closing the window or choosing New while dirty opens a prompt with `💾 Save`,
|
||
`🗑️ Discard`, and `❌ Cancel`. Cancel leaves the document open. Save As and
|
||
Load dialogs report malformed or unsupported files through the Error dialog.
|
||
|
||
## Current limitations and future scope
|
||
|
||
- Attach mode and Holding Preview are Prop Editor authoring tools only.
|
||
Sandbox Stage custom-prop loading, equipping, releasing, physics, collision,
|
||
and gameplay effects are future work.
|
||
- Preview uses one selected grip and one-hand IK. Two-hand IK, emitter effects,
|
||
impact behavior, mount behavior, throwing, and runtime lifecycle are not
|
||
implemented here.
|
||
- The preview can show the full multi-shape authored prop. Existing runtime
|
||
prop spawning still uses a deterministic single-shape conversion: the
|
||
frontmost closed polygon, otherwise a circle, otherwise the first shape.
|
||
Lines are editor-only and do not become collision geometry in that path.
|
||
- There is no document-wide Undo/Redo history yet. Autosave and recovery are
|
||
safety features, not an edit history.
|
||
- The shape clipboard is an in-memory editor clipboard; it is cleared when a
|
||
new document is started and is not saved into `.prop` files.
|
||
|
||
## Complete manual test checklist
|
||
|
||
### Launch and layout
|
||
|
||
- [ ] Open `res://scenes/prop_editor.tscn` and press F6.
|
||
- [ ] Confirm the File/View menus, prop-name field, mode buttons, canvas,
|
||
Inspector, and status bar are visible.
|
||
- [ ] Drag the main canvas/Inspector splitter left and right.
|
||
- [ ] Make the window narrow; confirm Inspector content can be scrolled and
|
||
controls do not run off the window.
|
||
- [ ] Confirm the Inspector starts at its minimum usable width and has a
|
||
darker contrasting background than the canvas.
|
||
- [ ] Confirm the top `Grid` field and `Snap` button have no clipped top or
|
||
bottom edges.
|
||
- [ ] Enter Attach mode and drag the canvas/preview splitter both directions.
|
||
- [ ] Open `eye.prop` in Arrange mode, switch to Attach, and confirm the
|
||
preview does not push into the Prop Name row or bottom status bar.
|
||
- [ ] Toggle `Show Stickman Preview` and confirm the preview pane appears and
|
||
disappears without affecting the prop document.
|
||
|
||
### New, naming, material, and status
|
||
|
||
- [ ] Choose File → New and confirm the canvas is empty except for the subtle
|
||
fixed-origin marker visible in all three modes.
|
||
- [ ] Type a prop name; confirm the status shows `• Modified` and the window
|
||
title gets `*`.
|
||
- [ ] Select each material preset and confirm the Mass, Friction, and Bounce
|
||
readouts update.
|
||
- [ ] Enter Attach mode and confirm the Material section is hidden.
|
||
- [ ] Confirm the physics readouts are informational and do not launch a
|
||
simulation.
|
||
|
||
### Add and style shapes
|
||
|
||
- [ ] In Arrange mode, add a Box, Plank, Triangle, Line, and Circle from the
|
||
Add Shape section.
|
||
- [ ] Change the primitive parameters before adding each shape.
|
||
- [ ] Right-click empty canvas and add each of the same five primitives.
|
||
- [ ] Select a shape and change Fill, Outline, and Width; confirm the canvas
|
||
updates immediately.
|
||
- [ ] Confirm Vertices reports the selected shape's point count.
|
||
- [ ] Click Erase Shape and confirm only the selected shape is removed.
|
||
|
||
### Arrange transforms and context menu
|
||
|
||
- [ ] Confirm the Arrange top bar order is Transform Whole Prop, Normalize Size,
|
||
Center Prop, then Show Stickman Guide.
|
||
- [ ] Drag a selected shape body to translate it.
|
||
- [ ] Drag the rotation dot and confirm the shape rotates continuously.
|
||
- [ ] Hold Ctrl while rotating and confirm 15-degree stepping.
|
||
- [ ] Drag each scale cross; hold Ctrl and confirm uniform scaling.
|
||
- [ ] Enable Transform Whole Prop; drag visible geometry, the rotation dot, and
|
||
each corner cross, confirming that all shapes and editable anchors follow.
|
||
- [ ] With Snap enabled, move the whole prop and confirm the move delta follows
|
||
the current grid; hold Ctrl while rotating and confirm 15-degree snapping.
|
||
- [ ] Press Esc during a whole-prop gesture and confirm the preview cancels
|
||
without changing the document.
|
||
- [ ] Switch to Reshape or Attach and confirm Transform Whole Prop and
|
||
Normalize Size are hidden while Center Prop and Show Stickman Guide remain.
|
||
- [ ] Use Copy, right-click empty canvas, and Paste; confirm the pasted shape
|
||
is offset and selected.
|
||
- [ ] Test Flip Left-Right and Flip Up-Down.
|
||
- [ ] Stack two or more shapes and test Bring Forward and Send Back.
|
||
- [ ] Confirm the two-tone selection outline, bounding box, dot, and crosses
|
||
remain visible over light and dark shapes.
|
||
|
||
### Reshape and navigation
|
||
|
||
- [ ] Switch to Reshape and confirm Add Shape and Erase Shape are hidden.
|
||
- [ ] Drag an original vertex and confirm the outline changes.
|
||
- [ ] Right-click a segment and choose Create Point; confirm a hollow vertex
|
||
appears at the cursor's projected segment position and flashes yellow.
|
||
- [ ] Right-click a vertex and choose Remove Point.
|
||
- [ ] Right-click the interior of a closed shape and confirm it selects without
|
||
opening a menu.
|
||
- [ ] Right-click empty canvas and confirm no menu appears.
|
||
- [ ] Reshape a circle and confirm Radius is replaced by the reshaped note.
|
||
- [ ] Change Radius after reshaping and confirm a clean circle and Radius row
|
||
return.
|
||
- [ ] Test wheel zoom, pinch/pan if available, and middle-mouse pan. Use View
|
||
→ Reset View and confirm only canvas pan/zoom resets.
|
||
|
||
### Anchors
|
||
|
||
- [ ] Switch to Attach and confirm the Attach toolbar and Anchors inspector
|
||
appear.
|
||
- [ ] Confirm the fixed origin marker is visible in Arrange, Reshape, and
|
||
Attach, has no text label, and cannot intercept clicks.
|
||
- [ ] Confirm `origin` is not in the editable Anchors list.
|
||
- [ ] Add an anchor and confirm it appears in the list at the shape-bounds
|
||
center with role `custom`.
|
||
- [ ] Rename it with a normalized name; confirm both clicking Rename and
|
||
pressing **Enter** commit the change, while Cancel leaves the old name.
|
||
- [ ] Add another anchor and confirm IDs remain normalized and unique.
|
||
- [ ] Delete a non-origin anchor and confirm it is removed.
|
||
- [ ] Test every Role and Allowed Hands option.
|
||
- [ ] Confirm Role contains grip, emitter, impact, mount, and custom, but not
|
||
pivot.
|
||
- [ ] Edit X, Y, Rotation, and Z Offset in the Inspector and confirm the marker
|
||
and preview update.
|
||
- [ ] Drag a selected anchor marker. Toggle Snap and confirm movement follows
|
||
the Grid increment.
|
||
- [ ] For a grip or emitter, drag the rotation dot and test Ctrl 15-degree
|
||
snapping. Confirm the origin marker has no rotation dot.
|
||
- [ ] Toggle Show Other Markers and confirm the origin marker and unselected
|
||
markers hide/show while the selected anchor remains visible.
|
||
- [ ] Apply each preset and confirm its documented anchors appear.
|
||
- [ ] Draw or move a prop far from the origin, click Center Prop, and confirm
|
||
shapes and anchors translate together while the prop's relative layout stays
|
||
unchanged and the canvas focuses on the center marker.
|
||
|
||
### Holding Preview and IK
|
||
|
||
- [ ] Select a grip anchor and confirm the complete authored prop appears in
|
||
Holding Preview, not only the cyan target marker.
|
||
- [ ] Select a non-grip role and confirm the prop hides with the compatibility
|
||
hint.
|
||
- [ ] Confirm the hand choices are labeled Left Hand and Right Hand. Set a grip
|
||
to left-only and right-only and
|
||
confirm the incompatible hand is disabled/forced away.
|
||
- [ ] Test Front Pose, Walk Left, and Walk Right. Confirm walking previews move
|
||
in place and do not change saved anchor X/rotation values.
|
||
- [ ] Drag the cyan target and confirm the arm bends with IK and the prop
|
||
follows the solved wrist.
|
||
- [ ] Confirm dragging the target pauses walking, then click Resume Walk and
|
||
confirm the selected walk resumes.
|
||
- [ ] Click Pause Walk and Resume Walk and confirm the button text and motion
|
||
state change. Confirm Pause Walk is disabled for Front Pose.
|
||
- [ ] Click Reset Arm and confirm walking pauses and the selected arm's manual
|
||
IK override resets. In Front Pose, confirm both hand targets return to rest.
|
||
- [ ] Wheel-zoom and middle-drag the preview camera.
|
||
- [ ] Click Reset View and confirm the complete stickman and visible prop are
|
||
framed.
|
||
- [ ] Confirm the preview has no gameplay physics or collision response.
|
||
|
||
### Save, load, recent, autosave, and compatibility
|
||
|
||
- [ ] Save As with and without typing `.prop`; confirm the final file has one
|
||
`.prop` extension.
|
||
- [ ] Reload the saved file and confirm name, material, all shapes, colors,
|
||
transforms, and anchors survive.
|
||
- [ ] Confirm a successful save clears the dirty indicator and updates Recent.
|
||
- [ ] Load through File → Recent and confirm the same document returns.
|
||
- [ ] Save/load enough files to verify Recent keeps only five, newest first.
|
||
- [ ] Move a prop far from the origin and use Save; verify the off-origin
|
||
warning offers Center & Save, Save Anyway, and Cancel, and that each choice
|
||
has the documented result.
|
||
- [ ] Remove or rename a recent file outside the editor; open Recent and
|
||
confirm the missing entry is pruned.
|
||
- [ ] Make an edit, wait at least one second, close/restart the editor, and
|
||
test Restore and Discard in the recovery dialog.
|
||
- [ ] Confirm Restore keeps the prop dirty and Discard clears the recovery
|
||
file.
|
||
- [ ] Test File → New and window close while dirty; verify Save, Discard, and
|
||
Cancel each do the expected thing.
|
||
- [ ] Load a `.prop` file that has no `anchors` key. Confirm Attach mode
|
||
synthesizes the fixed origin, then save and verify anchors are written.
|
||
- [ ] Load malformed JSON or an unsupported `version` and confirm the Error
|
||
dialog appears without replacing the current valid document.
|