Collapse a Design View mode switch to ONE undo point: FX writes run inline in applyMode's block, deferred park queue deleted

This commit is contained in:
2026-08-06 04:32:26 -04:00
parent 8a7056d19d
commit 8c06383fe7
11 changed files with 392 additions and 925 deletions
+24 -5
View File
@@ -23,13 +23,32 @@ namespace reasampler {
// `nullptr` meaning the current project here is inferred by analogy, not confirmed.
bool transportBlocksModeSwitch(ReaProject* proj);
// Does one applyMode leave an undo point behind?
//
// A REAPPLY that wrote nothing must not: the load-tick reapply over a project
// saved fully parked re-plans a park for every inactive leaf and finds every
// flag and every FX already where it wants them, so a point there would mean
// opening a project costs an undo step. `Undo_EndBlock2(proj, "", 0)` is the
// discard form (mintManagedLanes' no-op path uses the same idiom).
//
// A real switch mints regardless, fail-safe: it is an explicitly fired action
// and has to stay undoable even in the degenerate case where the plan found
// nothing to write. Note what applyMode CANNOT see when it decides — the
// `view_state` ext-state write lands in persistViewState, after this block has
// closed (src/shell/view/CLAUDE.md's Gotchas).
inline bool applyMintsUndoPoint(bool realSwitch, bool wroteAnything) {
return realSwitch || wroteAnything;
}
// 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.
// applies park/restore writes — flags AND per-FX offline, synchronously — plus
// parent visibility flags, then sets the active mode. ONE switch is ONE undo
// point; everything it moved rolls back in a single Ctrl-Z. 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