libgui 3.00
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& nudgeY(int n) { setNudgeY(n); return *this; }
53 GuiLabel& muted();
55 GuiLabel& accent();
58 GuiLabel& bind(std::function<std::string()> fn);
60 GuiLabel& visibleWhen(std::function<bool()> fn);
61 private:
62 UiScope& ui;
63};
64
67class GuiChip : public GuiOverlay
68{
69 public:
70 GuiChip(UiScope& scope, const char * text = "");
72 void setText(const char * t) { label.setText(t); }
74 GuiChip& bind(std::function<std::string()> fn);
75 GuiChip& visibleWhen(std::function<bool()> fn);
76 private:
77 UiScope& ui;
78 GuiShape backdrop;
79 GuiLabel label;
80};
81
87class GuiTextButton : public GuiButton
88{
89 public:
90 GuiTextButton(UiScope& scope, const char * text);
92 GuiTextButton& size(int w, int h);
94 GuiTextButton& fontSize(int px);
96 GuiTextButton& onClick(UiCallback fn);
98 GuiTextButton& onFocus(UiCallback fn);
100 GuiTextButton& style(const GuiShapeStyle& s);
102 GuiTextButton& rounded(float radius);
104 GuiTextButton& textNudge(int n) { text.setNudgeY(n); textLit.setNudgeY(n); return *this; }
106 GuiTextButton& litTextColor(PixelColor c) { textLit.textColor(c); return *this; }
108 GuiTextButton& disabled(bool d = true);
110 void setText(const char * t);
112 GuiTextButton& bind(std::function<std::string()> fn);
114 GuiTextButton& visibleWhen(std::function<bool()> fn);
116 GuiTextButton& enabledWhen(std::function<bool()> fn);
117
118 void update(InputController * c) override;
119 void setLayoutSize(int w, int h) override;
120 private:
121 UiScope& ui;
122 GuiShape shape;
123 GuiLabel text;
124 GuiLabel textLit;
125 UiCallback clickCb;
126 UiCallback focusCb;
127 bool wasSelected;
128};
129
132class GuiCardSurface : public GuiButton
133{
134 public:
135 GuiCardSurface();
136 void setLayoutSize(int w, int h) override;
137 GuiShape shape;
138};
139
145class GuiCard : public GuiOverlay
146{
147 public:
148 GuiCard(UiScope& scope);
150 GuiCard& onClick(UiCallback fn);
152 GuiCard& onFocus(UiCallback fn);
154 GuiCard& style(const GuiShapeStyle& s);
156 GuiCard& corners(const GuiCorners& c);
158 GuiCard& selectable(bool s);
160 GuiCard& disabled(bool d = true);
162 GuiCard& visibleWhen(std::function<bool()> fn);
164 void select() { surface.setState(STATE::SELECTED); }
166 void deselect() { surface.resetState(); }
168 bool isSelected() { const STATE s = surface.getState(); return s == STATE::SELECTED || s == STATE::HELD; }
170 GuiCard& enabledWhen(std::function<bool()> fn);
172 GuiCard& size(int w, int h) { setFixedSize(w, h); return *this; }
173 GuiCard& pad(float all) { setPadding(all); return *this; }
174 GuiCard& pad(float horizontal, float vertical) { setPadding(horizontal, vertical); return *this; }
175 GuiCard& add(GuiElement& e, const GuiItem& item = GuiItem()) { GuiLayout::add(&e, item); return *this; }
176 GuiCard& add(GuiElement * e, const GuiItem& item = GuiItem()) { GuiLayout::add(e, item); return *this; }
177
178 void update(InputController * c) override;
179 private:
180 UiScope& ui;
181 GuiCardSurface surface;
182 UiCallback clickCb;
183 UiCallback focusCb;
184 bool wasSelected;
185};
186
191class UiScope
192{
193 public:
194 UiScope();
195 ~UiScope();
196 UiScope(const UiScope&) = delete;
197 UiScope& operator=(const UiScope&) = delete;
198
201 template<class T, class... Args>
202 T& make(Args&&... args)
203 {
204 Held<T> * h = new Held<T>(std::forward<Args>(args)...);
205 holders.push_back(h);
206 h->value.setRemoveOnDestroy(true); // unhooks from its parent if destroyed first
207 return h->value;
208 }
210 template<class T, class... Args>
211 T& own(Args&&... args)
212 {
213 Held<T> * h = new Held<T>(std::forward<Args>(args)...);
214 holders.push_back(h);
215 return h->value;
216 }
217
218 GuiRow& row() { return make<GuiRow>(); }
219 GuiColumn& column() { return make<GuiColumn>(); }
220 GuiGrid& grid(int columns) { return make<GuiGrid>(columns); }
221 GuiOverlay& overlay() { return make<GuiOverlay>(); }
222 GuiLabel& label(const char * text = "") { return make<GuiLabel>(*this, text); }
223 GuiChip& chip(const char * text = "") { return make<GuiChip>(*this, text); }
224 GuiTextButton& button(const char * text) { return make<GuiTextButton>(*this, text); }
225 GuiCard& card() { return make<GuiCard>(*this); }
226 GuiGlyph& glyph(GLYPH kind, const char * letter = "") { return make<GuiGlyph>(kind, letter); }
227
229 void bind(UiCallback fn);
231 void visibleWhen(GuiElement& e, std::function<bool()> fn);
233 void enabledWhen(GuiElement& e, std::function<bool()> fn);
234
236 const GuiTheme& theme() const { return GuiTheme::current(); }
238 void setTrigger(GuiTrigger * t) { trig = t ? t : &primary; }
239 GuiTrigger * trigger() { return trig; }
241 void setSounds(GuiSound * over, GuiSound * click) { soundOver = over; soundClick = click; }
242 GuiSound * getSoundOver() { return soundOver; }
243 GuiSound * getSoundClick() { return soundClick; }
244
247 void attachTo(GuiWindow& window);
249 void runBindings();
250
251 private:
252 struct Holder { virtual ~Holder() {} };
253 template<class T>
254 struct Held : Holder
255 {
256 template<class... A> Held(A&&... a) : value(std::forward<A>(a)...) {}
257 T value;
258 };
259 class Runner;
260
261 std::vector<Holder*> holders;
262 std::vector<UiCallback> bindings;
263 GuiTrigger primary;
264 GuiTrigger * trig;
265 GuiSound * soundOver;
266 GuiSound * soundClick;
267 Runner * runner;
268};
Display, manage, and manipulate buttons in the GUI.
Definition GuiButton.h:13
Primary GUI class.
Definition GuiElement.h:62
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
STATE
Interaction state of a GuiElement (default, selected, clicked, held, disabled).
Definition GuiElement.h:37
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:21
static GuiTheme & current()
The theme the rest of the library reads. The first call fills it in with GuiThemeInit().
Definition GuiTheme.cpp:35
8-bit-per-channel RGBA color used by the video interfaces.
Definition Mesh.h:16