Implement Phase 6 features for Stickman Editor

- Updated BUGS.md with new issues related to selection bounding box, touchpad panning speed, and zooming behavior.
- Enhanced PROJECT.md with detailed specifications for touchpad controls, recent colors in the color picker, and a status bar for project information.
- Modified project.godot to update compatibility version to 4.7.
- Added a status bar in stickman_editor.tscn to display cursor coordinates and snap status.
- Updated body_part_panel.gd to handle recent colors and cursor detection over drawing areas.
- Enhanced stickman_editor.gd to manage cursor coordinates display and recent colors tracking.
- Improved whole_stickman_preview.gd to render selection gizmos on top of other parts.
- Created master_rig.tscn for the stickman rig structure with bones and IK targets.
- Developed master_rig_builder.gd to automate the rig building process with remote transforms and IK modifications.
This commit is contained in:
2026-08-14 21:49:06 -04:00
parent b97bc145e4
commit 28e8798021
11 changed files with 647 additions and 42 deletions
+39 -17
View File
@@ -22,6 +22,21 @@ assembled in a "Whole Stickman" preview that supports translation, rotation, and
Writes `FILE_VERSION "1.2"`; auto-migrates `"1.0"`/`"1.1"` files on load. Coordinates cross-panel
selection so only one shape is selected at a time (`shape_selected` → deselect others).
Collects per-part `{shapes[], position, rotation, scale}` for save/load.
- **Phase 6 recent colors:** stores `_recent_colors: Array[String]` (max 8,
most-recent-first), loads from `settings.json` (`recent_colors` key) in
`_load_settings()`, saves on each color selection via `_save_settings()`, and
broadcasts to all 10 panels via `_broadcast_recent_colors()`.
- `_on_color_selected(color, part_name)`: deduplicates, inserts the hex string at the
front, trims to 8 entries, saves settings, then broadcasts to all panels.
- `_broadcast_recent_colors()`: pushes `_recent_colors` to every panel via
`BodyPartPanel.set_recent_colors(_recent_colors)`.
- **Phase 6 status bar (cursor coords):** `_process()` polls
`get_global_mouse_position()` each frame, checks each panel via
`is_cursor_over_drawing(global_pos)` and the preview via
`is_cursor_over_preview(global_pos)`, converts to world space via
`global_to_world(global_pos)`, and writes `"X: ### Y: ###"` to `_status_cursor_coords`.
- **Phase 6 snap status:** `_status_snap_status` displays `"SNAP: ON"` / `"SNAP: OFF"`,
set in `_ready()` and re-synced when snap is toggled (`_on_edit_menu_id_pressed`).
- `scripts/body_part_panel.gd``class_name BodyPartPanel`, `extends PanelContainer`.
Reusable per-part editor. Public API:
- `set_shape_data(data: Variant)` — import shape data (Array or single Dictionary; used on Load/Clear)
@@ -31,6 +46,10 @@ assembled in a "Whole Stickman" preview that supports translation, rotation, and
- `deselect()` — clear selection and cancel any in-progress vertex drag
- `signal shape_changed(shapes: Array)` — emitted when any shape is created, modified, deleted, or reordered
- `signal shape_selected()` — emitted on left-click; the editor deselects all other panels
- `signal color_selected(color: Color)` — emitted when the color is confirmed (OK button)
- `set_recent_colors(colors_hex: Array)` — clears existing ColorPicker presets and populates with the given hex colors
- `is_cursor_over_drawing(global_pos: Vector2) -> bool` — true if `global_pos` is over the drawing surface
- `global_to_world(global_pos: Vector2) -> Vector2` — maps a global position to drawing ("world") space
- **Phase 2 vertex editing:** left-click on a shape selects it; drag a vertex handle to
reshape in real time; with a shape selected, right-click near an outline edge offers
"Create Point" (inserts a vertex flagged `1` at the edge midpoint). Original vertices
@@ -41,27 +60,23 @@ assembled in a "Whole Stickman" preview that supports translation, rotation, and
is active for vertex editing.
- **Per-panel zoom:** mouse wheel multiplies `_zoom` by 1.10, clamped to `[0.3, 3.0]`;
drawing and input hit-testing both run in world space via `draw_set_transform`.
- **Drawing approach:** closedness is read from the `closed` flag (Phase 2), not
`shape_type`. Closed shapes are filled via `draw_colored_polygon(pts, color)` before a
2 px outline is drawn with `_draw_polyline(..., closed=true)`. Open shapes render
outline-only (`closed=false`). Shapes draw in array order (z-order).
- `scripts/whole_stickman_preview.gd``class_name WholeStickmanPreview`,
`extends PanelContainer`. Assembles all parts and handles drag-to-reposition, rotation, scale.
- `set_body_parts(parts_data)`, `set_all_part_positions(pos)`, `get_part_position(name)`
- `get_part_rotation(name) -> float`, `set_part_rotation(name, degrees)`
- `get_part_scale(name) -> Vector2`, `set_part_scale(name, scale)`
- `_selected_part` (String) — part with white bounding box selected
- `_interaction` (enum: NONE, TRANSLATE, ROTATE, SCALE) — current gizmo interaction
- Rotation gizmo: filled circle centered below bounding box; Ctrl = 15° snap
- Scale gizmo: crosses at 4 corners; Ctrl = aspect ratio lock
- `signal part_moved(part_name, new_position)`
- Per-panel zoom via mouse wheel (×1.10, clamped to `[0.3, 3.0]`); drag hit-tests and
rendering run in world space.
- **Phase 6 touchpad:** `_gui_input` handles `InputEventMagnifyGesture` (pinch zoom)
and `InputEventPanGesture` (2-finger drag panning), both checked before
`InputEventMouseButton`. Pan gesture delta is multiplied by 3.0 for speed
parity with mouse panning.
- **Phase 6 cursor-centered zoom:** both mouse wheel and pinch zoom adjust
`_pan_offset` so the world point under the cursor stays fixed during zoom.
- **Selection gizmos always on top:** bounding box, rotation circle, and scale
crosses for the selected part are drawn in a second pass after all parts,
via `_selected_gizmo_bounds`, so they always render in front.
- Scenes:
- `scenes/stickman_editor.tscn` — main editor layout; unique-name nodes (`%Prefix`) used
for typed `@onready` access: `%MenuBar`, `%StickmanNameEdit`, `%LeftColumn`,
`%CenterColumn`, `%WholeStickmanPreview`, `%SaveDialog`, `%LoadDialog`,
`%ClearConfirmDialog`, `%ErrorDialog`.
`%ClearConfirmDialog`, `%ErrorDialog`, `%StatusBar`, `%CursorCoords`, `%SnapStatus`.
- **Phase 6 status bar:** `StatusBar` is an `HBoxContainer` bottom-anchored at 28 px
height containing `CursorCoords` (left) and `SnapStatus` (right); `MainLayout`
`offset_bottom` is `-28.0` to leave room for it.
- `scenes/body_part_panel.tscn` — instantiated 10× at runtime (5 per column). Each panel
sets `size_flags_vertical = SIZE_EXPAND_FILL` so the panels expand to fill the column
height in their parent VBoxContainer.
@@ -83,6 +98,13 @@ assembled in a "Whole Stickman" preview that supports translation, rotation, and
- The JSON `.stk` format is defined in `README.md` (versioned `"1.2"`, extensible;
`"1.0"`/`"1.1"` files auto-migrate on load).
### settings.json (Phase 6)
- Persisted editor preferences written to `settings.json` via `_save_settings()` and
loaded in `_load_settings()`.
- Keys: `version`, `grid_size`, `snap_to_grid`, `recent_colors`.
- `recent_colors: Array[String]` — the last up-to-8 selected hex colors, most-recent-first.
Populated on load and flushed on every color selection.
### Legacy scene (do not delete)
- `stick.tscn` — the original rigged/animated figure using `Skeleton2D` + IK targets +
`RemoteTransform2D` + `Line2D` limbs, plus an embedded `@tool` script drawing the head