Make the background FX drain visible: a busy cursor over the panel and a footer readout that names its direction, driven off fxReclaimActivity
This commit is contained in:
@@ -107,7 +107,7 @@ L7 sub-pass, 2026-07-27):
|
||||
- `theme` — pure palette module: role→color mapping, REAPER-grey neutral ladder + the pastel accent system, the keyboard strip's spectral ramp, WCAG contrast-floor helpers + `compositeOver` (the effective color of a translucent fill, so alpha overlays are testable). Only the ramp's MID stop is its own constant; lo/hi are still aliases of `accent/primary`/`accent/tertiary`, so a categorical accent move CAN still reorder the ramp — `testSpectralRampLuminanceIsMonotonic` is the build-time catch, not the structure.
|
||||
- `component_geometry` — pure button/slider/list-row geometry + hover hit-test helpers.
|
||||
- `action_bar` — pure task-grouped action-bar layout/hit-test: clusters (Capture / Placement / Maintenance / Tagging / Switching).
|
||||
- `footer_bar` — pure footer layout/hit-test: `[Arrange|Design]` mode-toggle geometry, Tail button, and Prune placement, plus `modeSegmentEnabled` — the mode segment's live/dead predicate under the playback gate AND under whether the shell resolved a routable command id for it (both bools passed IN, so this stays REAPER-free).
|
||||
- `footer_bar` — pure footer layout/hit-test: `[Arrange|Design]` mode-toggle geometry, Tail button, and Prune placement, plus `modeSegmentEnabled` — the mode segment's live/dead predicate under the playback gate AND under whether the shell resolved a routable command id for it (both bools passed IN, so this stays REAPER-free) — plus `footerReadout`, which decides what the footer's ONE passive readout box says: a MOVING background FX drain pre-empts the per-mode member count, since the drain is transient and the count is not. Its `FxDrainState` mirrors the shell's `FxReclaimActivity` name-for-name (a shell header cannot be included here); the shell owns the decision, this owns only the wording, and the two directions word differently because parking and restoring are different acts.
|
||||
- `overflow_menu` — pure overflow-menu-button geometry/reserve/hit-test for the top-toolbar More (⋯) button.
|
||||
- `mode_enable` — pure opposite-mode enablement predicate: given the active mode, computes per-button live/disabled state for the four Item/Track × Arrange/Design tag buttons.
|
||||
- `insert_fx_enable` — pure refusal fold behind the Insert-as-FX verb (one instance holds one capture, so it needs exactly one focused capture AND a destination track), plus the button's live/dead bit derived from that same fold and one sentence per refusal. The payload/destination axes are ordered deliberately because they are knowable at different times — the header states which half the button may speak for.
|
||||
|
||||
@@ -83,4 +83,15 @@ bool modeSegmentEnabled(bool isActiveSegment, bool transportRunning, bool routab
|
||||
return isActiveSegment || (!transportRunning && routable);
|
||||
}
|
||||
|
||||
std::string footerReadout(FxDrainState drain, int activeModeMembers) {
|
||||
// Enumerated rather than defaulted so a fourth state has to be answered here instead
|
||||
// of inheriting the count by accident.
|
||||
switch (drain) {
|
||||
case FxDrainState::Online: return kFxRestoringReadout;
|
||||
case FxDrainState::Offline: return kFxParkingReadout;
|
||||
case FxDrainState::Idle: break;
|
||||
}
|
||||
return std::to_string(activeModeMembers) + (activeModeMembers == 1 ? " track" : " tracks");
|
||||
}
|
||||
|
||||
} // namespace reasampler::ui
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
// (computeSegmentRects / hitTestSegment) for per-segment tiling — mode_switch stays the one
|
||||
// owner of segment geometry.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "core/ui/prune_button.h" // FooterRect — the shared footer strip input type
|
||||
|
||||
namespace reasampler::ui {
|
||||
@@ -79,4 +81,25 @@ FooterHit hitTestFooterBar(int px, int py, const FooterBarLayout& layout);
|
||||
// `core/ui` — stays REAPER-free, exactly as `transportRunning` is.
|
||||
bool modeSegmentEnabled(bool isActiveSegment, bool transportRunning, bool routable);
|
||||
|
||||
// Which way the background FX drain is moving, as the readout needs to hear it. Declared
|
||||
// here rather than taken from the shell's FxReclaimActivity because `core/ui` may not
|
||||
// include a shell header; the member names are deliberately the shell's, so the one map
|
||||
// between them (panel_input) is a name-for-name switch and a drift shows up as one.
|
||||
// Idle is "nothing moving", never "no work queued" — the shell's enum owns that reasoning.
|
||||
enum class FxDrainState { Idle, Online, Offline };
|
||||
|
||||
// DRAFT wording, pending sign-off. Short on purpose: these share the count box, whose
|
||||
// default 64px holds roughly a dozen glyphs at the panel's smallest font before the
|
||||
// shell's kit end-ellipsizes it. The two directions read differently because they ARE
|
||||
// different acts — Offline takes the inactive modes' chains out, Online brings the
|
||||
// entering mode's back.
|
||||
inline constexpr const char* kFxParkingReadout = "parking FX";
|
||||
inline constexpr const char* kFxRestoringReadout = "restoring FX";
|
||||
|
||||
// The footer's ONE passive readout. A moving FX drain pre-empts the per-mode member count
|
||||
// — the drain is transient and the count is not, so it borrows the slot the user already
|
||||
// reads rather than earning a second box that this footer's greedy layout would be the
|
||||
// first to drop on a narrow panel.
|
||||
std::string footerReadout(FxDrainState drain, int activeModeMembers);
|
||||
|
||||
} // namespace reasampler::ui
|
||||
|
||||
Reference in New Issue
Block a user