Files
hcie-rust-v3.05/docs/compose/plans/2025-07-15-iced-migration-handoff.md

10 KiB

ICED GUI Migration — Work Handoff (2026-07-15)

Status: IN PROGRESS (build green, 5/5 tests pass)

The 14-task migration plan (docs/compose/plans/2025-07-15-iced-full-gui-migration.md) was already committed by prior sessions. This session focused on closing the functional quality gap vs egui identified by deep comparison of both GUIs.

What this session completed (uncommitted working-tree changes)

All changes are in hcie-iced-app/crates/hcie-iced-gui/src/. Build: cargo build -p hcie-iced-gui (0 errors, 32 warnings).

HIGH priority (functional regressions vs egui — FIXED)

  1. TransformApply TODO stub (app.rs) — the Message::TransformApply handler was a no-op stub. Added apply_transform_to_layer() that composites the floating selection back onto the active layer with scale + rotation support (egui only had scale). Uses public API: get_active_layer_pixels + set_active_layer_pixels.

  2. ~20 missing canvas tool interactions (app.rs CanvasPointerPressed/Moved/Released) — only 8 tools were wired; the rest hit _ => {}. Now wired: MagicWand (engine create_selection_magic_wand), Lasso (freehand point accumulation → create_selection_lasso), PolygonSelect (vertex accumulation + close-on-near-start), SmartSelect (magic-wand fallback), VisionSelect (bbox drag → rect selection), Move (cut selection → floating transform), Gradient (endpoint drag → stroke fill), Text (draft begin), and all 12 vector shape tools (Star/Polygon/Arrow/Rhombus/Cylinder/Heart/Bubble/Gear/Cross/Crescent/Bolt/Arrow4 via add_vector_shape). FloodFill tolerance now reads from settings instead of hardcoded 32.

  3. Touch/pen pressure feed (app.rs subscription) — iced 0.13 touch events carry no pressure, but position feed to tablet_state was missing entirely. Added a TabletTouch message handling iced::Event::Touch (finger press/move → set_screen_pos, lift → reset_pressure), plus screen-size feed in CanvasSize handler. evdev listener (already started in main.rs) remains the pressure source.

  4. Tool option controls were all NoOp (panels/tool_settings.rs, panels/toolbar.rs) — Flow/Spacing/Density/Tolerance/vector-stroke/fill/gradient-type/text-font/size/angle/alignment all emitted Message::NoOp. Rewrote both panels to emit real messages wired to settings persistence. Added settings fields: vector_fill/radius/points/sides, spray_particle_size/density, gradient_type, selection_contiguous/anti_alias, text_font/angle, tool_apply_to_new_layer. Added Message variants: BrushFlowChanged/BrushSpacingChanged/SelectionToleranceChanged/SelectionContiguousToggled/ SelectionFeatherChanged/SprayParticleSizeChanged/SprayDensityChanged/GradientTypeChanged/ VectorStrokeChanged/VectorOpacityChanged/VectorFillToggled/VectorRadiusChanged/ VectorPointsChanged/VectorSidesChanged/TextFontChanged/TextAngleChanged/ TextOrientationChanged/TextContentChanged/TextCommit/ToolApplyToNewLayerToggled.

  5. Color picker broken (color_picker.rs, app.rs) — alpha was force-stripped to 255, recent colors never populated, colors not persisted. Fixed: hex input preserves alpha, added an alpha slider (0-255), swatches/recent render RGBA, FgColorChanged now calls add_recent_color, colors persist to ~/.config/hcie-iced/colors.json via PersistedColors (load on startup, save on change via colors_dirty flag).

MEDIUM priority (UX parity improvements — DONE)

  1. Missing keyboard shortcuts (app.rs subscription) — added P/F/G/C/I/J tools, X swap, [/] brush-size-relative, Tab (dock dialog), F12 (repaint). Enter/Escape now contextual (crop/transform/text-commit confirmation; viewer/crop/transform/selection/dialog cancel) via new EscapePressed/EnterPressed messages (the on_key_press closure must be a non-capturing fn, so resolution happens in update()). Note: [/] use BrushSizeRelative since the closure can't capture self.

  2. Sidebar improvements (sidebar/mod.rs, app.rs) — added per-slot last-used sub-tool memory (slot_last_used field, slot_for_tool/tool_slots/last_used_tool helpers); slot buttons now show the last-used tool's icon. Background swatch is now clickable (promotes bg→fg). Added "D" reset-colors button (ResetColors → fg=black/bg=white). ToolSlot is now pub; TOOL_SLOTS is pub const.

  3. Canvas overlays (canvas/mod.rs) — selection now has a semi-transparent purple fill overlay over the selection bounds (egui has fill over actual mask pixels; this is a bounds approximation since the overlay canvas::Program has no mask access). Vector shape previews now draw actual geometry (ellipse/line/5-star/6-polygon) instead of just a bounding box, driven by active_tool field. Added gradient endpoint preview line + markers. OverlayProgram gained active_tool and gradient_drag fields.

  4. On-canvas text editor (canvas/mod.rs) — when a text_draft is active, a positioned text_input + Commit/Cancel buttons overlay the canvas at the draft's screen position (egui text_overlay.rs). Uses iced Stack + padding offset. Enter commits, Escape cancels.

