Goal
Ship `quadraui::gtk::run<A: AppLogic>(app)` — the GTK runner. Blocked on multi-DrawingArea design and `GtkBackend` lift.
Why this is harder than the TUI runner
GTK is callback-driven, not loop-driven. Vimcode has ~20 distinct DrawingAreas (editor, sidebar, status, activity bar, terminal, hover popup, …) each with its own `set_draw_func`. A single `AppLogic::render(&self, backend: &mut Backend)` call can't paint all of them — they paint independently, when GTK queues a redraw on each.
Design sketch
Two options:
(A) Multi-render-method trait
```rust
pub trait GtkAppLogic {
fn setup(&mut self, runner: &mut GtkRunner);
fn handle(&mut self, ev: UiEvent, ...) -> Reaction;
// App declares its DrawingAreas at setup time:
// runner.add_drawing_area("editor", |app, backend| app.render_editor(backend));
}
```
The runner stores closures keyed by area name; each area's `set_draw_func` calls back into the registered closure.
(B) Single-render with target routing
```rust
fn render(&self, backend: &mut dyn Backend, target: AreaId) {
match target {
AreaId::Editor => { /* paint editor / }
AreaId::Sidebar => { / paint sidebar */ }
// …
}
}
```
Cleaner trait shape but needs `AreaId` to be flexible (string id? generic param?).
Depends on
- `GtkBackend` lift into `quadraui::gtk::*` (separate filed stage). Currently `pub(super)` in vimcode; runner can't construct it from outside.
- Decision on (A) vs (B) above.
Migration target
After this lands plus #261 stage runner-tui:
```rust
fn main() {
let app = MyApp::new();
#[cfg(feature = "gui")] quadraui::gtk::run(app);
#[cfg(feature = "tui")] quadraui::tui::run(app);
}
```
Vimcode's `src/main.rs` + `src/{tui_main,gtk}/mod.rs` collapse from ~16k lines to ~1k (the audit's estimate).
Surfaced during
#261 stage A — trait design landed.
Goal
Ship `quadraui::gtk::run<A: AppLogic>(app)` — the GTK runner. Blocked on multi-DrawingArea design and `GtkBackend` lift.
Why this is harder than the TUI runner
GTK is callback-driven, not loop-driven. Vimcode has ~20 distinct DrawingAreas (editor, sidebar, status, activity bar, terminal, hover popup, …) each with its own `set_draw_func`. A single `AppLogic::render(&self, backend: &mut Backend)` call can't paint all of them — they paint independently, when GTK queues a redraw on each.
Design sketch
Two options:
(A) Multi-render-method trait
```rust
pub trait GtkAppLogic {
fn setup(&mut self, runner: &mut GtkRunner);
fn handle(&mut self, ev: UiEvent, ...) -> Reaction;
}
```
The runner stores closures keyed by area name; each area's `set_draw_func` calls back into the registered closure.
(B) Single-render with target routing
```rust
fn render(&self, backend: &mut dyn Backend, target: AreaId) {
match target {
AreaId::Editor => { /* paint editor / }
AreaId::Sidebar => { / paint sidebar */ }
// …
}
}
```
Cleaner trait shape but needs `AreaId` to be flexible (string id? generic param?).
Depends on
Migration target
After this lands plus #261 stage runner-tui:
```rust
fn main() {
let app = MyApp::new();
#[cfg(feature = "gui")] quadraui::gtk::run(app);
#[cfg(feature = "tui")] quadraui::tui::run(app);
}
```
Vimcode's `src/main.rs` + `src/{tui_main,gtk}/mod.rs` collapse from ~16k lines to ~1k (the audit's estimate).
Surfaced during
#261 stage A — trait design landed.