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);
+}