#pragma once // view — the REAPER-facing shell of the Design View feature (Phase D2). It is the // mirror of the capture shell: the ViewModeModel (pure, D1) holds the mode/ // membership/snapshot state and emits the toggle plan; this shell reads the live // project's folder tree, snapshots the tracks it is about to park, runs the model's // planner, and applies the resulting flag + per-FX-offline writes to REAPER. // // It includes view_mode_model (pure) but NO REAPER headers — the .cpp is the one // REAPER-facing translation unit (CLAUDE.md §contract: only main.cpp defines the // API pointers; every other .cpp gets them extern). Callers (persist, actions) // depend on this seam without dragging the SDK into their include sites. // // Hard invariants this shell enforces (CONTEXT.md §Design View, precision // invariants) — verified in self-review, never crossed: // * Never touches the master track's visibility (SDK forbids B_SHOWINTCP/ // B_SHOWINMIXER on master); the master is never a node in the tree. // * Never reads or writes B_MUTE / I_SOLO on any track. // * Manages ALL leaves via the mode system: an untagged leaf is an Arrange member, // so it is fully parked in non-Arrange modes and restored in Arrange, identically // to a tagged leaf. show-both is the always-visible escape; parents are // visibility-only (derived); the master is never touched. // * Snapshots every to-be-parked track's prior flags BEFORE parking, storing // them into the model so restore is faithful and survives a save-while-parked. #include #include "view_mode_model.h" // REAPER's opaque project handle. Forward-declared to keep this header SDK-free; // the .cpp includes reaper_plugin_functions.h and sees the real class. class ReaProject; namespace reasampler { // Applies `targetModeId` to the live project `proj`: // 1. Reads the arrange-ordered track list, builds the FolderTree from // I_FOLDERDEPTH (via the pure buildFolderTree helper). // 2. Runs model.planToggle(tree, targetModeId). // 3. For each track about to be PARKED: snapshots its current B_SHOWINTCP / // B_SHOWINMIXER / B_MAINSEND / I_FXEN and per-FX offline state, stores the // snapshot into the model, THEN applies the park writes (expanding the // per-FX offline loop from TrackFX_GetCount, which the pure plan leaves empty). // 4. For each track to RESTORE: applies the plan's snapshot-sourced flag + per-FX // offline writes verbatim. // 5. For each PARENT (folder) node: drives B_SHOWINTCP / B_SHOWINMIXER to 1 if the // parent is in model.visibleTracks(tree, targetModeId), else 0 — derived from // membership, never parked/snapshotted. Only the two visibility flags. // 6. Sets the model's active mode to `targetModeId`. // All track mutations are wrapped in Undo_BeginBlock2 / Undo_EndBlock2. // // Returns false (no mutation, active mode unchanged) if `targetModeId` is not a // registered mode. `proj` may be nullptr to mean REAPER's current project. bool applyMode(ViewModeModel& model, const std::string& targetModeId, ReaProject* proj); } // namespace reasampler