| #ifndef _RIVE_PARENT_TRAVERSAL_HPP_ |
| #define _RIVE_PARENT_TRAVERSAL_HPP_ |
| |
| namespace rive |
| { |
| class Artboard; |
| class ArtboardHost; |
| class ArtboardInstance; |
| class Component; |
| class ContainerComponent; |
| |
| /// Helper class for traversing up the parent hierarchy, automatically |
| /// crossing artboard boundaries when needed (e.g., from a nested artboard |
| /// to its parent artboard via ArtboardHost). |
| /// |
| /// Usage: |
| /// ParentTraversal traversal(startComponent); |
| /// while (auto* parent = traversal.next()) |
| /// { |
| /// // Process parent... |
| /// } |
| /// |
| /// For traversals that need to know when artboard boundaries are crossed |
| /// (e.g., to transform coordinates), check didCrossBoundary() after each |
| /// next() call. When true, crossingHost() and sourceArtboard() provide |
| /// the information needed to transform between artboard spaces. |
| class ParentTraversal |
| { |
| public: |
| /// Start traversal from the given component. |
| /// The first call to next() will return the component's parent. |
| /// The component's artboard is used to detect when we need to |
| /// cross artboard boundaries. |
| ParentTraversal(Component* start); |
| |
| /// Move to the next parent in the hierarchy, crossing artboard |
| /// boundaries when needed. Returns the next parent, or nullptr |
| /// when the traversal is complete. |
| ContainerComponent* next(); |
| |
| /// Returns the artboard context for the current position in the traversal. |
| /// This changes when crossing artboard boundaries. |
| Artboard* currentArtboard() const { return m_currentArtboard; } |
| |
| /// Returns true if the last call to next() crossed an artboard boundary. |
| bool didCrossBoundary() const { return m_didCrossBoundary; } |
| |
| /// When didCrossBoundary() is true, returns the ArtboardHost that was |
| /// used to cross the boundary. Use this with sourceArtboard() to get |
| /// the world transform for coordinate conversions. |
| ArtboardHost* crossingHost() const { return m_crossingHost; } |
| |
| /// When didCrossBoundary() is true, returns the artboard we crossed FROM. |
| /// Cast to ArtboardInstance if needed for worldTransformForArtboard(). |
| Artboard* sourceArtboard() const { return m_sourceArtboard; } |
| |
| private: |
| ContainerComponent* m_current; |
| Artboard* m_currentArtboard; |
| |
| // Boundary crossing state (valid after next() that crosses a boundary) |
| bool m_didCrossBoundary = false; |
| ArtboardHost* m_crossingHost = nullptr; |
| Artboard* m_sourceArtboard = nullptr; |
| }; |
| |
| } // namespace rive |
| |
| #endif |