Fix parent visibility: parent visible by own membership OR derived from children
visibleTracks pass 1 now evaluates every node (parent or leaf) by its own membership, so an untagged folder carrying its own FX/media shows in Arrange (its default) as well as any mode derived from its children. Adds case-matrix tests; updates the nested-Arrange assertion to the corrected rule.
This commit is contained in:
+16
-9
@@ -172,24 +172,31 @@ std::set<std::string> ViewModeModel::visibleTracks(const FolderTree& tree,
|
||||
const std::string& modeId) const {
|
||||
std::set<std::string> visible;
|
||||
|
||||
// Pass 1: every leaf that belongs to the mode is visible.
|
||||
// Pass 1: every node — leaf OR parent — that belongs to the mode by its OWN
|
||||
// membership is visible. For a leaf this is the tagged/show-both/untagged-Arrange
|
||||
// rule; for a parent it means an untagged folder (which carries its own FX/media
|
||||
// and defaults to Arrange) shows in Arrange even when none of its children do.
|
||||
// Parents ALSO become visible in pass 2 by derivation from a visible descendant;
|
||||
// the two rules are OR'd, so an untagged folder of all-Design leaves shows in both
|
||||
// Arrange (own default) and Design (derived).
|
||||
for (const auto& node : tree.nodes) {
|
||||
if (node.isParent) continue; // parents derived in pass 2
|
||||
if (leafBelongsToMode(node.guid, modeId))
|
||||
visible.insert(node.guid);
|
||||
}
|
||||
|
||||
// Pass 2: a parent is visible if any descendant leaf is visible. Walk each
|
||||
// visible leaf up its parent chain and mark ancestors. Parent chains are read
|
||||
// from the supplied tree only (no REAPER access). A cycle-guard bounds the walk
|
||||
// in case a malformed tree links a node to itself.
|
||||
// Pass 2: a parent is also visible if any descendant is visible. Walk each
|
||||
// currently-visible node up its parent chain and mark ancestors. Seeding from the
|
||||
// full pass-1 set means a parent made visible by its own membership propagates its
|
||||
// visibility up the remaining ancestors too. Parent chains are read from the
|
||||
// supplied tree only (no REAPER access). A cycle-guard bounds the walk in case a
|
||||
// malformed tree links a node to itself.
|
||||
std::map<std::string, std::string> parentOf;
|
||||
for (const auto& node : tree.nodes) parentOf[node.guid] = node.parentGuid;
|
||||
|
||||
// Snapshot the leaf-visible set so we don't re-walk parents we add mid-loop.
|
||||
// Snapshot the pass-1 visible set so we don't re-walk parents we add mid-loop.
|
||||
const std::vector<std::string> seeds(visible.begin(), visible.end());
|
||||
for (const auto& leaf : seeds) {
|
||||
auto it = parentOf.find(leaf);
|
||||
for (const auto& node : seeds) {
|
||||
auto it = parentOf.find(node);
|
||||
std::size_t guard = 0;
|
||||
while (it != parentOf.end() && !it->second.empty() && guard++ < parentOf.size()) {
|
||||
const std::string& parent = it->second;
|
||||
|
||||
@@ -150,8 +150,9 @@ private:
|
||||
// -- Folder tree (INPUT, not stored) ----------------------------------------
|
||||
//
|
||||
// The shell builds this from I_FOLDERDEPTH each time and passes it to a visibility
|
||||
// query. A node is a leaf or a parent; a parent is visible in every mode any of
|
||||
// its descendant leaves belongs to, and is never parked. The master track is
|
||||
// query. A node is a leaf or a parent; a parent is visible in a mode if it belongs
|
||||
// to that mode by its own membership OR any of its descendant leaves does, and is
|
||||
// never parked. The master track is
|
||||
// modeled implicitly (always visible, never touched) and is NOT a node here.
|
||||
struct FolderNode {
|
||||
std::string guid;
|
||||
@@ -273,8 +274,11 @@ public:
|
||||
bool leafBelongsToMode(const std::string& guid, const std::string& modeId) const;
|
||||
|
||||
// The set of track GUIDs visible in `modeId`, tree-aware: active leaves,
|
||||
// show-both leaves, and every parent with at least one descendant leaf in the
|
||||
// mode. Untagged leaves count as Arrange. Stale GUIDs in the tree are tolerated.
|
||||
// show-both leaves, and every parent that EITHER belongs to the mode by its own
|
||||
// membership OR has at least one descendant visible in the mode. Untagged nodes
|
||||
// (leaf or folder) count as Arrange, so an untagged folder carrying its own
|
||||
// FX/media shows in Arrange even when none of its children do, and additionally
|
||||
// shows in a child's mode by derivation. Stale GUIDs in the tree are tolerated.
|
||||
// The master is not represented (always visible; the shell never touches it).
|
||||
std::set<std::string> visibleTracks(const FolderTree& tree,
|
||||
const std::string& modeId) const;
|
||||
|
||||
Reference in New Issue
Block a user