libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiUi.h
1/****************************************************************************
2 * libgui
3 * Daryl Borth 2026
4 * GuiUi.h
5 *
6 * The builder layer. A UiScope creates and owns a page's elements, so a screen
7 * is built by describing it: no `new`, no `delete`, no helper structs holding
8 * the pieces. Widgets here (GuiLabel, GuiChip, GuiTextButton, GuiCard) take
9 * their look from GuiTheme, draw with no image assets, and report clicks and
10 * focus through callbacks. Text, visibility and enabled state can be bound to
11 * a function that is re-evaluated every frame.
12 *
13 * UiScope ui;
14 * ui.column().gap(8)
15 * .add(ui.label("Controllers").fontSize(28))
16 * .add(ui.card().onClick([&]{ OpenPlayer(1); })
17 * .add(ui.label().bind([&]{ return DeviceName(1); })));
18 * ui.attachTo(page);
19 *
20 * Everything the scope made is destroyed with it, children before parents
21 * or the other way round; the elements unhook themselves.
22 ***************************************************************************/
23#pragma once
24
27typedef std::function<void()> UiCallback;
28
32#if defined(__GNUC__)
33std::string GuiFormat(const char * fmt, ...) __attribute__((format(printf, 1, 2)));
34#else
35std::string GuiFormat(const char * fmt, ...);
36#endif
37
38class UiScope;
39
42class GuiLabel : public GuiText
43{
44 public:
45 GuiLabel(UiScope& scope, const char * text = "");
47 GuiLabel& fontSize(int px);
49 GuiLabel& textColor(PixelColor c);
51 GuiLabel& muted();
53 GuiLabel& accent();
56 GuiLabel& bind(std::function<std::string()> fn);
58 GuiLabel& visibleWhen(std::function<bool()> fn);
59 private:
60 UiScope& ui;
61};
62
65class GuiChip : public GuiOverlay
66{
67 public:
68 GuiChip(UiScope& scope, const char * text = "");
70 void setText(const char * t) { label.setText(t); }
72 GuiChip& bind(std::function<std::string()> fn);
73 GuiChip& visibleWhen(std::function<bool()> fn);
74 private:
75 UiScope& ui;
76 GuiShape backdrop;
77 GuiLabel label;
78};
79
85class GuiTextButton : public GuiButton
86{
87 public:
88 GuiTextButton(UiScope& scope, const char * text);
90 GuiTextButton& size(int w, int h);
92 GuiTextButton& fontSize(int px);
94 GuiTextButton& onClick(UiCallback fn);
96 GuiTextButton& onFocus(UiCallback fn);
98 GuiTextButton& style(const GuiShapeStyle& s);
100 GuiTextButton& rounded(float radius);
102 GuiTextButton& disabled(bool d = true);
104 void setText(const char * t);
106 GuiTextButton& bind(std::function<std::string()> fn);
108 GuiTextButton& visibleWhen(std::function<bool()> fn);
110 GuiTextButton& enabledWhen(std::function<bool()> fn);
111
112 void update(InputController * c) override;
113 void setLayoutSize(int w, int h) override;
114 private:
115 UiScope& ui;
116 GuiShape shape;
117 GuiLabel text;
118 GuiLabel textLit;
119 UiCallback clickCb;
120 UiCallback focusCb;
121 bool wasSelected;
122};
123
126class GuiCardSurface : public GuiButton
127{
128 public:
129 GuiCardSurface();
130 void setLayoutSize(int w, int h) override;
131 GuiShape shape;
132};
133
139class GuiCard : public GuiOverlay
140{
141 public:
142 GuiCard(UiScope& scope);
144 GuiCard& onClick(UiCallback fn);
146 GuiCard& onFocus(UiCallback fn);
148 GuiCard& style(const GuiShapeStyle& s);
150 GuiCard& corners(const GuiCorners& c);
152 GuiCard& selectable(bool s);
154 GuiCard& disabled(bool d = true);
156 GuiCard& visibleWhen(std::function<bool()> fn);
158 GuiCard& enabledWhen(std::function<bool()> fn);
160 GuiCard& size(int w, int h) { setFixedSize(w, h); return *this; }
161 GuiCard& pad(float all) { setPadding(all); return *this; }
162 GuiCard& pad(float horizontal, float vertical) { setPadding(horizontal, vertical); return *this; }
163 GuiCard& add(GuiElement& e, const GuiItem& item = GuiItem()) { GuiLayout::add(&e, item); return *this; }
164 GuiCard& add(GuiElement * e, const GuiItem& item = GuiItem()) { GuiLayout::add(e, item); return *this; }
165
166 void update(InputController * c) override;
167 private:
168 UiScope& ui;
169 GuiCardSurface surface;
170 UiCallback clickCb;
171 UiCallback focusCb;
172 bool wasSelected;
173};
174
179class UiScope
180{
181 public:
182 UiScope();
183 ~UiScope();
184 UiScope(const UiScope&) = delete;
185 UiScope& operator=(const UiScope&) = delete;
186
189 template<class T, class... Args>
190 T& make(Args&&... args)
191 {
192 Held<T> * h = new Held<T>(std::forward<Args>(args)...);
193 holders.push_back(h);
194 h->value.setRemoveOnDestroy(true); // unhooks from its parent if destroyed first
195 return h->value;
196 }
198 template<class T, class... Args>
199 T& own(Args&&... args)
200 {
201 Held<T> * h = new Held<T>(std::forward<Args>(args)...);
202 holders.push_back(h);
203 return h->value;
204 }
205
206 GuiRow& row() { return make<GuiRow>(); }
207 GuiColumn& column() { return make<GuiColumn>(); }
208 GuiGrid& grid(int columns) { return make<GuiGrid>(columns); }
209 GuiOverlay& overlay() { return make<GuiOverlay>(); }
210 GuiLabel& label(const char * text = "") { return make<GuiLabel>(*this, text); }
211 GuiChip& chip(const char * text = "") { return make<GuiChip>(*this, text); }
212 GuiTextButton& button(const char * text) { return make<GuiTextButton>(*this, text); }
213 GuiCard& card() { return make<GuiCard>(*this); }
214 GuiGlyph& glyph(GLYPH kind, const char * letter = "") { return make<GuiGlyph>(kind, letter); }
215 GuiControllerView& controllerView(const GuiControllerLayout& layout, float scale = 1.0f) { return make<GuiControllerView>(layout, scale); }
216
218 void bind(UiCallback fn);
220 void visibleWhen(GuiElement& e, std::function<bool()> fn);
222 void enabledWhen(GuiElement& e, std::function<bool()> fn);
223
225 const GuiTheme& theme() const { return GuiTheme::current(); }
227 void setTrigger(GuiTrigger * t) { trig = t ? t : &primary; }
228 GuiTrigger * trigger() { return trig; }
230 void setSounds(GuiSound * over, GuiSound * click) { soundOver = over; soundClick = click; }
231 GuiSound * getSoundOver() { return soundOver; }
232 GuiSound * getSoundClick() { return soundClick; }
233
236 void attachTo(GuiWindow& window);
238 void runBindings();
239
240 private:
241 struct Holder { virtual ~Holder() {} };
242 template<class T>
243 struct Held : Holder
244 {
245 template<class... A> Held(A&&... a) : value(std::forward<A>(a)...) {}
246 T value;
247 };
248 class Runner;
249
250 std::vector<Holder*> holders;
251 std::vector<UiCallback> bindings;
252 GuiTrigger primary;
253 GuiTrigger * trig;
254 GuiSound * soundOver;
255 GuiSound * soundClick;
256 Runner * runner;
257};
Display, manage, and manipulate buttons in the GUI.
Definition GuiButton.h:13
Primary GUI class.
Definition GuiElement.h:61
virtual void setLayoutSize(int w, int h)
Gives the element a size chosen by a container (default: sets width and height)
GuiLayout & add(GuiElement *e, const GuiItem &item=GuiItem())
Adds a child. Children are laid out in the order they are added.
Definition GuiLayout.cpp:21
Stacks children in one box, each aligned inside it (centered by default).
Definition GuiLayout.h:189
Display, manage, and manipulate text in the GUI.
Definition GuiText.h:10
void enabledWhen(GuiElement &e, std::function< bool()> fn)
Formats like printf and returns a std::string, for bound text: ui.label().bind([&]{ return GuiFormat(...
std::function< void()> UiCallback
A callback with no arguments.
Definition GuiUi.h:27
GLYPH
Small control icons for lists and hints (the "A" in a circle, a bumper, a D-pad arrow).
Definition GuiGlyph.h:17
Colors, metrics and the style recipes built from them.
Definition GuiTheme.h:16
static GuiTheme & current()
The theme the rest of the library reads. Starts as the default dark theme.
Definition GuiTheme.cpp:35
8-bit-per-channel RGBA color used by the video interfaces.
Definition Mesh.h:16