Skip to content

SC panel button row → quadraui::Toolbar (unblocked by quadraui #257 + #259) #505

Description

@JDonaghy

Partial-execution of #480. Quadraui #257 (Toolbar primitive) and #259 (SidebarPanel + multi-row toolbar + hover tracker) have shipped, so the button-row chunk of the Source Control panel is now unblocked.

What this replaces

The SC panel currently hand-paints the same 4-button row twice, plus owns a manual hit-test:

Path Lines What it does
`src/tui_main/panels.rs:858-925` ~67 TUI button strip — equal-share widths, hover/focus bg, icon-only paint for Push/Pull/Sync
`src/gtk/draw.rs:2778-2845` ~67 GTK button strip — same shape, Cairo +Pango
`src/core/engine/source_control.rs:1178-1189` ~12 `sc_button_hit_test()` — hand-rolled `rel_x / total_width` arithmetic to resolve click → button index
`src/tui_main/mouse.rs:1653-1656, 2389-2392` ~10 Mouse hover + click dispatch wiring

~156 lines across four files, plus the engine state (`sc.button_focused: Option`, `sc.button_hovered: Option`) which today is bookkeeping the hover-tracker now owns.

Mapping to quadraui

Each existing button → `ToolbarButton::Action`:

SC button ToolbarButton::Action
Commit (icon + label, ~50% width) `{ id: 'sc:commit', label: 'Commit', icon: Some(GIT_COMMIT), key_hint: Some('c'), enabled: !commit_message.is_empty(), .. }`
Push (icon-only, equal share) `{ id: 'sc:push', label: '', icon: Some(GIT_PUSH), .. }` — Gap-4 icon-only compaction kicks in here
Pull (icon-only, equal share) `{ id: 'sc:pull', label: '', icon: Some(GIT_PULL), .. }`
Sync (icon-only, equal share) `{ id: 'sc:sync', label: '', icon: Some(GIT_SYNC), .. }`

`backend.draw_toolbar(button_row_rect, &bar, hover_tracker.hovered_id(), pressed_id)` replaces both hand-painters. Click routing collapses to `layout.hit_test(x, y)`. `sc_button_hit_test` deletes.

The toolbar's `enabled: !commit_message.is_empty()` on Commit is a genuine win — today the SC panel doesn't grey out Commit when the message is empty (it just no-ops on click). The new primitive makes "disabled with dim paint" first-class.

Bigger opportunity (optional, follow-up)

The bottom half of the SC panel — button row + sections list — has the exact shape of `quadraui::SidebarPanel`: optional toolbar header + content region with coordinated layout, hit-test, and slot-reservation. Migrating to:

```rust
let sc_panel = SidebarPanel {
id: WidgetId::new('sc:panel'),
toolbar: Some(sc_button_toolbar()), // 4-button row above
toolbar_height: Some(1.0), // 1 cell TUI, line_height GTK
};
let layout = backend.draw_sidebar_panel(rect, &sc_panel, hover.hovered_id(), pressed.as_ref());
// Paint sections into layout.content_bounds
sc_sidebar_system.render(backend, layout.content_bounds);
```

This eliminates the `y_commit` cursor + manual `section_start_y` math + the per-backend coordinate threading. Header + commit input stay separate (they don't fit SidebarPanel's shape) — only the button-row + sections pairing benefits.

Recommended order: do the Toolbar swap first (smallest, cleanest), evaluate the SidebarPanel adoption second once the Toolbar is wired through.

Other vimcode targets (separate issues)

This unblocks one of #480's four chunks. The debug toolbar (`debug_toolbar_to_quadraui_status_bar` at `src/render.rs:1954`) is the other obvious Toolbar adoption point but lives outside the SC panel — file separately when picked up.

Test plan

  • Round-trip mouse hover → `hovered_id` → painted hover bg verified by harness.
  • Click on each button fires the existing engine action (`sc_activate_button(idx)`).
  • Disabled Commit no-ops on click (and renders dim).
  • Both backends pass the same harness.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions