feat: add nested text run getters and setters in Unity This PR introduces new methods to get and set text run values in nested artboards in Unity ### Unity - Added to `Artboard` class in Unity: - `GetTextRunValue(string runName)` - `SetTextRunValueAtPath(string runName, string path, string value)` - `GetTextRunValueAtPath(string runName, string path)` ### rive-cpp - Exposed in `Artboard` class: - `TextValueRun* getTextRun(const std::string& name) const;` Diffs= 55de8286c feat: add nested text run getters and setters in Unity (#7808) Co-authored-by: Adam <67035612+damzobridge@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index c15f5b7..27941d2 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -2c0927fc5e9a5c420305a81446ac41eb5b896b2c +55de8286c5ba680de950a3a0aac26e13bb890d6b
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 6c9df53..b054943 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp
@@ -408,6 +408,7 @@ SMIBool* getBool(const std::string& name, const std::string& path); SMINumber* getNumber(const std::string& name, const std::string& path); SMITrigger* getTrigger(const std::string& name, const std::string& path); + TextValueRun* getTextRun(const std::string& name, const std::string& path); }; } // namespace rive
diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 6457727..6b97708 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp
@@ -69,4 +69,4 @@ }; } // namespace rive -#endif +#endif \ No newline at end of file
diff --git a/src/artboard.cpp b/src/artboard.cpp index 67a5a1b..b0576d9 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp
@@ -1359,6 +1359,28 @@ return getNamedInput<SMITrigger>(name, path); } +TextValueRun* ArtboardInstance::getTextRun(const std::string& name, const std::string& path) +{ + if (path.empty()) + { + return nullptr; + } + + auto nestedArtboard = nestedArtboardAtPath(path); + if (nestedArtboard == nullptr) + { + return nullptr; + } + + auto artboardInstance = nestedArtboard->artboardInstance(); + if (artboardInstance == nullptr) + { + return nullptr; + } + + return artboardInstance->find<TextValueRun>(name); +} + #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp<AudioEngine> Artboard::audioEngine() const { return m_audioEngine; } void Artboard::audioEngine(rcp<AudioEngine> audioEngine)
diff --git a/test/assets/runtime_nested_text_runs.riv b/test/assets/runtime_nested_text_runs.riv new file mode 100644 index 0000000..b7535a0 --- /dev/null +++ b/test/assets/runtime_nested_text_runs.riv Binary files differ
diff --git a/test/nested_text_run_test.cpp b/test/nested_text_run_test.cpp new file mode 100644 index 0000000..f79a6e6 --- /dev/null +++ b/test/nested_text_run_test.cpp
@@ -0,0 +1,61 @@ +#include "rive/core/binary_reader.hpp" +#include "rive/file.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/text/text_value_run.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_input_instance.hpp" +#include "catch.hpp" +#include "rive_file_reader.hpp" +#include <cstdio> + +TEST_CASE("validate nested text get/set", "[nestedText]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_text_runs.riv"); + + auto artboard = file->artboard("ArtboardA")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting TextValueRun view nested artboard path one level deep + + auto textRunB1 = artboard->getTextRun("ArtboardBRun", "ArtboardB-1"); + REQUIRE(textRunB1->is<rive::TextValueRun>()); + REQUIRE(textRunB1->text() == "Artboard B Run"); + + auto textRunB2 = artboard->getTextRun("ArtboardBRun", "ArtboardB-2"); + REQUIRE(textRunB2->is<rive::TextValueRun>()); + REQUIRE(textRunB2->text() == "Artboard B Run"); + + // Test getting/setting TextValueRun view nested artboard path two level deep + + auto textRunB1C1 = artboard->getTextRun("ArtboardCRun", "ArtboardB-1/ArtboardC-1"); + REQUIRE(textRunB1C1->is<rive::TextValueRun>()); + REQUIRE(textRunB1C1->text() == "Artboard C Run"); + + auto textRunB1C2 = artboard->getTextRun("ArtboardCRun", "ArtboardB-1/ArtboardC-2"); + REQUIRE(textRunB1C2->is<rive::TextValueRun>()); + REQUIRE(textRunB1C2->text() == "Artboard C Run"); + + auto textRunB2C1 = artboard->getTextRun("ArtboardCRun", "ArtboardB-2/ArtboardC-1"); + REQUIRE(textRunB2C1->is<rive::TextValueRun>()); + REQUIRE(textRunB2C1->text() == "Artboard C Run"); + + auto textRunB2C2 = artboard->getTextRun("ArtboardCRun", "ArtboardB-2/ArtboardC-2"); + REQUIRE(textRunB2C2->is<rive::TextValueRun>()); + REQUIRE(textRunB2C2->text() == "Artboard C Run"); + + // Validate that text run values can be set + + textRunB1->text("Artboard B1 Run Updated"); + textRunB2->text("Artboard B2 Run Updated"); + textRunB1C1->text("Artboard B1C1 Run Updated"); + textRunB1C2->text("Artboard B1C2 Run Updated"); + textRunB2C1->text("Artboard B2C1 Run Updated"); + textRunB2C2->text("Artboard B2C2 Run Updated"); + REQUIRE(textRunB1->text() == "Artboard B1 Run Updated"); + REQUIRE(textRunB2->text() == "Artboard B2 Run Updated"); + REQUIRE(textRunB1C1->text() == "Artboard B1C1 Run Updated"); + REQUIRE(textRunB1C2->text() == "Artboard B1C2 Run Updated"); + REQUIRE(textRunB2C1->text() == "Artboard B2C1 Run Updated"); + REQUIRE(textRunB2C2->text() == "Artboard B2C2 Run Updated"); +} \ No newline at end of file