Files
hcie-rust-v3.05/.kilo/plans/1783518925862-qt-transition-plan.md
T
2026-07-09 02:59:53 +03:00

14 KiB

Comprehensive Plan: Port All egui Signals/Events to Qt GUI

Complete Event/Signal Map (50+ events from AppEvent)

Every event in event_bus.rs must have a Qt equivalent. Here is the full mapping:

1. Tool & Drawing Events

egui Event Qt Signal/Slot Implementation
ToolChanged(Tool) ToolsPanel::toolChanged(int)MainWindow::onToolChanged(int) Already wired
LayerAdded LayersPanel button → MainWindow::onNewLayer() Already wired
LayerDeleted(u64) LayersPanel delete button → MainWindow::onDeleteLayer() Already wired
LayerSelected(u64) LayersPanel::itemClickedengine->setActiveLayer(id) Already wired
Undo actionUndoMainWindow::onUndo() Already wired
Redo actionRedoMainWindow::onRedo() Already wired
RenderRequested After every engine operation, call canvas->update() Needs wiring
DrawingFinished After end_stroke, no-op in egui No-op in Qt too

2. Document Events

egui Event Qt Signal/Slot Implementation
DocSwitched(usize) QTabWidget::currentChangedMainWindow::onTabChanged(int) Already wired
DocClosed(usize) QTabWidget::tabCloseRequestedMainWindow::onTabCloseRequested(int) Already wired
CloseAllDocs Menu action → iterate tabs, close all Needs wiring
DocCreated{name,w,h} NewImageDialogMainWindow::createDocument() Already wired

3. File Events

egui Event Qt Signal/Slot Implementation
FileOpenRequested actionOpenQFileDialog::getOpenFileNameengine->open_image() Stub exists
FileSaveRequested actionSaveengine->save_as() Stub exists
FileSaveAsRequested actionSaveAsQFileDialog::getSaveFileNameengine->save_as() Stub exists
FileOpened(path,data,w,h) After successful load, create document Needs wiring
ExportRequested actionExportQFileDialog::getSaveFileName Stub exists
ImportRequested actionImportQFileDialog::getOpenFileName Stub exists
ImportSvg(path) actionImportSvgengine->import_svg() Stub exists
ImportBrushesRequested actionImportBrushesQFileDialog → ABR parser Stub exists

4. Filter Events

egui Event Qt Signal/Slot Implementation
ApplyFilter(id, params) FiltersPanel::itemClickedengine->apply_filter() Already wired

5. Selection Events

egui Event Qt Signal/Slot Implementation
SelectionAll actionSelectAllengine->selection_all() Already wired
SelectionDeselect actionSelectDeselectengine->selection_clear() Already wired
SelectionInvert actionSelectInvertengine->selection_invert() Already wired
SelectionGrow(px) actionSelectGrow → dialog → engine->selection_grow() Stub exists
SelectionShrink(px) actionSelectShrink → dialog → engine->selection_shrink() Stub exists
SelectionFeather(r) actionSelectFeather → dialog → engine->selection_feather() Stub exists
SelectionErode(px) actionSelectErode → dialog → engine->selection_shrink() Stub exists
SelectionFade(px) actionSelectFade → dialog → engine->selection_feather() Stub exists

6. Image Transform Events

egui Event Qt Signal/Slot Implementation
RotateClockwise actionRotateCWengine->rotate_layer(+90) Already wired
RotateCounterClockwise actionRotateCCWengine->rotate_layer(-90) Already wired
Rotate180 actionRotate180engine->rotate_layer(180) Already wired
FlipHorizontal actionFlipHengine->flip_layer_horizontal() Already wired
FlipVertical actionFlipVengine->flip_layer_vertical() Already wired
Crop actionCropImageengine->crop(selection_rect) Stub exists
ImageSize actionImageSize → dialog Stub exists
CanvasSize actionCanvasSize → dialog Stub exists
Invert actionInvertengine->apply_filter("invert") Already wired

7. Layer Operations

egui Event Qt Signal/Slot Implementation
MergeDown actionMergeDownengine->merge_down() Already wired
FlattenImage actionFlattenImageengine->flatten_image() Already wired
LayerClear actionClearLayerengine->clear_active_layer_pixels() Already wired
TransformStart actionFreeTransform → enter transform mode Stub exists
AlignLayer(axis) Layer > Align > [axis]engine->align_active_layer() Stub exists

8. Clipboard Events

