MiMo 2.5 feat: enhance vector shape handling with angle snapping and color state management
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# Plan: Fix Vector Tool Angle Persistence and Color State Leaking
|
||||
|
||||
## Problem Analysis
|
||||
|
||||
Both issues stem from `sync_tool_from_shape()` in `hcie-iced-app/crates/hcie-iced-gui/src/shape_sync.rs`.
|
||||
|
||||
### Issue 1: Angle Persistence
|
||||
|
||||
**Root cause:** Two mechanisms conspire to leak angle state:
|
||||
|
||||
1. `sync_tool_from_shape()` (line 150) copies the selected shape's angle into `tool_settings.vector_angle`:
|
||||
```rust
|
||||
ts.vector_angle = shape.angle().to_degrees();
|
||||
```
|
||||
|
||||
2. Canvas drag-rotation (line 6397 in `app.rs`) also writes the rotated angle back:
|
||||
```rust
|
||||
self.settings.tool_settings.vector_angle = angle.to_degrees();
|
||||
```
|
||||
|
||||
3. New SVG shape creation (line 5768 in `app.rs`) reads from the same field:
|
||||
```rust
|
||||
let svg_angle = self.settings.tool_settings.vector_angle.to_radians();
|
||||
```
|
||||
Then applies it to every new SVG shape at line 6203-6204:
|
||||
```rust
|
||||
if matches!(shape, hcie_engine_api::VectorShape::SvgShape { .. }) {
|
||||
shape.set_angle(svg_angle);
|
||||
}
|
||||
```
|
||||
|
||||
**Flow that reproduces the bug:**
|
||||
1. Draw a shape (angle=0, correct)
|
||||
2. Select the shape → `sync_tool_from_shape` copies its angle to `tool_settings.vector_angle`
|
||||
3. Rotate via drag → `tool_settings.vector_angle` updated to rotated value (e.g., 45°)
|
||||
4. Draw a NEW shape → `svg_angle = 45°` → new shape created with 45° rotation
|
||||
|
||||
**Desired behavior:** Every new drawing starts at angle 0, while the properties panel angle slider continues to work for editing selected shapes.
|
||||
|
||||
### Issue 2: Color State Leaking
|
||||
|
||||
**Root cause:** `sync_tool_from_shape()` (lines 182-186) copies the selected shape's colors into the app's active palette:
|
||||
|
||||
```rust
|
||||
app.fg_color = shape.color();
|
||||
if let Some(fc) = shape.fill_color() {
|
||||
app.bg_color = fc;
|
||||
}
|
||||
app.colors_dirty = true;
|
||||
```
|
||||
|
||||
This is called from `VectorShapeSelect` handler (line 6527 in `app.rs`).
|
||||
|
||||
**Desired behavior:** Selecting a shape should NOT change the active color palette. The palette should only change when the user explicitly picks a new color.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### File 1: `hcie-iced-app/crates/hcie-iced-gui/src/shape_sync.rs`
|
||||
|
||||
**Change A — Remove angle sync from `sync_tool_from_shape` (line 150):**
|
||||
|
||||
Delete the line:
|
||||
```rust
|
||||
ts.vector_angle = shape.angle().to_degrees();
|
||||
```
|
||||
|
||||
The Properties panel (`properties.rs`) already receives `vector_angle` from `tool_settings` and passes it to the slider. When the user changes the slider, `VectorAngleChanged` writes directly to `tool_settings.vector_angle` and calls `sync_shape_from_tool`. The selected shape's own angle will no longer contaminate the "default for new shapes" value.
|
||||
|
||||
**Change B — Remove color sync from `sync_tool_from_shape` (lines 182-186):**
|
||||
|
||||
Delete these lines:
|
||||
```rust
|
||||
// Colors
|
||||
app.fg_color = shape.color();
|
||||
if let Some(fc) = shape.fill_color() {
|
||||
app.bg_color = fc;
|
||||
}
|
||||
app.colors_dirty = true;
|
||||
```
|
||||
|
||||
The Geometry and Properties panels already display the selected shape's stroke/fill colors directly from the engine (`shapes[idx].color()`, `shapes[idx].fill_color()`), so the UI remains correct. Color changes in those panels go directly to the engine via `set_vector_shape_color` / `set_vector_shape_fill_color`, independent of `fg_color`/`bg_color`.
|
||||
|
||||
### File 2: `hcie-iced-app/crates/hcie-iced-gui/src/app.rs`
|
||||
|
||||
**Change C — Reset angle after new shape creation (after line 6206):**
|
||||
|
||||
After `engine.add_vector_shape(shape)` at line 6206, add:
|
||||
```rust
|
||||
self.settings.tool_settings.vector_angle = 0.0;
|
||||
```
|
||||
|
||||
This provides a safety net: even if something else writes to `vector_angle` between the last `sync_tool_from_shape` and the next draw, the angle resets after each new shape is committed. The reset also applies for non-SVG shapes (Rect, Circle, Line), ensuring complete consistency.
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `hcie-iced-app/crates/hcie-iced-gui/src/shape_sync.rs` | Remove angle copy (line 150) and color copy (lines 182-186) from `sync_tool_from_shape` |
|
||||
| `hcie-iced-app/crates/hcie-iced-gui/src/app.rs` | Reset `vector_angle` to 0.0 after `add_vector_shape` in `VectorDrawEnd` |
|
||||
|
||||
## What Is Preserved
|
||||
|
||||
- **Properties panel angle slider:** Still works. It reads from `tool_settings.vector_angle` and writes via `VectorAngleChanged`. The slider just won't auto-populate from the selected shape anymore — it retains its value until explicitly changed.
|
||||
- **Geometry panel stroke/fill colors:** Still read directly from the engine shape, unaffected by this change.
|
||||
- **Other tool properties (stroke, opacity, fill, radius, points, sides):** Unaffected — `sync_tool_from_shape` still syncs all non-angle, non-color properties.
|
||||
- **Color palette when picking colors:** Still works. `sync_shape_from_tool` is still called when the user changes colors while a shape is selected, pushing the new palette color to the shape.
|
||||
|
||||
## Validation
|
||||
|
||||
1. Build: `cargo check -p hcie-iced-gui`
|
||||
2. Manual test sequence:
|
||||
- Draw a Rect → select → rotate to 30° → deselect → draw a new Rect → verify new Rect has angle 0°
|
||||
- Draw a Star → select → change angle slider to 45° → deselect → draw a new Star → verify new Star has angle 0°
|
||||
- Select a shape → verify active palette color is NOT changed
|
||||
- Change palette color while shape is selected → verify shape color updates
|
||||
- Use Properties panel angle slider on selected shape → verify the shape's angle changes correctly
|
||||
Reference in New Issue
Block a user