ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
widget.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <utility>
5
7
9 : visible(other.visible)
10 , enabled(other.enabled)
11 , focusable(other.focusable)
12 , nav_up(other.nav_up)
13 , nav_down(other.nav_down)
14 , nav_left(other.nav_left)
15 , nav_right(other.nav_right)
16 , focus_ring(other.focus_ring)
17 , transform(other.transform)
18 , anchor(other.anchor)
19 , anchor_margin(other.anchor_margin)
20 , _children(std::move(other._children))
21 , _id(generate_id())
22{
23 adopt_children();
24}
25
27{
28 if (this == &other) {
29 return *this;
30 }
31
32 visible = other.visible;
33 enabled = other.enabled;
34 focusable = other.focusable;
35 nav_up = other.nav_up;
36 nav_down = other.nav_down;
37 nav_left = other.nav_left;
38 nav_right = other.nav_right;
39 focus_ring = other.focus_ring;
40 transform = other.transform;
41 anchor = other.anchor;
42 anchor_margin = other.anchor_margin;
43
44 // Root may still point into the old children, keep them until it frees them
45 detach_children();
46 _children = std::move(other._children);
47
48 adopt_children();
49 return *this;
50}
51
53{
54 for (auto const& c : _children) {
55 c->parent = this;
56 }
57}
58
60{
61 for (auto& c : _children) {
62 c->parent = nullptr;
63 _removed.push_back(std::move(c));
64 }
65 _children.clear();
66}
67
69{
70 (void)ctx;
71}
72
74{
75 for (auto const& c : _children) {
76 c->measure(ctx);
77 if (c->anchor != Anchor::None) {
78 place_anchored(*c);
79 }
80 c->layout(ctx);
81 }
82}
83
85{
86 const auto& area = transform;
87 const auto& size = child.transform.size;
88 const auto& margin = child.anchor_margin;
89
90 // 0 start, 1 middle, 2 end of each axis
91 int col = 1;
92 int row = 1;
93 switch (child.anchor) {
94 case Anchor::TopLeft:
95 col = 0;
96 row = 0;
97 break;
98 case Anchor::Top:
99 row = 0;
100 break;
101 case Anchor::TopRight:
102 col = 2;
103 row = 0;
104 break;
105 case Anchor::Left:
106 col = 0;
107 break;
108 case Anchor::Right:
109 col = 2;
110 break;
112 col = 0;
113 row = 2;
114 break;
115 case Anchor::Bottom:
116 row = 2;
117 break;
119 col = 2;
120 row = 2;
121 break;
122 default:
123 break;
124 }
125
126 const auto along = [](int part, float start, float extent, float own, float gap) {
127 if (part == 0) {
128 return start + gap;
129 }
130 if (part == 2) {
131 return start + extent - own - gap;
132 }
133 return start + ((extent - own) / 2.0F);
134 };
135
136 child.transform.position = { along(col, area.position.x, area.size.x, size.x, margin.x),
137 along(row, area.position.y, area.size.y, size.y, margin.y) };
138}
139
141{
142 (void)ctx;
143 (void)e;
144 return false;
145}
146
148{
149 (void)ctx;
150 (void)focused;
151}
152
154{
155 (void)ctx;
156}
157
159{
160 return _pressed || _hovered || (_focused && ctx.show_focus);
161}
162
164{
165 for (auto const& c : _children) {
166 if (c->visible) {
167 c->draw(ctx);
168 }
169 }
170}
171
173{
174 const auto it = std::ranges::find_if(
175 _children, [&child](const std::unique_ptr<Widget>& c) { return c.get() == &child; });
176 if (it == _children.end()) {
177 return false;
178 }
179 (*it)->parent = nullptr;
180 _removed.push_back(std::move(*it));
181 _children.erase(it);
182 return true;
183}
184
186{
187 detach_children();
188}
Vec2< T > size
The size of the rectangle.
Definition geometry.h:728
Vec2< T > position
The position of the rectangle.
Definition geometry.h:725
Shared state for the UI system.
Definition context.h:97
bool show_focus
Whether focus is shown. Root turns it on for keyboard and controller navigation and off when the mous...
Definition context.h:115
Base class for all UI widgets.
Definition widget.h:43
asw::Quad< float > transform
The transform (position and size) of the widget.
Definition widget.h:192
void detach_children()
Definition widget.cpp:59
Widget & operator=(Widget &&other) noexcept
Move assignment operator. The children move over and point to this widget as their parent....
Definition widget.cpp:26
void adopt_children()
Definition widget.cpp:52
void place_anchored(Widget &child) const
Place a child that has an anchor inside this widget.
Definition widget.cpp:84
asw::Vec2< float > anchor_margin
Space between an anchored widget and the parent's edges.
Definition widget.h:201
virtual void on_focus_changed(Context &ctx, bool focused)
Called when focus state changes.
Definition widget.cpp:147
virtual void measure(Context &ctx)
Set this widget's own size, before its parent places it. Does nothing by default.
Definition widget.cpp:68
Anchor anchor
Pin this widget to a point of its parent, e.g. BottomRight for a corner button. The parent places it ...
Definition widget.h:198
virtual bool on_event(Context &ctx, const UIEvent &e)
Handle a UI event.
Definition widget.cpp:140
virtual void draw(Context &ctx)
Draw this widget and its children.
Definition widget.cpp:163
std::vector< std::unique_ptr< Widget > > _children
Definition widget.h:249
void clear_children()
Remove every child widget, destroyed as for remove_child.
Definition widget.cpp:185
bool is_highlighted(const Context &ctx) const
Whether to draw the hover look: hovered, pressed, or focused while focus is shown.
Definition widget.cpp:158
virtual void activate(Context &ctx)
Called when the widget is clicked, or activated with the keyboard or a controller while focused....
Definition widget.cpp:153
bool remove_child(const Widget &child)
Remove a child widget. It leaves the tree now and is destroyed at the next Root::update,...
Definition widget.cpp:172
virtual void layout(Context &ctx)
Lay out this widget and its children.
Definition widget.cpp:73
Widget()
Default constructor for Widget.
Definition widget.h:47
UI context and focus management for the ASW UI module.
Event structure for UI interactions.
Definition event.h:21
Base widget class for the ASW UI module.