L4: re-home dock-panel buttons into three zones

Top toolbar = capture+placement, bottom toolbar = Design-View verbs, footer = narrow Arrange|Design toggle + count + Tail button + set-apart Prune. New pure footer_bar module; Tail is now a real kit button.
This commit is contained in:
2026-07-26 22:42:56 -04:00
parent 7dd9de14df
commit 8f4a84ac79
7 changed files with 817 additions and 278 deletions
+32 -16
View File
@@ -1,12 +1,18 @@
#pragma once
// action_bar — the REAPER-free, LICE-free layout + hit-test math behind the bank_panel's
// TASK-GROUPED action bar (Phase L, L2). L2's dock-panel layout redesign (DS-3: a thorough
// layout, not a re-skin) groups the M11 action-trigger button inventory BY TASK — a compact
// bar of clusters (capture / placement / maintenance) instead of one flat equal-tiled strip
// (the M11 action_buttons row this supersedes for the panel's action inventory). Each button
// carries a label sub-rect and a keybinding-help MICRO sub-rect ("icon+label, keybinding as a
// micro sub-label" — the L2 contract), and the bar degrades gracefully on a narrow panel by
// dropping WHOLE trailing buttons (never clipping) so the frequent capture cluster survives.
// TASK-GROUPED toolbars (Phase L, L2 + L4). L2's dock-panel layout redesign (DS-3: a thorough
// layout, not a re-skin) groups the action-trigger button inventory BY TASK — a compact bar of
// clusters instead of one flat equal-tiled strip (the M11 action_buttons row this supersedes
// for the panel's action inventory). Each button carries a label sub-rect and a keybinding-help
// MICRO sub-rect ("icon+label, keybinding as a micro sub-label" — the L2 contract), and the bar
// degrades gracefully on a narrow panel by dropping WHOLE trailing buttons (never clipping) so
// the frequent leading cluster survives.
//
// L4 re-homes the inventory across TWO toolbars, BOTH driven by this one module: a TOP toolbar
// (Capture + Placement — the two acts the tool exists for) and a BOTTOM toolbar (the Design-View
// verbs, Tagging then Switching). The tiling is cluster-agnostic — it walks the caller's
// ClusterSpec list in order — so the same computeBarSlots / hitTestActionBar serve both bars;
// only the cluster membership and the band rect differ per toolbar.
//
// Why pure (CLAUDE.md §load-bearing split, DS-1 caution): the panel shell owns the SWELL
// window, the L1-kit draws, and the NamedCommandLookup/Main_OnCommand dispatch — all
@@ -32,13 +38,22 @@
namespace reasampler {
// The task cluster a button belongs to (the L2 "group by task" mandate). Capture is the
// primary/frequent gesture (leftmost), then placement, then the rarer maintenance actions.
// The order here IS the left-to-right cluster order in the bar.
// The task cluster a button belongs to (the L2 "group by task" mandate). The order here is
// NOT itself the bar order — the caller passes ClusterSpecs in the order it wants; this enum
// only names the groups so a slot can carry (and a test/shell can assert) its membership.
//
// L4 split the panel's buttons across TWO toolbars, each an action_bar instance:
// * the TOP toolbar draws Capture + Placement (the two acts the tool exists for);
// * the BOTTOM toolbar draws the Design-View verbs, grouped Tagging then Switching.
// Both toolbars share this ONE pure layout module (the tiling is cluster-agnostic — it walks
// the caller's ClusterSpec list in order), so a cluster value belongs to whichever toolbar
// the shell places it in; nothing here couples a cluster to a specific bar.
enum class ActionCluster {
Capture, // capture item / track / realtime / batch — the primary gesture
Placement, // insert at cursor / insert-conform — placing a bank sample on the timeline
Capture, // capture item / track / realtime / batch — top toolbar, primary gesture
Placement, // insert at cursor / insert-conform — top toolbar, placing a sample
Maintenance, // re-capture from source / cancel realtime — rarer upkeep actions
Tagging, // tag / untag selected tracks for the active mode — bottom toolbar (L4)
Switching, // activate Arrange / Design, toggle mode, show-both — bottom toolbar (L4)
};
// The bar the clusters are drawn into, top-left origin (SWELL/LICE convention). (x, y) is the
@@ -90,10 +105,11 @@ struct ActionBarSlot {
};
// One cluster's button count, in the caller's flat action-list order. The caller passes these
// in ActionCluster order (Capture, Placement, Maintenance); a cluster with count 0 is skipped
// (no gap emitted for it). The flat action index a slot carries is the running sum across
// clusters (cluster 0's buttons are indices [0, counts[0]), etc.), so the shell's flat action
// table lines up with the slots by index.
// in the left-to-right order it wants them drawn (top toolbar: Capture then Placement; bottom
// toolbar: Tagging then Switching); a cluster with count 0 is skipped (no gap emitted for it).
// The flat action index a slot carries is the running sum across clusters (cluster 0's buttons
// are indices [0, counts[0]), etc.), so the shell's flat action table lines up with the slots
// by index.
struct ClusterSpec {
ActionCluster cluster = ActionCluster::Capture;
int count = 0;