Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
scene_group.hpp
Go to the documentation of this file.
1// SceneGroup — retained container node.
2//
3// Owns its children by value via `std::unique_ptr<SceneNode>`.
4// Mutation propagates upward via
5// `SceneNode::mark_dirty()`; the group's local_bounds() is the union
6// of its visible children's transformed local bounds.
7#pragma once
8
10
11#include <cstddef>
12#include <memory>
13#include <utility>
14#include <vector>
15
16namespace pulp::canvas {
17
18class SceneGroup : public SceneNode {
19public:
21
25 SceneNode* add_child(std::unique_ptr<SceneNode> child) {
26 if (!child) return nullptr;
27 child->parent_ = this;
28 SceneNode* raw = child.get();
29 children_.push_back(std::move(child));
30 mark_dirty();
31 return raw;
32 }
33
35 template <class T, class... Args>
36 T* emplace_child(Args&&... args) {
37 auto owned = std::make_unique<T>(std::forward<Args>(args)...);
38 T* raw = owned.get();
39 add_child(std::move(owned));
40 return raw;
41 }
42
44 bool remove_child(size_t index) {
45 if (index >= children_.size()) return false;
46 children_[index]->parent_ = nullptr;
47 children_.erase(children_.begin() + static_cast<long>(index));
48 mark_dirty();
49 return true;
50 }
51
53 bool remove_child(SceneNode* node) {
54 for (size_t i = 0; i < children_.size(); ++i) {
55 if (children_[i].get() == node) {
56 return remove_child(i);
57 }
58 }
59 return false;
60 }
61
62 size_t child_count() const { return children_.size(); }
63 SceneNode* child_at(size_t i) const {
64 return i < children_.size() ? children_[i].get() : nullptr;
65 }
66
67 const std::vector<std::unique_ptr<SceneNode>>& children() const {
68 return children_;
69 }
70
73 template <class Fn>
74 void for_each_descendant(Fn fn) const {
75 for (auto& c : children_) {
76 fn(*c);
77 if (c->kind() == SceneNodeKind::group) {
78 static_cast<SceneGroup*>(c.get())->for_each_descendant(fn);
79 }
80 }
81 }
82
83 // ── SceneNode overrides ──────────────────────────────────────────────
84 SceneRect local_bounds() const override;
85 void paint_geometry(Canvas& canvas) const override;
86
87private:
88 std::vector<std::unique_ptr<SceneNode>> children_;
89};
90
91} // namespace pulp::canvas
Definition canvas.hpp:240
bool remove_child(SceneNode *node)
Detach + destroy a child by raw pointer. Returns true on success.
Definition scene_group.hpp:53
bool remove_child(size_t index)
Detach + destroy a child by index. Returns true on success.
Definition scene_group.hpp:44
size_t child_count() const
Definition scene_group.hpp:62
SceneGroup()
Definition scene_group.hpp:20
SceneNode * add_child(std::unique_ptr< SceneNode > child)
Take ownership of child and re-parent it to this group.
Definition scene_group.hpp:25
void for_each_descendant(Fn fn) const
Walk the sub-tree depth-first, applying fn(node).
Definition scene_group.hpp:74
const std::vector< std::unique_ptr< SceneNode > > & children() const
Definition scene_group.hpp:67
SceneRect local_bounds() const override
Local-coordinate bounding box (pre-transform, pre-opacity).
T * emplace_child(Args &&... args)
Convenience for the common in-place construction case.
Definition scene_group.hpp:36
void paint_geometry(Canvas &canvas) const override
Paint this node (and its sub-tree) into canvas.
SceneNode * child_at(size_t i) const
Definition scene_group.hpp:63
void mark_dirty()
Mark this node and (recursively) every ancestor dirty.
SceneNode(SceneNodeKind kind)
Definition scene_node.hpp:108
Definition affine_transform.hpp:24
SceneNodeKind
Kind discriminator — keeps dynamic_cast off the hot path.
Definition scene_node.hpp:91
@ group
Definition scene_node.hpp:92
Axis-aligned bounding box used for repaint-rect math.
Definition scene_node.hpp:27