Files
hcie-rust-v3.05/.kilo/plans/wx-plain-slider-port.md
T
2026-07-09 02:59:53 +03:00

8.2 KiB
Executable File
Raw Blame History

Plan: Port PlainSlider Design to hcie-wx-app

User Request

Apply the PlainSlider visual/interaction design from hcie-egui-app (label + value centered on a rounded bar, right-side spinner triangles, direct numeric input, progress-bar fill, subtle handle) to the slider controls in hcie-wx-app, which currently uses native wxSlider controls via wxdragon.

Current State

hcie-egui-app PlainSlider

  • Located in hcie-egui-app/crates/egui-panel-adapter/src/lib.rs (lines 188504) and re-exported by hcie-gui-egui/src/app/widgets.rs.
  • Fully custom immediate-mode widget painted with egui:
    • 160×22 px default size, 4 px rounded rectangle.
    • Background color changes on hover (dark/light themes supported via ThemeColors / ThemePreset).
    • Filled track up to current value using a semi-transparent accent color.
    • Thin vertical accent handle at the value position.
    • Centered text: "{label}: {value}{suffix}" (e.g. Size: 110.00 px).
    • Right 24 px spinner area with up/down triangles for stepping.
    • Drag anywhere on the bar to set value; drag ignores spinner area.
    • Logarithmic and snap-step support.
    • Direct keyboard input when the bar is hovered and the user starts typing digits.
  • It is not reusable outside egui; it depends on egui::Widget, egui::Ui, egui::Painter, etc.

hcie-wx-app

  • Native desktop app built on wxdragon (wxWidgets wrapper).
  • Cargo.toml depends on wxdragon only; no egui dependency.
  • Sliders defined in XRC/FBP files as wxSlider:
    • m_sliderSize (1500, current 10)
    • m_sliderOpacity (0100, current 100)
    • m_sliderFlow (0100, current 100)
    • m_sliderHardness (0100, current 0)
    • m_sliderColorR/G/B (color channel sliders in Colors panel)
    • m_slider5 (footer/layer opacity slider)
  • Rust code in hcie-wx-app/src/main.rs accesses them as Slider and binds on_slider events.
  • UI is generated from *.fbp (wxFormBuilder) via Python scripts under hcie-wx-app/ui/.

Technical Verdict

Can the egui PlainSlider be used directly in hcie-wx-app?

No. egui and wxWidgets are separate GUI stacks. There is no supported way to embed an egui widget inside a wxWidgets window.

Can the PlainSlider design be reproduced in hcie-wx-app?

Yes, by creating a custom painted wxWidgets control. This is the viable path:

  1. Implement a new custom wx control (e.g. HciePlainSlider) using wxPanel + wxPaintDC/wxBufferedPaintDC.
  2. Replicate the PlainSlider paint logic: rounded track, fill, handle, centered label/value text, right-side spinner triangles, hover effects.
  3. Replicate interactions: mouse drag/click to set value, spinner up/down on click, keyboard input on hover/focus.
  4. Replace wxSlider usages in the wxFormBuilder project and/or in generated XRC with the new custom control.
  5. Update main.rs event binding to use the new controls API.

User Decisions Confirmed

  • Scope: Replace all wxSlider controls in hcie-wx-app:
    • Properties panel: m_sliderSize, m_sliderOpacity, m_sliderFlow, m_sliderHardness
    • Colors panel: m_sliderColorR, m_sliderColorG, m_sliderColorB
    • Footer: m_slider5
  • Behavior parity: Full PlainSlider behavior: drag, spinner step, direct text input, logarithmic mode where applicable, suffix formatting.

Feasibility Check

Inspected wxdragon 0.9.16 source in cargo registry:

  • Panel supports on_paint, on_left_down, on_left_up, on_motion, on_char, on_key_down, on_key_up, on_enter_window, on_leave_window, on_set_focus, on_kill_focus (via WindowEvents trait).
  • AutoBufferedPaintDC + PaintDC are available, plus DeviceContext trait exposes draw_rounded_rectangle, draw_text, draw_line, draw_polygon, set_pen, set_brush, set_font, set_text_foreground, get_text_extent, get_size, etc.
  • Window trait exposes set_background_style(BackgroundStyle::Paint), refresh, get_client_size, set_min_size, set_size, etc.
  • Conclusion: Option A (custom wxPanel-based control) is fully feasible.

