Files
hcie-rust-v3.05/.kilo/plans/1784597466971-vector-state-management-fix.md
T

5.3 KiB

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:

    ts.vector_angle = shape.angle().to_degrees();
    
  2. Canvas drag-rotation (line 6397 in app.rs) also writes the rotated angle back:

    self.settings.tool_settings.vector_angle = angle.to_degrees();
    
  3. New SVG shape creation (line 5768 in app.rs) reads from the same field:

    let svg_angle = self.settings.tool_settings.vector_angle.to_radians();
    

    Then applies it to every new SVG shape at line 6203-6204:

    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:

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:

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:

// 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:

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