egui Event Qt Signal/Slot Implementation
ClipboardCopy actionCopyQClipboard → copy layer pixels Stub exists
ClipboardCut actionCut → copy + clear pixels Stub exists
ClipboardPaste actionPasteQClipboard → paste as new layer Stub exists
ClipboardPasteSpecial actionPasteSpecial → paste with options Stub exists

9. Zoom/Pan Events

egui Event Qt Signal/Slot Implementation
ZoomIn actionZoomIncanvas->zoomIn() Already wired
ZoomOut actionZoomOutcanvas->zoomOut() Already wired
ZoomReset actionZoomResetcanvas->setZoom(1.0) Already wired
ZoomSet(f) zoomSlider valueChanged → canvas->setZoom() Already wired
Pan(dx,dy) Middle-mouse drag → canvas->resetPan() Already wired
PanReset actionPanResetcanvas->resetPan() Already wired

10. AI/Vision Events

egui Event Qt Signal/Slot Implementation
AiChatSubmit(text) AiChatPanel send button → AI engine call Stub exists
AiChatStop AI panel stop button Stub exists
SmartSelectRun{x,y} Smart Select tool click → engine->vision_object_segment() Stub exists
VisionRunTask Vision panel run button → engine->vision_*() Stub exists
VisionSelectRun{x1,y1,x2,y2} Vision Select tool drag → engine->vision_object_segment() Stub exists
VisionBackendChanged(backend) Vision panel CPU/GPU toggle Stub exists

11. Text Events

egui Event Qt Signal/Slot Implementation
ToolTextStart{x,y} Text tool click → engine->add_text() Stub exists
ToolTextAccepted Accept button → commit text layer Stub exists
ToolTextCancelled Cancel button → delete/revert text layer Stub exists
TextLayerSelected(id) Double-click text layer → enter edit mode Stub exists

12. Theme/Misc Events

egui Event Qt Signal/Slot Implementation
ThemeChanged(preset) Theme menu items → applyTheme() Already wired
ResetLayout actionResetLayout → recreate dock layout Stub exists
SaveSettings After settings change → save to file Stub exists
ShowStatusMessage(text) After operations → statusBar->showMessage() Needs wiring
OpenLayerStyles(id) Layer Styles button → open panel Stub exists

13. Brush Editor Events (from brush_editor.rs)

egui Feature Qt Implementation
Brush Tip category (size, hardness, spacing, opacity) BrushesPanel needs sliders
Dynamics category (pressure, velocity, tilt) BrushesPanel needs sliders
Color category (cyclic color, variant) BrushesPanel needs checkboxes
Texture category (brush texture overlays) BrushesPanel needs texture picker
Live stroke preview (engine-rendered) CanvasWidget render brush preview
Preset save/load BrushesPanel save/load buttons

14. Geometry Panel Events (from geometry_panel.rs)

egui Feature Qt Implementation
Vector shape list (per-shape selection) PropertiesPanel or new GeometryPanel
Per-shape stroke/opacity/hardness sliders PropertiesPanel dynamic controls
Per-shape color picker (stroke + fill) PropertiesPanel color buttons
Per-shape bounds display PropertiesPanel label
Per-shape delete button PropertiesPanel delete button
Boolean operations (union, subtract, intersect) PropertiesPanel or context menu

15. Layer Styles Events (from layer_styles_panel.rs)

egui Feature Qt Implementation
Drop Shadow (enable, opacity, angle, distance, spread, size, color, blend) LayerStylesPanel sliders
Inner Shadow (same params) LayerStylesPanel sliders
Outer Glow (enable, opacity, spread, size, color, blend) LayerStylesPanel sliders
Inner Glow (enable, opacity, choke, size, color, blend) LayerStylesPanel sliders
Bevel & Emboss (enable, depth, size, angle, altitude, highlight/shadow) LayerStylesPanel sliders
Satin (enable, opacity, angle, distance, size, color, invert) LayerStylesPanel sliders
Color Overlay (enable, opacity, color, blend) LayerStylesPanel controls
Gradient Overlay (enable, opacity, blend, angle, scale, gradient) LayerStylesPanel controls
Pattern Overlay (enable, opacity, blend, scale, pattern) LayerStylesPanel controls
Stroke (enable, size, position, opacity, color, blend) LayerStylesPanel controls

Tasks (Priority Order)

P0: Fix QSS Colors to Match egui Exactly

File: hcie-qt-app/resources/themes/photoshop_dark.qss

All 12+ color tokens must match ThemeColors::get(ThemePreset::Photoshop):

  • #1c1c1e (bg_app), #323236 (bg_panel), #3e3e42 (bg_hover), #242426 (bg_dark_depth)
  • #3a3a3e (bg_elevated), #161618 (bg_recessed), #202022 (title_bar_bg)
  • #3878dc (accent), #404044 (border_high), #28282a (border_low)
  • #e0e0e0 (text_primary), #949498 (text_secondary)

