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.h
Go to the documentation of this file.
1
8
9#ifndef ASW_MODULES_UI_WIDGET_H
10#define ASW_MODULES_UI_WIDGET_H
11
12#include <memory>
13#include <type_traits>
14#include <vector>
15
16#include "event.h"
17
18namespace asw::ui {
19
20class Context;
21
24enum class Anchor {
25 None,
26 TopLeft,
27 Top,
29 Left,
30 Center,
31 Right,
33 Bottom,
35};
36
39using WidgetId = uint32_t;
40
43class Widget {
44public:
48 : _id(generate_id()) { };
49
52 virtual ~Widget() = default;
53
59 Widget(Widget&& other) noexcept;
60
66 Widget& operator=(Widget&& other) noexcept;
67
68 Widget(const Widget&) = delete;
69 Widget& operator=(const Widget&) = delete;
70
75 WidgetId id() const
76 {
77 return _id;
78 }
79
81 bool visible = true;
82
84 bool enabled = true;
85
88 bool focusable = false;
89
91 Widget* nav_up = nullptr;
92
94 Widget* nav_down = nullptr;
95
97 Widget* nav_left = nullptr;
98
100 Widget* nav_right = nullptr;
101
104 bool focus_ring = true;
105
107 Widget* parent = nullptr;
108
115 const std::vector<std::unique_ptr<Widget>>& children() const
116 {
117 return _children;
118 }
119
125 virtual void measure(Context& ctx);
126
131 virtual void layout(Context& ctx);
132
139 virtual bool on_event(Context& ctx, const UIEvent& e);
140
146 virtual void on_focus_changed(Context& ctx, bool focused);
147
153 virtual void activate(Context& ctx);
154
159 virtual void draw(Context& ctx);
160
168 template <class T, class... Args> T& add_child(Args&&... args)
169 {
170 static_assert(std::is_base_of_v<Widget, T>, "add_child<T>: T must derive from Widget");
171 auto ptr = std::make_unique<T>(std::forward<Args>(args)...);
172 ptr->parent = this;
173 auto& ref = *ptr;
174 _children.emplace_back(std::move(ptr));
175 return ref;
176 }
177
185 bool remove_child(const Widget& child);
186
189 void clear_children();
190
193
199
202
204 bool is_hovered() const { return _hovered; }
205
207 bool is_pressed() const { return _pressed; }
208
210 bool is_focused() const { return _focused; }
211
214 bool is_captured() const { return _captured; }
215
222 bool is_highlighted(const Context& ctx) const;
223
224protected:
225 // Set by Root and FocusManager
226 friend class Root;
227 friend class FocusManager;
228
233 void place_anchored(Widget& child) const;
234
235 bool _hovered = false;
236 bool _pressed = false;
237 bool _focused = false;
238 bool _captured = false;
239
240private:
241 // Point every child at this widget as its parent
242 void adopt_children();
243
244 // Move every child to _removed
245 void detach_children();
246
247 // Child widgets, private so only add_child, remove_child and
248 // clear_children change them
249 std::vector<std::unique_ptr<Widget>> _children;
250
251 // Children removed from the tree, kept alive until Root frees them
252 std::vector<std::unique_ptr<Widget>> _removed;
253
254 static inline int _id_counter { 1 };
255
256 static int generate_id()
257 {
258 return _id_counter++;
259 }
260
262};
263
264} // namespace asw::ui
265
266#endif // ASW_MODULES_UI_WIDGET_H
A 2D rectangle in space.
Definition geometry.h:504
A 2D vector in space.
Definition geometry.h:27
Shared state for the UI system.
Definition context.h:97
Manages focus navigation for UI widgets.
Definition context.h:23
Root container that manages the UI tree, input, and rendering.
Definition root.h:49
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 * nav_up
Widget to focus on up, instead of the nearest one. Optional.
Definition widget.h:91
static int _id_counter
Definition widget.h:254
static int generate_id()
Definition widget.h:256
Widget(const Widget &)=delete
Widget & operator=(Widget &&other) noexcept
Move assignment operator. The children move over and point to this widget as their parent....
Definition widget.cpp:26
Widget * nav_right
Widget to focus on right, instead of the nearest one. Optional.
Definition widget.h:100
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
const std::vector< std::unique_ptr< Widget > > & children() const
Get the child widgets. Change them with add_child, remove_child and clear_children,...
Definition widget.h:115
bool is_pressed() const
Whether this widget is currently being pressed.
Definition widget.h:207
asw::Vec2< float > anchor_margin
Space between an anchored widget and the parent's edges.
Definition widget.h:201
bool is_hovered() const
Whether the pointer is currently over this widget.
Definition widget.h:204
virtual void on_focus_changed(Context &ctx, bool focused)
Called when focus state changes.
Definition widget.cpp:147
bool is_focused() const
Whether this widget currently holds focus.
Definition widget.h:210
virtual void measure(Context &ctx)
Set this widget's own size, before its parent places it. Does nothing by default.
Definition widget.cpp:68
bool enabled
Whether the widget is enabled.
Definition widget.h:84
virtual ~Widget()=default
Default virtual destructor.
T & add_child(Args &&... args)
Add a child widget.
Definition widget.h:168
WidgetId id() const
Get the unique identifier for this widget.
Definition widget.h:75
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
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
Widget & operator=(const Widget &)=delete
bool focus_ring
Draw the theme focus ring around this widget while it has visible focus. Turn off for widgets that sh...
Definition widget.h:104
bool is_captured() const
Whether this widget was pressed and the pointer is still held, even if it has moved off the widget.
Definition widget.h:214
Widget * nav_left
Widget to focus on left, instead of the nearest one. Optional.
Definition widget.h:97
bool focusable
Whether the widget can receive focus. Focusable widgets are also the ones the pointer can press.
Definition widget.h:88
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
bool visible
Whether the widget is visible.
Definition widget.h:81
virtual void layout(Context &ctx)
Lay out this widget and its children.
Definition widget.cpp:73
Widget * parent
Pointer to the parent widget.
Definition widget.h:107
Widget * nav_down
Widget to focus on down, instead of the nearest one. Optional.
Definition widget.h:94
Widget()
Default constructor for Widget.
Definition widget.h:47
WidgetId _id
Definition widget.h:261
std::vector< std::unique_ptr< Widget > > _removed
Definition widget.h:252
UI event types for the ASW UI module.
Anchor
A point of the parent an anchored widget sits at, see Widget::anchor.
Definition widget.h:24
uint32_t WidgetId
Unique identifier type for widgets.
Definition widget.h:39
Event structure for UI interactions.
Definition event.h:21