Supporting changes

  • IcedDocument gained fields: lasso_points, polygon_points, gradient_drag, vision_rect, text_draft. Added TextDraft struct + Default.
  • app.rs new() restored after an accidental deletion during editing (app construction + load_path handling + init_task were re-added from git HEAD).
  • 3 IcedDocument construction sites updated with the new fields.
  • New Message variants also added: LassoDragMove/LassoDragEnd/PolygonAddPoint/PolygonClose/ GradientDragStart/GradientDragMove/GradientDragEnd/BrushSizeRelative/TabletTouch/ EscapePressed/EnterPressed/ResetColors.

What REMAINS to be done (prioritized)

HIGH (functional gaps still open)

  • Marching ants only for rect selections. iced draws marching ants around the selection bounding box (canvas/mod.rs marching-ants section). egui follows the actual irregular selection edge via edge-extraction (render.rs:58-96). Fix requires passing the selection mask to the overlay canvas::Program and rendering an edge outline. The selection-fill overlay added this session is bounds-only for the same reason.

  • Shift+drag brush resize & Ctrl+click eyedropper during strokes (egui mod.rs:271-292). iced shader_canvas event handling has no modifier-key awareness for brush resize, and no Ctrl+click eyedropper shortcut. Requires extending CanvasShaderProgram::update to read modifiers (may need passing modifiers into the shader program or handling at app level).

  • Pen tool distinct path. egui uses draw_pen_segment for vector-like pen strokes (mod.rs:916-933); iced treats Pen identically to Brush (app.rs:1021). Needs an engine API check for a pen-segment method.

  • VectorSelect tool has no canvas interaction. Selecting/moving/rotating existing vector shapes (egui mod.rs:651-739) is unimplemented. Needs find_vector_shape_at + modify_vector_shape engine calls + handle hit-testing in the overlay.

  • History for transform apply. egui's transform also doesn't push a dedicated snapshot, so this matches egui, but ideally TransformApply should be undoable. The engine's push_draw_snapshot is private (locked engine-api); needs an unlock + public wrapper or routing through begin_stroke/end_stroke.

MEDIUM (polish / parity)

  • SmartSelect/VisionSelect real AI backend. Currently SmartSelect falls back to magic-wand and VisionSelect makes a rect selection. egui runs SAM/vision pipelines via AppEvent. Needs the hcie-vision API wired (configurable model path, run buttons in a panel).

  • AI/vision tool option panels (SmartSelect model-path UI, VisionSelect task/backend/run UI — egui panels.rs:1837-1997). Tools are selectable but not configurable from the GUI.

  • Brush stamp cursor (egui mod.rs:1444-1645 cached footprint). iced only draws a simple 10px crosshair. Needs the actual brush-size circle cursor on the canvas overlay.

  • Right-click context menu on canvas (egui mod.rs:2027-2089: copy/cut/paste/new layer/ deselect/crop/quick filters). Not implemented in iced.

  • Double-click to edit existing text layer (egui mod.rs:2013-2025). Not implemented.

  • Layer-not-editable guard + auto-create layer by tool type (egui mod.rs:232-267). iced doesn't guard locked layers or auto-create vector/text layers on tool use.

  • dock_profile dialog toggle on Tab is a stop-in (egui Tab hides panels). A proper panel-visibility toggle is better.

LOW (both GUIs lack these — future work)

Rulers, canvas grid/snap, guides, navigator/minimap, pixel grid at high zoom, scrubby zoom, true fit-to-screen, space-drag pan, scrollbars, pinch zoom, tilt input.

Verification performed

  • cargo build -p hcie-iced-gui → 0 errors, 32 warnings (all unused/dead-code, no logic errors).
  • cargo test -p hcie-iced-gui → 5/5 pass.
  • No manual app launch / screenshot verification done this session (no display available).

Files changed this session

  • hcie-iced-app/crates/hcie-iced-gui/src/app.rs (main logic, ~+400 lines)
  • hcie-iced-app/crates/hcie-iced-gui/src/settings.rs (+13 settings fields + defaults)
  • hcie-iced-app/crates/hcie-iced-gui/src/color_picker.rs (alpha + recent + persistence)
  • hcie-iced-app/crates/hcie-iced-gui/src/panels/tool_settings.rs (full rewrite, NoOp→real)
  • hcie-iced-app/crates/hcie-iced-gui/src/panels/toolbar.rs (flow/tolerance/feather/stroke wired)
  • hcie-iced-app/crates/hcie-iced-gui/src/sidebar/mod.rs (last-used memory, bg-click, reset)
  • hcie-iced-app/crates/hcie-iced-gui/src/canvas/mod.rs (selection fill, shape previews, text overlay)
  • hcie-iced-app/crates/hcie-iced-gui/src/dock/view.rs (tool_settings + toolbar arg wiring)

Note for next session

The uncommitted pressure-indicator work from the prior session (panels/pressure_indicator.rs

  • its canvas wiring) is included in the working tree and builds. Nothing has been committed this session — the next step is to review the diff and commit in logical chunks, then continue with the HIGH-priority remaining items above (marching-ants-for-irregular-selections and Shift/Ctrl modifier handling are the highest-value next steps).