Ψ-W1-T2: disjoint per-mode solo surfaces and a playback-gated mode switch

Solo is cached, cleared and replayed per mode on a real switch only; the switch is refused visibly while the transport runs. The footer segment now routes through the activate actions, so a panel switch finally persists.
This commit is contained in:
2026-08-01 19:43:18 -04:00
parent 8bf6841f7b
commit 9c234c2e6b
23 changed files with 811 additions and 49 deletions
+13 -4
View File
@@ -14,10 +14,19 @@ class ReaProject;
namespace reasampler {
// Snapshots each about-to-park track's flags into `model`, runs planToggle,
// applies park/restore writes plus parent visibility flags, then sets the
// active mode. Wrapped in one Undo block. Returns false (no mutation) if
// `targetModeId` isn't registered. `proj` == nullptr means the current project.
// True while `proj`'s transport is playing or recording — the condition under which
// applyMode refuses a real mode switch. Exposed so the panel can paint the footer's
// [Arrange|Design] segments disabled BEFORE the click rather than only refusing on
// it. `proj` == nullptr means the current project.
bool transportBlocksModeSwitch(ReaProject* proj);
// Snapshots each about-to-park track's flags into `model`, caches/clears the
// outgoing mode's solo state and replays the incoming mode's, runs planToggle,
// applies park/restore writes plus parent visibility flags, then sets the active
// mode. Wrapped in one Undo block. Returns false (no mutation) if `targetModeId`
// isn't registered, or if this is a real switch (target != active) while the
// transport is running. A reapply (target == active) is never gated and never
// touches solo. `proj` == nullptr means the current project.
bool applyMode(ViewModeModel& model, const std::string& targetModeId, ReaProject* proj);
// Splits any track visible in more than one mode while carrying its own media