1 #ifndef _RIVE_ARTBOARD_HPP_
2 #define _RIVE_ARTBOARD_HPP_
4 #include "rive/animation/linear_animation.hpp"
5 #include "rive/animation/state_machine.hpp"
6 #include "rive/core_context.hpp"
7 #include "rive/generated/artboard_base.hpp"
8 #include "rive/hit_info.hpp"
9 #include "rive/math/aabb.hpp"
10 #include "rive/renderer.hpp"
11 #include "rive/shapes/shape_paint_container.hpp"
22 class ArtboardImporter;
24 class ArtboardInstance;
25 class LinearAnimationInstance;
27 class StateMachineInstance;
29 class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer {
31 friend class ArtboardImporter;
32 friend class Component;
35 std::vector<Core*> m_Objects;
36 std::vector<LinearAnimation*> m_Animations;
37 std::vector<StateMachine*> m_StateMachines;
38 std::vector<Component*> m_DependencyOrder;
39 std::vector<Drawable*> m_Drawables;
40 std::vector<DrawTarget*> m_DrawTargets;
41 std::vector<NestedArtboard*> m_NestedArtboards;
43 unsigned int m_DirtDepth = 0;
44 std::unique_ptr<CommandPath> m_BackgroundPath;
45 std::unique_ptr<CommandPath> m_ClipPath;
46 Factory* m_Factory = nullptr;
47 Drawable* m_FirstDrawable = nullptr;
48 bool m_IsInstance = false;
49 bool m_FrameOrigin = true;
51 void sortDependencies();
54 Artboard* getArtboard() override { return this; }
58 Artboard(Factory* factory) : m_Factory(factory) {}
60 void addObject(Core* object);
61 void addAnimation(LinearAnimation* object);
62 void addStateMachine(StateMachine* object);
63 void addNestedArtboard(NestedArtboard* object);
68 StatusCode initialize();
70 Core* resolve(uint32_t id) const override;
72 /// Find the id of a component in the artboard the object in the artboard. The artboard
73 /// itself has id 0 so we use that as a flag for not found.
74 uint32_t idOf(Core* object) const;
76 Factory* factory() const { return m_Factory; }
78 // EXPERIMENTAL -- for internal testing only for now.
79 // DO NOT RELY ON THIS as it may change/disappear in the future.
80 Core* hitTest(HitInfo*, const Mat2D* = nullptr);
82 void onComponentDirty(Component* component);
84 /// Update components that depend on each other in DAG order.
85 bool updateComponents();
86 void update(ComponentDirt value) override;
87 void onDirty(ComponentDirt dirt) override;
89 bool advance(double elapsedSeconds);
91 enum class DrawOption {
96 void draw(Renderer* renderer, DrawOption = DrawOption::kNormal);
98 CommandPath* clipPath() const { return m_ClipPath.get(); }
99 CommandPath* backgroundPath() const { return m_BackgroundPath.get(); }
101 const std::vector<Core*>& objects() const { return m_Objects; }
105 // Can we hide these from the public? (they use playable)
106 bool isTranslucent(const LinearAnimation*) const;
107 bool isTranslucent(const LinearAnimationInstance*) const;
109 template <typename T = Component> T* find(const std::string& name) {
110 for (auto object : m_Objects) {
111 if (object != nullptr && object->is<T>() && object->as<T>()->name() == name) {
112 return reinterpret_cast<T*>(object);
118 size_t animationCount() const { return m_Animations.size(); }
119 std::string animationNameAt(size_t index) const;
121 size_t stateMachineCount() const { return m_StateMachines.size(); }
122 std::string stateMachineNameAt(size_t index) const;
124 LinearAnimation* firstAnimation() const { return animation(0); }
125 LinearAnimation* animation(const std::string& name) const;
126 LinearAnimation* animation(size_t index) const;
128 StateMachine* firstStateMachine() const { return stateMachine(0); }
129 StateMachine* stateMachine(const std::string& name) const;
130 StateMachine* stateMachine(size_t index) const;
132 /// When provided, the designer has specified that this artboard should
133 /// always autoplay this StateMachine. Returns -1 if it was not
135 int defaultStateMachineIndex() const;
137 /// Make an instance of this artboard, must be explictly deleted when no
140 std::unique_ptr<ArtboardInstance> instance() const;
142 /// Returns true if the artboard is an instance of another
143 bool isInstance() const { return m_IsInstance; }
145 /// Returns true when the artboard will shift the origin from the top
146 /// left to the relative width/height of the artboard itself. This is
147 /// what the editor does visually when you change the origin value to
148 /// give context as to where the origin lies within the framed bounds.
149 bool frameOrigin() const { return m_FrameOrigin; }
150 /// When composing multiple artboards together in a common world-space,
151 /// it may be desireable to have them share the same space regardless of
152 /// origin offset from the bounding artboard. Set frameOrigin to false
153 /// to move the bounds relative to the origin instead of the origin
154 /// relative to the bounds.
155 void frameOrigin(bool value);
157 StatusCode import(ImportStack& importStack) override;
160 class ArtboardInstance : public Artboard {
162 ArtboardInstance() {}
164 std::unique_ptr<LinearAnimationInstance> animationAt(size_t index);
165 std::unique_ptr<LinearAnimationInstance> animationNamed(const std::string& name);
167 std::unique_ptr<StateMachineInstance> stateMachineAt(size_t index);
168 std::unique_ptr<StateMachineInstance> stateMachineNamed(const std::string& name);
170 /// When provided, the designer has specified that this artboard should
171 /// always autoplay this StateMachine instance. If it was not specified,
172 /// this returns nullptr.
173 std::unique_ptr<StateMachineInstance> defaultStateMachine();
175 // This attemps to always return *something*, in this search order:
176 // 1. default statemachine instance
177 // 2. first statemachine instance
178 // 3. first animation instance
180 std::unique_ptr<Scene> defaultScene();