| #include "rive/nested_artboard.hpp" |
| #include "rive/artboard.hpp" |
| #include "rive/backboard.hpp" |
| #include "rive/importers/import_stack.hpp" |
| #include "rive/importers/backboard_importer.hpp" |
| #include "rive/nested_animation.hpp" |
| |
| using namespace rive; |
| |
| NestedArtboard::~NestedArtboard() |
| { |
| if (m_NestedInstance->isInstance()) |
| { |
| delete m_NestedInstance; |
| } |
| } |
| Core* NestedArtboard::clone() const |
| { |
| NestedArtboard* nestedArtboard = |
| static_cast<NestedArtboard*>(NestedArtboardBase::clone()); |
| if (m_NestedInstance == nullptr) |
| { |
| return nestedArtboard; |
| } |
| nestedArtboard->nest(m_NestedInstance->instance()); |
| return nestedArtboard; |
| } |
| |
| void NestedArtboard::nest(Artboard* artboard) |
| { |
| assert(artboard != nullptr); |
| m_NestedInstance = artboard; |
| m_NestedInstance->advance(0.0f); |
| } |
| |
| void NestedArtboard::draw(Renderer* renderer) |
| { |
| if (m_NestedInstance == nullptr) |
| { |
| return; |
| } |
| renderer->save(); |
| renderer->transform(worldTransform()); |
| Mat2D translation; |
| translation[4] = -m_NestedInstance->originX() * m_NestedInstance->width(); |
| translation[5] = -m_NestedInstance->originY() * m_NestedInstance->height(); |
| renderer->transform(translation); |
| m_NestedInstance->draw(renderer); |
| renderer->restore(); |
| } |
| |
| StatusCode NestedArtboard::import(ImportStack& importStack) |
| { |
| auto backboardImporter = |
| importStack.latest<BackboardImporter>(Backboard::typeKey); |
| if (backboardImporter == nullptr) |
| { |
| return StatusCode::MissingObject; |
| } |
| backboardImporter->addNestedArtboard(this); |
| |
| return Super::import(importStack); |
| } |
| |
| void NestedArtboard::addNestedAnimation(NestedAnimation* nestedAnimation) |
| { |
| m_NestedAnimations.push_back(nestedAnimation); |
| } |
| |
| StatusCode NestedArtboard::onAddedClean(CoreContext* context) |
| { |
| // N.B. The nested instance will be null here for the source artboards. |
| // Instances will have a nestedInstance available. This is a good thing as |
| // it ensures that we only instance animations in artboard instances. It |
| // does require that we always use an artboard instance (not just the source |
| // artboard) when working with nested artboards, but in general this is good |
| // practice for any loaded Rive file. |
| if (m_NestedInstance != nullptr) |
| { |
| for (auto animation : m_NestedAnimations) |
| { |
| animation->initializeAnimation(m_NestedInstance); |
| } |
| } |
| return Super::onAddedClean(context); |
| } |
| |
| bool NestedArtboard::advance(float elapsedSeconds) |
| { |
| if (m_NestedInstance == nullptr) |
| { |
| return false; |
| } |
| for (auto animation : m_NestedAnimations) |
| { |
| animation->advance(elapsedSeconds, m_NestedInstance); |
| } |
| return m_NestedInstance->advance(elapsedSeconds); |
| } |