L6 toolbar polish: single-row faces, Cancel RT -> overflow, Re-capture between groups
Button faces now show only the short label (keybinding moved to hover tooltip as "name — binding"). Cancel RT joins the overflow menu alongside Capture RT. Re-capture sits between the capture and placement clusters. Toolbar heights 40->28.
This commit is contained in:
+20
-30
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
// action_bar — the REAPER-free, LICE-free layout + hit-test math behind the bank_panel's
|
||||
// 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.
|
||||
// TASK-GROUPED toolbars (Phase L, L2 + L4 + L6). 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 spanning
|
||||
// its full height — a single-row short label (L6: the keybinding sub-row was on the button face
|
||||
// through L5; L6 moves it to the hover tooltip instead). 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
|
||||
@@ -17,8 +18,8 @@
|
||||
// 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
|
||||
// DAW-verified. What is NOT DAW-bound — how the clusters tile the bar, where each button and
|
||||
// its two text sub-rects sit, and which button a click hits — lives HERE, unit-tested outside
|
||||
// the DAW. Mirror of mode_switch / action_buttons / prune_button.
|
||||
// its label sub-rect sit, and which button a click hits — lives HERE, unit-tested outside the
|
||||
// DAW. Mirror of mode_switch / action_buttons / prune_button.
|
||||
//
|
||||
// NAME NOTE (brief §name-collision): ButtonRect / ButtonStripRect / ActionButtonRect /
|
||||
// SegmentRect / CellRect / FooterRect / KitButtonBox are already owned in this namespace, so
|
||||
@@ -74,10 +75,9 @@ struct ActionBarRect {
|
||||
// position in the caller's flat action list (the caller supplies actions in cluster order, so
|
||||
// index also selects the action to fire on a hit). `cluster` is the task group it was laid out
|
||||
// under (surfaced so a test can assert the grouping is structural, and the shell can tint a
|
||||
// cluster). `box` is the whole button rect; `labelBox` and `bindingBox` split it into the
|
||||
// action-name row (top) and the keybinding MICRO row (bottom) so the shell draws each with the
|
||||
// matching kit font. Only VISIBLE buttons get a slot — a button that does not fit is omitted,
|
||||
// never returned clipped, so every slot is fully drawable.
|
||||
// cluster). `box` is the whole button rect; `labelBox` is the text area inset horizontally so
|
||||
// text clears the button edge. Only VISIBLE buttons get a slot — a button that does not fit is
|
||||
// omitted, never returned clipped, so every slot is fully drawable.
|
||||
struct ActionBarSlot {
|
||||
int index = 0;
|
||||
ActionCluster cluster = ActionCluster::Capture;
|
||||
@@ -85,22 +85,16 @@ struct ActionBarSlot {
|
||||
int y = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
// Text sub-rects (absolute, top-left origin), both inside `box`. bindingBox is the bottom
|
||||
// micro strip; labelBox is the remainder above it. When the button is too short to split
|
||||
// (height < a minimum), bindingBox is empty (width/height 0) and labelBox is the whole
|
||||
// interior — the shell then draws only the label (graceful, no clipped micro row).
|
||||
// Label rect (absolute, top-left origin), inside `box`. The label spans the full button
|
||||
// height — a single-row short label only (L6: keybinding sub-row removed from the face;
|
||||
// binding is surfaced in the hover tooltip instead).
|
||||
int labelX = 0, labelY = 0, labelW = 0, labelH = 0;
|
||||
int bindX = 0, bindY = 0, bindW = 0, bindH = 0;
|
||||
|
||||
bool bindingEmpty() const { return bindW <= 0 || bindH <= 0; }
|
||||
|
||||
bool operator==(const ActionBarSlot& o) const {
|
||||
return index == o.index && cluster == o.cluster &&
|
||||
x == o.x && y == o.y && width == o.width && height == o.height &&
|
||||
labelX == o.labelX && labelY == o.labelY &&
|
||||
labelW == o.labelW && labelH == o.labelH &&
|
||||
bindX == o.bindX && bindY == o.bindY &&
|
||||
bindW == o.bindW && bindH == o.bindH;
|
||||
labelW == o.labelW && labelH == o.labelH;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,16 +118,12 @@ struct ClusterSpec {
|
||||
// task grouping reads visually; the 8px-grid density decision).
|
||||
// * sidePad — left/right inset from the bar edges to the first/last button.
|
||||
// * verticalInset — top/bottom gap inside the bar (buttons read as raised, not full-bleed).
|
||||
// * bindingHeight — height of the keybinding MICRO sub-row at the button's bottom.
|
||||
// * minSplitHeight— a button shorter than this is not split (bindingBox empty; label fills).
|
||||
struct ActionBarSpec {
|
||||
int buttonWidth = 108;
|
||||
int buttonGap = 4;
|
||||
int clusterGap = 16;
|
||||
int sidePad = 8;
|
||||
int verticalInset = 3;
|
||||
int bindingHeight = 11;
|
||||
int minSplitHeight = 30;
|
||||
};
|
||||
|
||||
// How many buttons (from the front, cluster by cluster) fit the bar at `spec.buttonWidth`.
|
||||
@@ -152,9 +142,9 @@ BarFit computeBarFit(const ActionBarRect& bar, const std::vector<ClusterSpec>& c
|
||||
// Lays out the VISIBLE buttons (per computeBarFit) left-to-right in cluster order: buttons
|
||||
// pack at buttonWidth with buttonGap inside a cluster and clusterGap between clusters, starting
|
||||
// at bar.x + sidePad. Each slot carries its flat action index, its cluster, its box, and the
|
||||
// label / keybinding sub-rects. Empty clusters emit no gap. Returns exactly visibleCount slots
|
||||
// in ascending index order. A degenerate bar (width/height <= 0), an empty cluster list, or a
|
||||
// non-positive buttonWidth yields empty.
|
||||
// label sub-rect (full-height single row). Empty clusters emit no gap. Returns exactly
|
||||
// visibleCount slots in ascending index order. A degenerate bar (width/height <= 0), an empty
|
||||
// cluster list, or a non-positive buttonWidth yields empty.
|
||||
std::vector<ActionBarSlot> computeBarSlots(const ActionBarRect& bar,
|
||||
const std::vector<ClusterSpec>& clusters,
|
||||
const ActionBarSpec& spec);
|
||||
|
||||
Reference in New Issue
Block a user