| #include "rive/container_component.hpp" | |
| #include <algorithm> | |
| using namespace rive; | |
| void ContainerComponent::addChild(Component* component) | |
| { | |
| #ifdef WITH_RIVE_EDITOR | |
| // Editor build: dedupe. Journal replay re-fires `parentIdChanged` | |
| // (which calls addChild via the core_hook callback) AND walks the | |
| // recreated Core through `onAddedDirty` (which also calls addChild | |
| // in `Component::onAddedDirty`'s editor branch). Without dedupe | |
| // m_children ends up with two entries for the same Component → | |
| // hierarchy panel shows duplicates and `forEachChild` visits | |
| // twice. Runtime importer builds children in a single | |
| // monotonic pass and never double-adds, so the cost is editor- | |
| // only. | |
| if (std::find(m_children.begin(), m_children.end(), component) != | |
| m_children.end()) | |
| { | |
| return; | |
| } | |
| #endif | |
| m_children.push_back(component); | |
| } | |
| bool ContainerComponent::collapse(bool value) | |
| { | |
| if (!Super::collapse(value)) | |
| { | |
| return false; | |
| } | |
| for (Component* child : m_children) | |
| { | |
| child->collapse(value); | |
| } | |
| return true; | |
| } | |
| bool ContainerComponent::forAll(std::function<bool(Component*)> predicate) | |
| { | |
| if (!predicate(this)) | |
| { | |
| return false; | |
| } | |
| forEachChild(predicate); | |
| return true; | |
| } | |
| void ContainerComponent::forEachChild(std::function<bool(Component*)> predicate) | |
| { | |
| for (Component* child : m_children) | |
| { | |
| if (!predicate(child)) | |
| { | |
| continue; | |
| } | |
| if (child->is<ContainerComponent>()) | |
| { | |
| child->as<ContainerComponent>()->forEachChild(predicate); | |
| } | |
| } | |
| } |