Proposed Implementation Plan

Phase 1 — Create HciePlainSlider custom control

  • Add hcie-wx-app/src/plain_slider.rs.
  • Implement a thin wrapper around wxdragon::Panel that replicates PlainSlider:
    • Stores label, value (f64 internally), min, max, suffix, logarithmic flag, step, snap steps.
    • Handles on_paint with AutoBufferedPaintDC to draw rounded background, fill track, handle, text, spinner triangles, border, hover glow.
    • Handles on_left_down, on_left_up, on_motion for drag/click/spinner.
    • Handles on_char / on_key_down for direct numeric input.
    • Emits value-changed via closure or callback API matching wxdragon::Slider::on_slider style.
  • Provide builder pattern: PlainSlider::builder(parent).with_label(...).with_range(...).with_suffix(...).with_logarithmic(...).build().
  • Port a minimal ThemeColors/ThemePreset from hcie-egui-app to hcie-wx-app (single dark palette as default; add light later if needed).

Phase 2 — Add theme support

  • Create hcie-wx-app/src/theme.rs with ThemePreset and ThemeColors.
  • Default to the existing dark workspace palette (Photoshop/ProDark equivalent).
  • Wire into HciePlainSlider via a theme builder method or global app state if available.

Phase 3 — Replace sliders in UI definition

  • Update hcie-wx-app/ui/refactor_fbp.py make_slider() to generate a custom wxPanel subclass (HciePlainSlider) with the required XRC subclass header instead of wxSlider.
  • Update affected *.fbp files (95_properties.fbp, 70_colors.fbp, 99_project_footer.fbp) to reference the new custom control (either via wxPanel + subclass or by removing the sliders from XRC and creating them in Rust code).
  • Regenerate main.xrc using the existing Python scripts, or document that XRC must be regenerated manually.
  • Recommended: Keep XRC simple and create the custom sliders in Rust during panel initialization, placing them in the sizers by name. This avoids fighting wxFormBuilder.

Phase 4 — Update main.rs integration

  • Change frame.find_child_by_xrc_name::<Slider>("m_sliderSize") etc. to find the new PlainSlider type.
  • Replace slider.on_slider(...) calls with the new control's on_changed API.
  • Ensure all initial values and ranges match the old wxSlider settings.
  • Update RGB slider binding in the Colors section to use the new control.
  • Update footer/layer opacity slider (m_slider5) binding.

Phase 5 — Verify build

  • cargo check --package hcie-wx-app
  • Fix any wxdragon API mismatches (e.g., event data accessor names).

Relevant Files

  • hcie-egui-app/crates/egui-panel-adapter/src/lib.rs — reference PlainSlider paint/interaction logic.
  • hcie-egui-app/crates/egui-panel-adapter/src/theme.rs — reference ThemeColors / ThemePreset definitions.
  • hcie-wx-app/src/main.rs — current slider lookup and event binding.
  • hcie-wx-app/src/plain_slider.rsnew custom slider module.
  • hcie-wx-app/src/theme.rsnew minimal theme tokens.
  • hcie-wx-app/Cargo.toml — no new external deps expected; all needed APIs come from wxdragon.
  • hcie-wx-app/ui/parts/95_properties.fbp, 70_colors.fbp, 99_project_footer.fbp and/or refactor_fbp.py — replace wxSlider definitions with placeholders or subclass references.
  • hcie-wx-app/ui/main.xrc — regenerate or manually update after FBP changes.
  • hcie-wx-app/src/lib.rs (does not exist) or add pub mod plain_slider; pub mod theme; to main.rs.

Risks / Caveats

  • wxdragon API surface now confirmed feasible, but subtle differences from egui painting coordinates may require iterative tuning.
  • High effort for a small UI gain: Replicating a fully custom-painted slider with interaction in wxWidgets is substantially more work than the egui version; estimate 400600 lines of new Rust.
  • XRC/FBP round-trip: Any manual edits to generated files can be overwritten if UI is regenerated from wxFormBuilder. The source of truth should be the *.fbp files and the Python generation scripts, or use Rust-side creation to avoid FBP complexity.
  • Accessibility / native feel: A custom-painted control may lose native accessibility and platform-specific slider behavior.

Plan Exit

Plan finalized and ready for implementation upon user approval.