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.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# 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`:
|
||||
```rust
|
||||
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:
|
||||
```rust
|
||||
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:
|
||||
```rust
|
||||
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:
|
||||
```rust
|
||||
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:
|
||||
```rust
|
||||
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
|
||||
Reference in New Issue
Block a user