Files
hcie-rust-v3.05/.mimocode/plans/1784552687276-playful-panda.md
phantom 3659b886ff Refactor and enhance the Iced GUI with new features and improvements
- Improved layout and styling in filter_params.rs for better visual consistency.
- Enhanced filters.rs to ensure scrollable parameters fill the available width.
- Added a new Custom Shapes panel to display user-defined SVG shapes.
- Updated menus.rs to include a new Custom Shapes menu item and adjusted related logic.
- Modified properties.rs to support additional spray tool properties (particle size and density).
- Adjusted title_bar.rs for improved menu button dimensions and layout.
- Enhanced toolbar.rs to include spray tool options in the toolbar.
- Fixed color persistence issues in settings.rs to ensure colors are saved and loaded correctly.
- Updated plain_slider.rs to ensure sliders utilize the full width of their containers.
- Created a visual polish plan to address various UI/UX issues and improve overall usability.
2026-07-20 20:24:40 +03:00

4.1 KiB

Color Palette Panel — Persistence & Layout Fixes

Problem Statement

The iced GUI color palette panel has several issues:

  1. Colors don't persist between sessions — bg color changes are never saved (bug in BgColorChanged handler), and save failures are silently ignored
  2. Reset button should return to black/white (already works correctly)
  3. Recent colors don't persist — same root cause as #1 (dirty flag issue)
  4. Panel minimum height is too low (180px) — contents get clipped, especially the color wheel (220px canvas)

Root Cause Analysis

Bug 1: BgColorChanged never persists (PRIMARY ISSUE)

In app.rs:2352-2356, the BgColorChanged handler does NOT set self.colors_dirty = true:

Message::BgColorChanged(color) => {
    self.bg_color = color;
    // MISSING: self.colors_dirty = true;
    crate::shape_sync::sync_shape_from_tool(self);
    self.refresh_composite_if_needed();
}

Compare with FgColorChanged (line 2347) which DOES set it. This means background color changes are never written to disk.

Bug 2: Save order issue

In app.rs:8845-8848, the dirty flag is cleared BEFORE the save:

if self.colors_dirty {
    self.colors_dirty = false;        // cleared first
    save_colors(...);                  // save second — if this fails, flag is already cleared
}

If save_colors fails (e.g., directory doesn't exist), the flag is already cleared and the save won't retry.

Bug 3: Silent save failures

save_colors() uses let _ = std::fs::write(...) which discards errors. If ~/.config/hcie-iced/ doesn't exist, writes fail silently.

Implementation Plan

Step 1: Fix BgColorChanged persistence

File: hcie-iced-app/crates/hcie-iced-gui/src/app.rs (line ~2354)

Add self.colors_dirty = true; to the handler.

Step 2: Fix save order

File: hcie-iced-app/crates/hcie-iced-gui/src/app.rs (line 8845-8848)

Swap the order — save first, then clear the flag:

if self.colors_dirty {
    save_colors(self.fg_color, self.bg_color, &self.recent_colors);
    self.colors_dirty = false;
}

Step 3: Add directory creation in save_colors

File: hcie-iced-app/crates/hcie-iced-gui/src/app.rs (line 93-101)

Add create_dir_all before writing:

fn save_colors(fg: [u8; 4], bg: [u8; 4], recent: &[[u8; 4]]) {
    let path = colors_path();
    if let Some(parent) = path.parent() {
        let _ = std::fs::create_dir_all(parent);
    }
    // ... rest unchanged
}

Step 4: Increase panel minimum height

File: hcie-iced-app/crates/hcie-iced-gui/src/dock/sizing.rs (line 70-73)

Change ColorPicker policy:

PaneType::ColorPicker => PaneSizePolicy {
    width: axis(180.0, 280.0, 380.0, 1),
    height: axis(300.0, 420.0, 500.0, 1),
}

Rationale for values:

  • Min 300px: Shows swatch row, hex input, alpha slider, tab bar, and start of color wheel
  • Preferred 420px: Shows full color wheel (220px canvas) + header + recent colors without scrolling
  • Max 500px: Bounded to prevent stealing vertical space from sibling panels (Layers has grow_priority=35 vs color's 1)

Step 5: Update test assertions

File: hcie-iced-app/crates/hcie-iced-gui/src/dock/sizing.rs

Tests to update:

  1. policy_values_prioritize_canvas_and_bound_color_picker (line 437-441): Update preferred/max values
  2. subtree_constraints_follow_split_axis (line 453): Update height.max assertion (Layers has INFINITY max, so shared axis max becomes INFINITY)
  3. color_picker_does_not_receive_vertical_surplus_with_list_sibling (line 494): Update max bound check

Files to Modify

  1. hcie-iced-app/crates/hcie-iced-gui/src/app.rs — 3 changes (BgColorChanged fix, save order, create_dir_all)
  2. hcie-iced-app/crates/hcie-iced-gui/src/dock/sizing.rs — policy update + 3 test updates

Verification

  1. Launch app, change both fg and bg colors, close and reopen — both should be restored
  2. Click "D" button — fg=black, bg=white
  3. Select several colors, close/reopen — recent colors preserved
  4. Resize color palette pane to minimum — color wheel and recent colors visible
  5. cargo test -p hcie-iced-gui — all tests pass