Fixing solo nesting. Fixes some visibility conditions JC caught while attempting to nest multiple solos into other solos a few times. Added tests for these conditions to both the editor and the C++ runtime. Diffs= 2bc4acfba Fixing solo nesting. (#5066)
diff --git a/.rive_head b/.rive_head index 3f2c367..3b930e3 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -daaf140ba0a062ba9ec7f4eafa1e198d9121b220 +2bc4acfbae514b00af797f08e28e35bad6fb76c3
diff --git a/include/rive/solo.hpp b/include/rive/solo.hpp index fcfe8e3..8458d76 100644 --- a/include/rive/solo.hpp +++ b/include/rive/solo.hpp
@@ -8,9 +8,10 @@ public: void activeComponentIdChanged() override; StatusCode onAddedClean(CoreContext* context) override; + bool collapse(bool value) override; private: - void propagateCollapse(); + void propagateCollapse(bool collapse); }; } // namespace rive
diff --git a/src/solo.cpp b/src/solo.cpp index 0934430..8e842f8 100644 --- a/src/solo.cpp +++ b/src/solo.cpp
@@ -3,15 +3,29 @@ using namespace rive; -void Solo::propagateCollapse() +void Solo::propagateCollapse(bool collapse) { - Core* active = artboard()->resolve(activeComponentId()); + Core* active = collapse ? nullptr : artboard()->resolve(activeComponentId()); for (Component* child : children()) { child->collapse(child != active); } } -void Solo::activeComponentIdChanged() { propagateCollapse(); } + +bool Solo::collapse(bool value) +{ + // Intentionally using Component instead of Super as we don't want to call + // collapse on the Container logic which just propagates blindly to + // children. + if (!Component::collapse(value)) + { + return false; + } + propagateCollapse(value); + return true; +} + +void Solo::activeComponentIdChanged() { propagateCollapse(isCollapsed()); } StatusCode Solo::onAddedClean(CoreContext* context) { @@ -21,6 +35,6 @@ return code; } - propagateCollapse(); + propagateCollapse(isCollapsed()); return StatusCode::Ok; } \ No newline at end of file
diff --git a/test/assets/nested_solo.riv b/test/assets/nested_solo.riv new file mode 100644 index 0000000..981202c --- /dev/null +++ b/test/assets/nested_solo.riv Binary files differ
diff --git a/test/solo_test.cpp b/test/solo_test.cpp index f653930..9483e1b 100644 --- a/test/solo_test.cpp +++ b/test/solo_test.cpp
@@ -58,3 +58,85 @@ REQUIRE(green->isHidden()); REQUIRE(red->isHidden()); } + +TEST_CASE("nested solos work", "[solo]") +{ + auto file = ReadRiveFile("../../test/assets/nested_solo.riv"); + + auto artboard = file->artboard()->instance(); + artboard->advance(0.0f); + auto s1 = artboard->find<rive::Solo>("Solo 1"); + REQUIRE(s1 != nullptr); + auto s2 = artboard->find<rive::Solo>("Solo 2"); + REQUIRE(s2 != nullptr); + auto s3 = artboard->find<rive::Solo>("Solo 3"); + REQUIRE(s3 != nullptr); + + auto a = artboard->find<rive::Shape>("A"); + REQUIRE(a != nullptr); + auto b = artboard->find<rive::Shape>("B"); + REQUIRE(b != nullptr); + auto c = artboard->find<rive::Shape>("C"); + REQUIRE(c != nullptr); + auto d = artboard->find<rive::Shape>("D"); + REQUIRE(d != nullptr); + auto e = artboard->find<rive::Shape>("E"); + REQUIRE(e != nullptr); + auto f = artboard->find<rive::Shape>("F"); + REQUIRE(f != nullptr); + auto g = artboard->find<rive::Shape>("G"); + REQUIRE(g != nullptr); + auto h = artboard->find<rive::Shape>("H"); + REQUIRE(h != nullptr); + auto i = artboard->find<rive::Shape>("I"); + REQUIRE(i != nullptr); + + s1->activeComponentId(artboard->idOf(a)); + s2->activeComponentId(artboard->idOf(d)); + s3->activeComponentId(artboard->idOf(h)); + artboard->advance(0.0f); + + REQUIRE(a->isCollapsed() == false); + REQUIRE(b->isCollapsed() == true); + REQUIRE(c->isCollapsed() == true); + + REQUIRE(d->isCollapsed() == true); + REQUIRE(e->isCollapsed() == true); + REQUIRE(f->isCollapsed() == true); + + REQUIRE(g->isCollapsed() == true); + REQUIRE(h->isCollapsed() == true); + REQUIRE(i->isCollapsed() == true); + + // Changing active in a collapsed solo doesn't affect anything. + s3->activeComponentId(artboard->idOf(g)); + artboard->advance(0.0f); + + REQUIRE(a->isCollapsed() == false); + REQUIRE(b->isCollapsed() == true); + REQUIRE(c->isCollapsed() == true); + + REQUIRE(d->isCollapsed() == true); + REQUIRE(e->isCollapsed() == true); + REQUIRE(f->isCollapsed() == true); + + REQUIRE(g->isCollapsed() == true); + REQUIRE(h->isCollapsed() == true); + REQUIRE(i->isCollapsed() == true); + + s1->activeComponentId(artboard->idOf(c)); + artboard->advance(0.0); + + // Now the rest of the nested solo items should be visible. + REQUIRE(a->isCollapsed() == true); + REQUIRE(b->isCollapsed() == true); + REQUIRE(c->isCollapsed() == false); + + REQUIRE(d->isCollapsed() == false); + REQUIRE(e->isCollapsed() == true); + REQUIRE(f->isCollapsed() == true); + + REQUIRE(g->isCollapsed() == false); + REQUIRE(h->isCollapsed() == true); + REQUIRE(i->isCollapsed() == true); +}