**Phase 1: Prop Theme & Material Token Integration** - **Task 1.1: Prop Design Token Schema** - Define a standalone JSON theme configuration (`prop_theme.json`) structuring design tokens specifically for prop editing (e.g., `outline_widths`, `material_tints`, `primitive_defaults`). - Implement fallback hierarchy for default colors, line widths, and physics values. - _Acceptance Criteria:_ - `prop_theme.json` parses successfully and loads default tokens on editor startup. - Missing keys in custom prop files fall back gracefully without raising runtime errors. - **Task 1.2: Material Preset Visual Utility** - Create helper logic mapping physics material presets (Wood, Rubber, Cardboard, Metal) directly to default mass, friction, bounce, and fill/outline color tints. - _Acceptance Criteria:_ - Selecting a material preset populates default mass, friction, restitution, and visual tint values. - **Task 1.3: Prop Control Inspector Theme** - Apply standardized `.theme` styling to Prop Editor control widgets (`OptionButton`, `SpinBox`, `ColorPicker`, `Button`). - _Acceptance Criteria:_ - Prop Editor controls match visual styling without mutating global GUI settings or sandbox scenes. --- **Phase 2: Vector Geometry, Vertex Editing & Shape Manipulation** - **Task 2.1: Multi-Shape Creation & Primitive Geometry Controls** - Implement UI controls to instantiate primitive shapes (Polygons, Circles, Lines) onto the active drawing surface. - Support an internal shape stack array for multiple vector shapes per prop asset. - _Acceptance Criteria:_ - Adding a shape appends a new vector item to the shape stack array. - Switching primitive modes exposes mode-specific geometry parameters (e.g., radius for circles, vertex lists for polygons). - **Task 2.2: Direct Vertex Dragging & Reshaping** - Render interactive vertex handles on selected shapes. - Implement left-click drag on vertex handles to reshape polygon geometry in real time. - _Acceptance Criteria:_ - Dragging a vertex handle updates the shape mesh visually during input. - Releasing the mouse commits the updated vertex coordinates. - **Task 2.3: Contextual Vertex Insertion & Deletion** - Right-clicking an outline segment displays a **"Create Point"** menu option to insert a vertex at the edge midpoint. - Right-clicking an existing vertex handle displays a **"Remove Point"** option to delete the vertex. - Handle degenerate edges gracefully. - _Acceptance Criteria:_ - Inserting a vertex adds a new point to the shape's point list at the targeted midpoint. - Deleting a vertex removes the handle and closes the surrounding line segment. - Shapes reduced below 2 vertices are removed from the canvas. - **Task 2.4: Shape Selection, Context Menu & Z-Ordering** - Build a canvas hit-testing system to select shapes via left-click. - Implement a right-click context menu offering Copy, Paste, Delete, Mirror X, Mirror Y, Bring Forward, and Send Back. - _Acceptance Criteria:_ - Left-clicking a shape highlights its bounding box and handles. - Pressing `Delete`/`Backspace` or selecting "Delete" removes the targeted shape. - "Bring Forward" and "Send Back" alter the target shape's draw order in the rendering stack. - **Task 2.5: Translation, Rotation & Scaling Gizmos** - Implement direct click-and-drag translation handles on selected shape bounding boxes. - Provide a rotation gizmo that snaps to **15-degree increments** when holding **Ctrl**. - Provide corner scaling handles that lock **aspect ratio** uniform scaling while holding **Ctrl**. - _Acceptance Criteria:_ - Dragging the translation handle translates all vertices in unison. - Holding **Ctrl** during rotation snaps rotation strictly to 15-degree steps. - Holding **Ctrl** during scaling locks aspect ratio; releasing **Ctrl** allows non-uniform scaling. - **Task 2.6: Shape Mirroring Engine** - Implement **Mirror X** and **Mirror Y** shape transformations relative to the shape's bounding-box center. - _Acceptance Criteria:_ - Triggering "Mirror X" inverts X-coordinates across the shape center; "Mirror Y" inverts Y-coordinates. - **Task 2.7: In-Memory Shape Clipboard System** - Implement a dedicated shape clipboard module storing deep duplicates of shape property dictionaries. - _Acceptance Criteria:_ - Copying a shape stores its full parameter dictionary in memory. - Pasting creates a duplicate shape offset from the original. - The "Paste" context menu option is disabled when the clipboard is empty. - **Task 2.8: Live Vector Canvas Synchronizer** - Wire UI input signals directly to `PropBlock` setters for real-time visual updates. - _Acceptance Criteria:_ - Modifying `fill_color`, `outline_color`, or `outline_width` reflects instantly on the active canvas. - **Task 2.9: Point Sanitization Pipeline** - Pass edited polygon coordinates through `TerrainUtils.sanitize_points()`. - _Acceptance Criteria:_ - Committed geometry maintains clockwise vertex ordering and strips redundant collinear points. --- **Phase 3: Physical Property Inspector & Styling Tools** - **Task 3.1: Material Preset Picker** - Implement UI selectors for assigning `material_preset` values and displaying physics properties. - _Acceptance Criteria:_ - Changing material presets updates displayed physics values (mass, friction, restitution). - **Task 3.2: Custom Color Swatch & Palette Pickers** - Build reusable visual color swatches for custom interior fill and outline stroke colors. - _Acceptance Criteria:_ - Selecting custom colors overrides preset colors and updates visual stroke/fill values. --- **Phase 4: Prop Preview Rendering & Disk Caching** - **Task 4.1: Prop SubViewport Thumbnail Generator** - Build an isolated `SubViewport` preview pipeline (`prop_thumbnail.gd`) to capture 2D textures. - _Acceptance Criteria:_ - `prop_thumbnail.gd` renders off-screen prop geometry into a transparent 2D texture without interfering with main editor performance. - **Task 4.2: Disk Caching Pipeline** - Implement local thumbnail export writing textures to `user://thumbnails/props/.png`. - Validate file timestamps to reload cached textures when up-to-date. - _Acceptance Criteria:_ - Saving a prop exports a 200x200 PNG thumbnail to `user://thumbnails/props/.png`. - The editor loads cached thumbnails from disk if source files are unchanged.