# Iced History, Panel, Visual, and Slider Improvements ## Scope And Decisions - Target the Iced workspace under `hcie-iced-app/`; use `hcie-egui-app/` only as a behavioral/design reference. - Visual scope: shared design system plus main chrome (title/menu/sidebar/dock/dialogs) and History, Custom Shapes, and Brushes & Tips. Canvas rendering and AI/script plugin internals are out of scope. - Brush filters: `All`, `Drawing`, `Painting`, `Effects`, `Custom`, and `Imported`; combine built-in/default presets, every engine `BrushStyle`, and imported ABR presets. New custom-preset authoring/rename/delete is out of scope. - Slider input: typing a numeric character while hovering enters edit mode; Enter commits, Escape or focus loss cancels. Clicking the value area also enters edit mode. - First shape on a non-vector layer is one atomic `Add Vector Shape` history action; Undo removes the auto-created vector layer and shape together, Redo restores both. - Preserve all current uncommitted work and protected GPU/dirty-region behavior. ## Implementation Plan 1. **Make vector creation an atomic engine history operation.** - Temporarily unlock `hcie-document` and `hcie-engine-api` with the repository scripts; relock them after edits. - In `hcie-document/src/lib.rs`, add a documented vector-layer creation path that constructs the final vector layer (including its first shape) before recording history. Record one layer-add action whose captured redo layer is already `LayerType::Vector` and contains the shape; label it `Add Vector Shape`. - In `hcie-engine-api/src/lib.rs::Engine::add_vector_shape`, retain `push_vector_snapshot` for an existing vector layer. Replace the current non-vector path (`add_layer` followed by mutation) with the atomic document operation so no intermediate raster-layer history entry is created. - Ensure undo/redo/jump leave `active_layer` valid after the generated layer is removed/restored; clamp or restore selection through the existing engine history wrapper rather than changing protected compositing caches. - In `hcie-iced-gui/src/app.rs::VectorDrawEnd`, keep the single `add_vector_shape` call, then refresh cached layers/history through the existing composite refresh path. Add a small helper for refreshing `cached_history` if tests show no composite dirty flag after a history-only transition. - Add engine tests for: first shape on raster layer adds exactly one named entry; second shape on existing vector layer adds exactly one entry; undo/redo restores layer count, layer type, and shape count; cancelled/zero-result custom shape creates no entry. Add an Iced update-level regression test confirming `cached_history` exposes the new entry after `VectorDrawEnd`. 2. **Convert Custom Shapes from a list to a responsive grid.** - Refactor `hcie-iced-gui/src/panels/custom_shapes.rs` to build cards through `iced::widget::responsive`, deriving columns from available width rather than fixing a one-column list. - Use a theme-safe minimum cell width around 72–84 px, 4–6 px gaps, at least two columns when the pane permits, and row chunking that recomputes whenever dock width changes. - Keep SVG preview, readable label, selected accent border, click behavior, refresh button, path hint, and empty state. Truncate/wrap long labels without expanding a cell beyond the grid width. - Extract/test a pure `grid_column_count(available_width, cell_min, gap)` helper for narrow, normal, and wide panes. 3. **Build a complete, filterable Brushes & Tips catalog.** - Add a public GUI-side `BrushCategory`/filter type and transient `brush_category` state to `HcieIcedApp`, plus `Message::BrushCategorySelected` and `Message::BrushPresetSelected` as needed. - Replace the partial 22-entry `BRUSH_PRESETS` list in `panels/brushes.rs` with a canonical GUI catalog covering every currently exported `BrushStyle` variant, including inactive/missing styles such as Round, Square, Rock, Meadow, Wood, WetPaint, Dirt, Tree, Bristle, Mixer, Blender, and Bitmap. - Initialize built-in runtime presets from `BrushPreset::all_defaults()`, merge `ToolState.imported_brushes`, deduplicate by preset ID, and pass the resulting slices plus active category into `brushes::view` from `dock/view.rs`. - Port egui’s category mapping: Drawing = Basic/Sketch and drawing styles; Painting = Paint/Ink and painting styles; Effects = Texture/Effect/Nature/Mixer and effect styles; Custom matches custom presets; Imported matches Imported and Imported (ABR). Keep all six filter controls visible even when a category is empty. - Make category controls functional and visually selected; show an explicit empty-filter message. Imported ABR completion should switch to or visibly populate `Imported` without dropping existing entries. - Use responsive rows for style/preset cells, cached previews, selected styling, and tooltips. Selecting a preset applies its complete `BrushTip`/style data; selecting a style-only cell updates the style while retaining current size/opacity/hardness unless the egui reference explicitly applies a preset. - Add tests for exhaustive category mapping, imported/custom matching, deduplication, and filter state transitions. 4. **Introduce a shared Photoshop-inspired surface system.** - Extend `iced-panel-adapter/src/theme.rs::ThemeColors` with explicit recessed/elevated surface and shadow/highlight tokens, or documented derivation helpers, for every theme preset. Do not hard-code dark-only colors; use `is_light` and active theme tokens. - In `panels/styles.rs`, add reusable styles for recessed controls, raised cards/buttons, focused cards, pane headers, menus, and dialogs. Use a restrained 1 px highlight edge, low-contrast lower border, 2–6 px shadow blur, and 2–6 px corner radii; avoid heavy shadows on dense lists. - Apply the shared styles to title/menu/sidebar/dock headers and cards, common dialog surfaces, History rows, Custom Shape cards, and Brush filter/preset cells. Preserve the independent opaque surface layers already required to stay above the custom canvas shader. - Match the supplied Photoshop reference’s hierarchy: darkest workspace, mid-level panels, slightly raised headers/controls, compact typography, clear selected states. The “soft 3D” treatment should come from elevation/highlight/shadow, not large gradients or oversized rounded cards. - Capture before/after screenshots for the full viewport and each changed panel; verify both one dark and one light theme. 5. **Replace `plain_slider` with an event-aware custom Iced widget.** - Rewrite `hcie-iced-gui/src/widgets/plain_slider.rs` as a documented `iced::advanced::Widget` instead of the deprecated `Component`, because hover-triggered keyboard entry requires direct event/cursor handling. - Store editing/buffer state in the widget tree; support click/drag on the track, step increments in the right spinner area, hover-started numeric typing, click-to-edit, Enter commit, Escape/blur cancel, range clamping, decimal/comma parsing, suffix formatting, normalized percentages, and event capture while editing so global shortcuts do not fire. - Render a 22 px compact progress-bar control modeled on egui: theme-derived recessed track, subtle vertical gradient on the filled accent portion, narrow value handle, centered label/value, right-side up/down spinner, focus/hover border, and lightweight hover shadow. Derive every color from `ThemeColors`. - Preserve a builder/convenience API for label, range, step, suffix, decimals, width, optional logarithmic mapping, and optional snap steps. Keep parent-owned values and emit messages only for committed typing or pointer/spinner changes. - Add focused unit/widget tests for parsing, formatting, clamping, hover-to-edit, Enter/Escape/blur, percentage conversion, drag endpoints, spinner steps, logarithmic mapping, and theme-derived style output. 6. **Migrate every Iced slider call site.** - Replace existing `plain_slider` calls to pass `ThemeColors` and adopt the new API in dialogs (`new_image`, `confirm`, `adjustments`), properties, filters, layers, tool settings, and any other current users. - Replace direct `iced::widget::slider` calls in `color_picker.rs`, `toolbar.rs`, `tool_options.rs`, `geometry.rs`, `layer_styles.rs`, `brushes.rs`, `text_editor.rs`, and `status_bar.rs`, preserving ranges, steps, units, integer conversions, and compact layout requirements. - Update `iced-panel-adapter/src/lib.rs` so engine-described `WidgetDescription::Slider` also uses the same control and receives active theme colors through its render API. - Use compact labels for RGB/HSL/zoom sliders and avoid duplicated external labels where the new control already displays one. Confirm no raw slider imports/calls remain with a repository grep, except internal implementation details or explicitly documented non-numeric controls. 7. **Validation and regression protection.** - Run formatting and `git diff --check` without reverting unrelated work. - Run `cargo check -p hcie-iced-gui`, `cargo test -p hcie-iced-gui --tests`, and the relevant document/engine API tests. - Because locked engine crates are touched, run `cargo test -p hcie-engine-api --test visual_regression` and `cargo test -p hcie-engine-api --test performance_stroke_4k -- --nocapture`; confirm no protected pooling, cache, dirty-region, tile, or shader code changed. - Exercise vector creation on raster, vector, and locked-vector starting layers; confirm each successful creation adds one visible History row and Undo/Redo is exact. - Use built-in screenshot flows for `History`, `Custom Shapes`, and `Brushes & Tips`, plus full-viewport/dialog captures. Verify responsive grids at narrow/default/wide dock widths, all six brush filters, imported ABR visibility, dark/light themes, slider typing and dragging, and no transparency regression over the shader canvas. ## Risks And Guardrails - The history fix crosses locked engine boundaries; use the sanctioned unlock/lock scripts and stage only intended files. - Do not emulate atomic vector history solely in the GUI or push a pixel snapshot; that would leave redo with the wrong layer type/content. - Keep brush preview generation cached; generating all style/preset thumbnails every frame would regress panel performance. - Hover typing must only start when the pointer is inside the slider and the text event is numeric; otherwise tool shortcuts remain unaffected. - Maintain the protected Iced shader layering and partial-upload mechanisms. New shadows/surfaces must be ordinary GUI layers above the shader, not changes to `shader_canvas.rs`. - No persisted-data migration is required: brush category and slider edit buffers are transient. Existing settings, imported brush behavior, dock layouts, and theme preset serialization remain compatible.