P1: Wire All Menu Actions to Engine FFI

File: hcie-qt-app/src/mainwindow.cpp

Currently stub implementations exist for: Import, Export, ClipboardCopy/Cut/Paste, Crop, ImageSize, CanvasSize, SelectionGrow/Shrink/Feather/Erode/Fade, Align, Transform, LayerStyles, ImageSize, CanvasSize.

Each must call the corresponding m_engine->methodName() and then refresh() all panels + update canvas.

P2: Wire Panel Signals to Engine

Files: All panel .cpp files

Each panel's refresh() must read from engine and populate widgets. Each widget change must call engine method and emit renderRequested.

Key panels needing signal wiring:

  • LayersPanel: visibility toggle, blend mode change, opacity change, layer reorder, add/delete/group/flatten buttons
  • HistoryPanel: jump-to-step click → engine->jumpToHistory()
  • PropertiesPanel: tool-specific sliders (size, opacity, hardness, flow, spacing per tool)
  • BrushesPanel: preset selection → engine->set_brush_tip()
  • FiltersPanel: filter click → engine->apply_filter(name, params)
  • ColorsPanel: color selection → engine->set_color(rgba)
  • AiChatPanel: send button → engine->ai_chat_submit()

P3: Add Missing Panels

New files needed:

  • geometry_panel.h/cpp — vector shape list and per-shape editing
  • layer_styles_panel.cpp — flesh out with 10 style editors (currently stub)

P4: Canvas Rendering Loop

File: hcie-qt-app/src/canvas_widget.cpp

The paintGL() must call engine->get_composite_pixels() every frame (or on dirty). The current implementation does this but needs to handle the dirty flag properly — only re-upload when engine->isCompositeDirty().

P5: Properties Panel Tool-Specific Controls

File: hcie-qt-app/src/panels/properties_panel.cpp

Currently shows placeholder. Must rebuild tool settings based on active tool:

  • Brush/Eraser: size, opacity, hardness, flow, spacing, color variant, cyclic color
  • Pen: size, opacity, hardness, cyclic color
  • Spray: radius, particle size, density, opacity, hardness
  • Flood Fill: tolerance
  • Magic Wand: tolerance
  • Vector tools: stroke, opacity, fill toggle, round rect radius, star points
  • Text: font, size, color, angle, alignment, orientation
  • Gradient: type (linear/radial)
  • VectorSelect: per-shape editing

P6: Color Panel with Standard Qt ColorPicker

File: hcie-qt-app/src/panels/colors_panel.cpp

Replace custom HSL wheel (broken rendering) with:

  • Foreground/Background color swatches
  • "Pick Color" button → QColorDialog::getColor()
  • Palette grid (basic colors)
  • Recent colors list

P7: Status Bar Message Expiry

File: hcie-qt-app/src/mainwindow.cpp

Implement ShowStatusMessage with 3-second timer expiry (matching egui).

Validation

After each task:

  1. cmake --build build — must compile
  2. Visual comparison with egui screenshots
  3. Functional test: each menu item, each panel interaction, each keyboard shortcut

Files Modified

File Changes
hcie-qt-app/resources/themes/photoshop_dark.qss ~30 color values, all widget styling
hcie-qt-app/src/mainwindow.cpp Wire all menu actions to engine
hcie-qt-app/src/mainwindow.h Add missing method declarations
hcie-qt-app/src/panels/properties_panel.cpp Tool-specific settings
hcie-qt-app/src/panels/colors_panel.cpp QColorDialog-based picker
hcie-qt-app/src/panels/brushes_panel.cpp Preset selection, brush tip editing
hcie-qt-app/src/panels/history_panel.cpp Jump-to-step
hcie-qt-app/src/panels/layers_panel.cpp Visibility/blend/opacity signals
hcie-qt-app/src/panels/filters_panel.cpp Filter param dialogs
hcie-qt-app/src/panels/ai_chat_panel.cpp AI chat submit
hcie-qt-app/src/panels/layer_styles_panel.cpp 10 style editors
hcie-qt-app/src/panels/layer_details_panel.cpp Read-only info display
hcie-qt-app/src/canvas_widget.cpp Dirty flag, composite upload
hcie-qt-app/src/hcie_engine_wrapper.h/cpp Missing FFI methods
hcie-qt-app/src/dialogs/* Wire all dialog buttons
hcie-engine-api/src/ffi.rs Add missing FFI functions