b49106dc1d
feat: Refactor Iced panel adapter and introduce build metadata management - Updated Cargo.toml files across multiple crates to use workspace versioning. - Enhanced the `iced-panel-adapter` to include a new `plain_slider` module and updated widget rendering to support theme colors. - Added new theme color utilities for recessed and elevated surfaces in `iced-panel-adapter`. - Introduced a new `hcie-build-info` crate to manage build metadata, including a build ID system. - Created a build script to synchronize build IDs across the workspace. - Added a Makefile for simplified build commands for the Iced application. - Implemented regression tests for vector shape creation history in the engine API. - Added a new script for managing Cargo commands with synchronized build ID increments. - Updated line count report to reflect recent changes in codebase. - Created a visual plan document for future improvements in the Iced history and panel systems.
11 KiB
11 KiB
Iced History, Panel, Visual, and Slider Improvements
Scope And Decisions
- Target the Iced workspace under
hcie-iced-app/; usehcie-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, andImported; combine built-in/default presets, every engineBrushStyle, 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 Shapehistory 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
-
Make vector creation an atomic engine history operation.
- Temporarily unlock
hcie-documentandhcie-engine-apiwith 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 alreadyLayerType::Vectorand contains the shape; label itAdd Vector Shape. - In
hcie-engine-api/src/lib.rs::Engine::add_vector_shape, retainpush_vector_snapshotfor an existing vector layer. Replace the current non-vector path (add_layerfollowed by mutation) with the atomic document operation so no intermediate raster-layer history entry is created. - Ensure undo/redo/jump leave
active_layervalid 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 singleadd_vector_shapecall, then refresh cached layers/history through the existing composite refresh path. Add a small helper for refreshingcached_historyif 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_historyexposes the new entry afterVectorDrawEnd.
- Temporarily unlock
-
Convert Custom Shapes from a list to a responsive grid.
- Refactor
hcie-iced-gui/src/panels/custom_shapes.rsto build cards throughiced::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.
- Refactor
-
Build a complete, filterable Brushes & Tips catalog.
- Add a public GUI-side
BrushCategory/filter type and transientbrush_categorystate toHcieIcedApp, plusMessage::BrushCategorySelectedandMessage::BrushPresetSelectedas needed. - Replace the partial 22-entry
BRUSH_PRESETSlist inpanels/brushes.rswith a canonical GUI catalog covering every currently exportedBrushStylevariant, 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(), mergeToolState.imported_brushes, deduplicate by preset ID, and pass the resulting slices plus active category intobrushes::viewfromdock/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
Importedwithout 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.
- Add a public GUI-side
-
Introduce a shared Photoshop-inspired surface system.
- Extend
iced-panel-adapter/src/theme.rs::ThemeColorswith explicit recessed/elevated surface and shadow/highlight tokens, or documented derivation helpers, for every theme preset. Do not hard-code dark-only colors; useis_lightand 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.
- Extend
-
Replace
plain_sliderwith an event-aware custom Iced widget.- Rewrite
hcie-iced-gui/src/widgets/plain_slider.rsas a documentediced::advanced::Widgetinstead of the deprecatedComponent, 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.
- Rewrite
-
Migrate every Iced slider call site.
- Replace existing
plain_slidercalls to passThemeColorsand adopt the new API in dialogs (new_image,confirm,adjustments), properties, filters, layers, tool settings, and any other current users. - Replace direct
iced::widget::slidercalls incolor_picker.rs,toolbar.rs,tool_options.rs,geometry.rs,layer_styles.rs,brushes.rs,text_editor.rs, andstatus_bar.rs, preserving ranges, steps, units, integer conversions, and compact layout requirements. - Update
iced-panel-adapter/src/lib.rsso engine-describedWidgetDescription::Slideralso 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.
- Replace existing
-
Validation and regression protection.
- Run formatting and
git diff --checkwithout 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_regressionandcargo 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, andBrushes & 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.
- Run formatting and
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.