fix(view): park untagged leaves in non-Arrange modes; refresh TCP/MCP on apply
planToggle now enumerates all leaves in the FolderTree instead of only tagged membership entries, so untagged (Arrange-member) tracks park in Design and restore in Arrange. applyMode calls TrackList_AdjustWindows + UpdateArrange so changes render immediately. Correct the stale "tagged-only" invariant comments.
This commit is contained in:
@@ -27,6 +27,8 @@
|
||||
#define REAPERAPI_WANT_TrackFX_SetOffline
|
||||
#define REAPERAPI_WANT_Undo_BeginBlock2
|
||||
#define REAPERAPI_WANT_Undo_EndBlock2
|
||||
#define REAPERAPI_WANT_TrackList_AdjustWindows
|
||||
#define REAPERAPI_WANT_UpdateArrange
|
||||
#include "reaper_plugin_functions.h"
|
||||
|
||||
namespace reasampler {
|
||||
@@ -191,6 +193,14 @@ bool applyMode(ViewModeModel& model, const std::string& targetModeId, ReaProject
|
||||
|
||||
model.setActiveMode(targetModeId);
|
||||
|
||||
// Force REAPER to rebuild the TCP + MCP so visibility/park changes appear now,
|
||||
// not on the user's next TCP interaction. TrackList_AdjustWindows(false) does the
|
||||
// major (full) relayout required when tracks appear/disappear from the panels;
|
||||
// UpdateArrange() repaints the arrange view. Both are documented for exactly this
|
||||
// "you changed track-info flags, now refresh the panels" case.
|
||||
TrackList_AdjustWindows(false);
|
||||
UpdateArrange();
|
||||
|
||||
Undo_EndBlock2(proj, "ReaSampler: apply Design View mode", -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
+4
-2
@@ -15,8 +15,10 @@
|
||||
// * 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.
|
||||
// * Acts only on tracks the model owns (tagged leaves the planner names) plus
|
||||
// derived parents' visibility — never an untagged track's owned flags.
|
||||
// * 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.
|
||||
|
||||
|
||||
+17
-13
@@ -204,15 +204,18 @@ std::set<std::string> ViewModeModel::visibleTracks(const FolderTree& tree,
|
||||
TogglePlan ViewModeModel::planToggle(const FolderTree& tree, const std::string& targetMode) const {
|
||||
TogglePlan plan;
|
||||
|
||||
// Index the tree so we can classify each tagged GUID (leaf vs parent vs stale).
|
||||
std::map<std::string, const FolderNode*> byGuid;
|
||||
for (const auto& node : tree.nodes) byGuid[node.guid] = &node;
|
||||
|
||||
for (const auto& [guid, m] : membership_.all()) {
|
||||
auto it = byGuid.find(guid);
|
||||
if (it == byGuid.end()) continue; // stale GUID: prune-safe, ignore
|
||||
if (it->second->isParent) continue; // parents are derived, never parked
|
||||
if (m.showBoth) continue; // show-both leaves are never parked
|
||||
// The mode system manages EVERY leaf, not just tagged ones. An untagged leaf is
|
||||
// an Arrange member (leafBelongsToMode resolves that), so it must park when the
|
||||
// target mode is not Arrange and restore when it is — the same full park/restore
|
||||
// a tagged leaf gets. Enumerating the FolderTree (not membership_.all()) is what
|
||||
// brings untagged leaves — which are absent from the membership index — under
|
||||
// management. Parents are visibility-only (handled by visibleTracks + the shell's
|
||||
// parent-visibility pass) and show-both leaves are the always-visible escape;
|
||||
// neither is ever parked.
|
||||
for (const auto& node : tree.nodes) {
|
||||
if (node.isParent) continue; // parents are derived, never parked
|
||||
const std::string& guid = node.guid;
|
||||
if (membership_.isShowBoth(guid)) continue; // show-both leaves are never parked
|
||||
|
||||
const bool active = leafBelongsToMode(guid, targetMode);
|
||||
if (active) {
|
||||
@@ -221,10 +224,11 @@ TogglePlan ViewModeModel::planToggle(const FolderTree& tree, const std::string&
|
||||
if (const TrackSnapshot* snap = snapshot(guid))
|
||||
plan.restore.push_back(makeRestorePlan(guid, *snap));
|
||||
} else {
|
||||
// Inactive tagged leaf ⇒ park. fxOffline is intentionally empty here:
|
||||
// the D2 shell expands per-FX offline writes using TrackFX_GetCount.
|
||||
// The pure model has no access to REAPER FX counts at plan time;
|
||||
// makeParkPlan(guid, 0) emits only the scalar flags as a result.
|
||||
// Inactive leaf (tagged into another mode, or untagged in a non-Arrange
|
||||
// mode) ⇒ park. fxOffline is intentionally empty here: the D2 shell
|
||||
// expands per-FX offline writes using TrackFX_GetCount. The pure model
|
||||
// has no access to REAPER FX counts at plan time; makeParkPlan(guid, 0)
|
||||
// emits only the scalar flags as a result.
|
||||
plan.park.push_back(makeParkPlan(guid, /*fxCount=*/0));
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -232,8 +232,9 @@ struct TrackPlan {
|
||||
// The plan for a whole toggle to a target mode: which tracks to park, and which to
|
||||
// restore from their snapshots. Parents and show-both leaves never appear here —
|
||||
// they are derived-visible and never parked (visibility is answered separately by
|
||||
// visibleTracks). Untagged tracks never appear either (the tool owns only what it
|
||||
// tagged).
|
||||
// visibleTracks). Untagged LEAVES DO appear: an untagged leaf is an Arrange member,
|
||||
// so it parks in every non-Arrange mode and restores in Arrange — the mode system
|
||||
// manages all leaves, not only tagged ones.
|
||||
struct TogglePlan {
|
||||
std::vector<TrackPlan> park; // inactive leaves -> parked (fixed zeros)
|
||||
std::vector<TrackPlan> restore; // active leaves returning -> snapshot values
|
||||
@@ -278,11 +279,14 @@ public:
|
||||
std::set<std::string> visibleTracks(const FolderTree& tree,
|
||||
const std::string& modeId) const;
|
||||
|
||||
// Plans a toggle to `targetMode` against the current tree. Inactive tagged
|
||||
// leaves (not show-both, not derived-visible-only) are parked with fixed zeros;
|
||||
// leaves that become active AND have a stored snapshot are restored from it.
|
||||
// Parents, show-both leaves, the master, and untagged tracks are never parked.
|
||||
// Unknown/stale membership GUIDs absent from the tree are ignored (prune-safe).
|
||||
// Plans a toggle to `targetMode` by enumerating EVERY leaf in the supplied tree.
|
||||
// A leaf inactive in the target mode — tagged into another mode, or untagged and
|
||||
// the target isn't Arrange — is parked with fixed zeros; a leaf that becomes
|
||||
// active AND has a stored snapshot is restored from it. Parents (visibility-only)
|
||||
// and show-both leaves (always visible) are never parked; the master is not in
|
||||
// the tree. Untagged leaves ARE managed: they are Arrange members, so they park
|
||||
// in non-Arrange modes and restore in Arrange. Tree membership is the enumeration
|
||||
// source, so stale membership GUIDs absent from the tree are naturally ignored.
|
||||
//
|
||||
// Note: park plans emitted here have an empty fxOffline vector. The D2 shell
|
||||
// expands per-FX offline writes using TrackFX_GetCount — the pure model has no
|
||||
|
||||
Reference in New Issue
Block a user