diff --git a/include/rive/viewmodel/runtime/viewmodel_runtime.hpp b/include/rive/viewmodel/runtime/viewmodel_runtime.hpp index a0435bfb3..08cddb31b 100644 --- a/include/rive/viewmodel/runtime/viewmodel_runtime.hpp +++ b/include/rive/viewmodel/runtime/viewmodel_runtime.hpp @@ -17,6 +17,7 @@ struct PropertyData DataType type; std::string name; std::string enumName; + std::string viewModelName; }; class ViewModelRuntime : public RefCnt @@ -34,8 +35,7 @@ class ViewModelRuntime : public RefCnt rcp createDefaultInstance() const; rcp createInstance() const; std::vector properties(); - static std::vector buildPropertiesData( - std::vector& properties); + static std::vector buildPropertiesData(ViewModel* viewModel); std::vector instanceNames() const; private: diff --git a/include/rive/viewmodel/viewmodel.hpp b/include/rive/viewmodel/viewmodel.hpp index cea2cc6dd..b0df138bc 100644 --- a/include/rive/viewmodel/viewmodel.hpp +++ b/include/rive/viewmodel/viewmodel.hpp @@ -28,9 +28,7 @@ class ViewModel : public ViewModelBase, public RefCnt rcp createInstance(); rcp createFromInstance(const std::string& instanceName); void file(File* value) { m_file = value; }; -#ifdef WITH_RIVE_TOOLS - File* file() { return m_file; }; -#endif + File* file() const { return m_file; }; ViewModelInstance* defaultInstance(); size_t instanceCount() const; std::vector properties() { return m_Properties; } diff --git a/src/viewmodel/runtime/viewmodel_instance_runtime.cpp b/src/viewmodel/runtime/viewmodel_instance_runtime.cpp index 01e58b742..3c62b7938 100644 --- a/src/viewmodel/runtime/viewmodel_instance_runtime.cpp +++ b/src/viewmodel/runtime/viewmodel_instance_runtime.cpp @@ -424,7 +424,6 @@ bool ViewModelInstanceRuntime::replaceViewModelByName( std::vector ViewModelInstanceRuntime::properties() const { - std::vector props; - auto properties = m_viewModelInstance->viewModel()->properties(); - return ViewModelRuntime::buildPropertiesData(properties); + return ViewModelRuntime::buildPropertiesData( + m_viewModelInstance->viewModel()); } \ No newline at end of file diff --git a/src/viewmodel/runtime/viewmodel_runtime.cpp b/src/viewmodel/runtime/viewmodel_runtime.cpp index f111ae0b2..5414bc72e 100644 --- a/src/viewmodel/runtime/viewmodel_runtime.cpp +++ b/src/viewmodel/runtime/viewmodel_runtime.cpp @@ -41,13 +41,15 @@ const std::string& ViewModelRuntime::name() const } std::vector ViewModelRuntime::buildPropertiesData( - std::vector& properties) + ViewModel* viewModel) { + auto* file = viewModel->file(); std::vector props; - for (auto property : properties) + for (auto property : viewModel->properties()) { DataType type = DataType::none; std::string enumName; + std::string viewModelName; switch (property->coreType()) { case ViewModelPropertyString::typeKey: @@ -82,8 +84,20 @@ std::vector ViewModelRuntime::buildPropertiesData( type = DataType::trigger; break; case ViewModelPropertyViewModelBase::typeKey: + { type = DataType::viewModel; + if (file != nullptr) + { + auto* referencedViewModel = file->viewModel( + static_cast(property) + ->viewModelReferenceId()); + if (referencedViewModel != nullptr) + { + viewModelName = referencedViewModel->name(); + } + } break; + } case ViewModelPropertySymbolListIndex::typeKey: type = DataType::symbolListIndex; break; @@ -99,15 +113,14 @@ std::vector ViewModelRuntime::buildPropertiesData( default: break; } - props.push_back({type, property->name(), enumName}); + props.push_back({type, property->name(), enumName, viewModelName}); } return props; } std::vector ViewModelRuntime::properties() { - auto props = m_viewModel->properties(); - return buildPropertiesData(props); + return buildPropertiesData(m_viewModel); } std::vector ViewModelRuntime::instanceNames() const diff --git a/tests/unit_tests/runtime/data_binding_test.cpp b/tests/unit_tests/runtime/data_binding_test.cpp index 9e4c8f3b8..d115a4ea7 100644 --- a/tests/unit_tests/runtime/data_binding_test.cpp +++ b/tests/unit_tests/runtime/data_binding_test.cpp @@ -1497,6 +1497,23 @@ TEST_CASE("View model runtime properties", "[data binding]") REQUIRE(numData != properties.end()); REQUIRE(numData->type == rive::DataType::number); REQUIRE(numData->enumName.empty()); + REQUIRE(numData->viewModelName.empty()); + + // View model properties expose the name of the view model they reference, + // both from an instance and from the view model runtime itself. + auto chiData = findProperty("chi"); + REQUIRE(chiData != properties.end()); + REQUIRE(chiData->type == rive::DataType::viewModel); + REQUIRE(chiData->viewModelName == "child"); + + auto viewModelProperties = vm->properties(); + auto chiViewModelData = std::find_if(viewModelProperties.begin(), + viewModelProperties.end(), + [](const rive::PropertyData& data) { + return data.name == "chi"; + }); + REQUIRE(chiViewModelData != viewModelProperties.end()); + REQUIRE(chiViewModelData->viewModelName == "child"); } TEST_CASE("Trigger fires single change on listener", "[data binding]")