libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiLayout.h
1/****************************************************************************
2 * libgui
3 * Daryl Borth 2026
4 * GuiLayout.h
5 *
6 * Layout containers: GuiRow, GuiColumn, GuiGrid and GuiOverlay. They are
7 * GuiWindows that position and size their children from rules instead of
8 * pixel offsets. Drawing, input, focus and triggers are the ordinary GuiWindow
9 * ones; a container only decides where its children go. The D-pad moves the
10 * selection through nested containers by on-screen position.
11 *
12 * Sizes are in design-canvas pixels. A container's width or height of 0 means
13 * "fit the content" on that axis. Layout re-runs by itself when a child's size,
14 * visibility or the container's rules change, so a label whose text changes
15 * simply reflows.
16 ***************************************************************************/
17#pragma once
18
22struct GuiItem {
23 float growWeight;
24 bool hasAlignH;
25 bool hasAlignV;
26 LAYOUT_ALIGN alignH;
27 LAYOUT_ALIGN alignV;
28 bool isBackground;
29
30 GuiItem() : growWeight(0), hasAlignH(false), hasAlignV(false),
31 alignH(LAYOUT_ALIGN::START), alignV(LAYOUT_ALIGN::START), isBackground(false) {}
32
35 GuiItem& grow(float weight = 1.0f) { growWeight = weight; return *this; }
37 GuiItem& stretch() { return at(LAYOUT_ALIGN::STRETCH, LAYOUT_ALIGN::STRETCH); }
39 GuiItem& alignStart() { return at(LAYOUT_ALIGN::START, LAYOUT_ALIGN::START); }
41 GuiItem& alignCentre() { return at(LAYOUT_ALIGN::CENTRE, LAYOUT_ALIGN::CENTRE); }
43 GuiItem& alignEnd() { return at(LAYOUT_ALIGN::END, LAYOUT_ALIGN::END); }
46 GuiItem& at(LAYOUT_ALIGN h, LAYOUT_ALIGN v) { alignH = h; alignV = v; hasAlignH = hasAlignV = true; return *this; }
49 GuiItem& background() { isBackground = true; return *this; }
50};
51
54class GuiLayout : public GuiWindow
55{
56 public:
60 GuiLayout& add(GuiElement* e, const GuiItem& item = GuiItem());
63 GuiLayout& add(GuiElement& e, const GuiItem& item = GuiItem()) { return add(&e, item); }
65 GuiLayout& addGap(float size);
68 GuiLayout& addSpace(float weight = 1.0f);
70 GuiLayout& setPadding(float all);
71 GuiLayout& setPadding(float horizontal, float vertical);
72 GuiLayout& setPadding(float left, float top, float right, float bottom);
74 GuiLayout& setSpacing(float s);
75 GuiLayout& setSpacing(float x, float y);
81 GuiLayout& setFixedSize(int w, int h);
84 GuiLayout& size(int w, int h) { return setFixedSize(w, h); }
85 GuiLayout& gap(float s) { return setSpacing(s); }
86 GuiLayout& gap(float x, float y) { return setSpacing(x, y); }
87 GuiLayout& pad(float all) { return setPadding(all); }
88 GuiLayout& pad(float horizontal, float vertical) { return setPadding(horizontal, vertical); }
89 GuiLayout& pad(float left, float top, float right, float bottom) { return setPadding(left, top, right, bottom); }
90 GuiLayout& align(LAYOUT_ALIGN a) { return setAlignItems(a); }
91 GuiLayout& justifyContent(LAYOUT_JUSTIFY j) { return setJustify(j); }
93 void invalidate();
95 void clear();
96
97 void remove(GuiElement* e) override;
98 void layout() override;
99 void draw() override;
100 void update(InputController * c) override;
101 void getNaturalSize(int& w, int& h) override;
102 void setLayoutSize(int w, int h) override;
103 void collectNavigable(std::vector<GuiElement*>& out) override;
104
105 protected:
107 struct Entry {
109 GuiItem item;
110 float gapSize;
111 int natW, natH;
112 int baseW, baseH;
113 int assignedW, assignedH;
114 bool haveAssigned;
115 int lastW, lastH;
116 bool lastVisible;
117 Entry() : e(nullptr), gapSize(0), natW(0), natH(0), baseW(0), baseH(0), assignedW(0), assignedH(0),
118 haveAssigned(false), lastW(-1), lastH(-1), lastVisible(true) {}
119 };
120
121 GuiLayout();
126 virtual GuiLayoutResult solve(const std::vector<Entry*>& visible, float fixedW, float fixedH) = 0;
127
128 GuiInsets padding;
129 float spacingX;
130 float spacingY;
131 LAYOUT_JUSTIFY justify;
132 LAYOUT_ALIGN alignItems;
133
134 private:
135 void syncEntries();
136
137 std::vector<Entry> entries;
138 std::vector<Entry*> visibleScratch;
139 int userFixedW, userFixedH;
140 int assignedW, assignedH;
141 int naturalW, naturalH;
142 bool dirty;
143 bool settled;
144};
145
148class GuiRow : public GuiLayout
149{
150 public:
153 GuiRow(int w = 0, int h = 0);
154 protected:
155 GuiLayoutResult solve(const std::vector<Entry*>& visible, float fixedW, float fixedH) override;
156};
157
160class GuiColumn : public GuiLayout
161{
162 public:
165 GuiColumn(int w = 0, int h = 0);
166 protected:
167 GuiLayoutResult solve(const std::vector<Entry*>& visible, float fixedW, float fixedH) override;
168};
169
172class GuiGrid : public GuiLayout
173{
174 public:
178 GuiGrid(int columns, int w = 0, int h = 0);
179 protected:
180 GuiLayoutResult solve(const std::vector<Entry*>& visible, float fixedW, float fixedH) override;
181 private:
182 int columns;
183};
184
188class GuiOverlay : public GuiLayout
189{
190 public:
193 GuiOverlay(int w = 0, int h = 0);
194 protected:
195 GuiLayoutResult solve(const std::vector<Entry*>& visible, float fixedW, float fixedH) override;
196};
GuiColumn(int w=0, int h=0)
GuiLayoutResult solve(const std::vector< Entry * > &visible, float fixedW, float fixedH) override
Works out the container size and each visible entry's rectangle (what a subclass does)
GuiElement()
Constructor.
Definition GuiElement.cpp:9
bool visible
Visibility of the element.
Definition GuiElement.h:296
GuiLayoutResult solve(const std::vector< Entry * > &visible, float fixedW, float fixedH) override
Works out the container size and each visible entry's rectangle (what a subclass does)
GuiGrid(int columns, int w=0, int h=0)
Base of the layout containers. Not used directly; see GuiRow, GuiColumn, GuiGrid, GuiOverlay.
Definition GuiLayout.h:55
void clear()
Removes every child.
void remove(GuiElement *e) override
Removes the specified child.
GuiLayout & add(GuiElement &e, const GuiItem &item=GuiItem())
Adds a child by reference, so a builder can pass it straight in: row.add(ui.label("Hi"))
Definition GuiLayout.h:63
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
void collectNavigable(std::vector< GuiElement * > &out) override
Appends the elements that selection can move between (default: this element; layout containers add th...
GuiLayout & size(int w, int h)
Short names for the setters above, for reading a layout top to bottom: ui.row().size(568,...
Definition GuiLayout.h:84
void layout() override
Brings the element's own layout up to date.
GuiLayout & addSpace(float weight=1.0f)
Adds flexible empty space that takes a share of what is left over, for example to push one child to e...
Definition GuiLayout.cpp:44
GuiLayout & setFixedSize(int w, int h)
Fixes the container's size (0 on an axis = fit the content)
Definition GuiLayout.cpp:97
GuiLayout & setSpacing(float s)
Sets the gap between neighbouring children (a grid uses both numbers)
Definition GuiLayout.cpp:70
void getNaturalSize(int &w, int &h) override
Layout protocol: how a layout container (GuiRow, GuiColumn, GuiGrid, GuiOverlay) asks about and arran...
GuiLayout & setAlignItems(LAYOUT_ALIGN a)
Sets the default alignment of children across the main axis.
Definition GuiLayout.cpp:90
void update(InputController *c) override
Called constantly to allow the element to respond to the current input data.
void draw() override
Called constantly to redraw the element.
void invalidate()
Forces layout to run again.
GuiLayout & addGap(float size)
Adds a fixed gap along a row's width or a column's height.
Definition GuiLayout.cpp:35
GuiLayout & setPadding(float all)
Sets the space between the container's edge and its children.
Definition GuiLayout.cpp:53
virtual GuiLayoutResult solve(const std::vector< Entry * > &visible, float fixedW, float fixedH)=0
Works out the container size and each visible entry's rectangle (what a subclass does)
GuiLayout & setJustify(LAYOUT_JUSTIFY j)
Sets how leftover space along the main axis is spent when no child grows.
Definition GuiLayout.cpp:83
void setLayoutSize(int w, int h) override
Gives the element a size chosen by a container (default: sets width and height)
GuiOverlay(int w=0, int h=0)
GuiLayoutResult solve(const std::vector< Entry * > &visible, float fixedW, float fixedH) override
Works out the container size and each visible entry's rectangle (what a subclass does)
GuiLayoutResult solve(const std::vector< Entry * > &visible, float fixedW, float fixedH) override
Works out the container size and each visible entry's rectangle (what a subclass does)
GuiRow(int w=0, int h=0)
GuiWindow()
Constructor.
Definition GuiWindow.cpp:9
bool hasAlignH
Per-child options passed to GuiLayout::add().
Definition GuiLayout.h:24
LAYOUT_ALIGN
How an item sits across the main direction of a stack, or inside a grid cell.
LAYOUT_JUSTIFY
How leftover space along a stack's main direction is spent (when no item grows).
@ STRETCH
Fills the available space.
@ CENTRE
Centered.
@ START
Top or left.
@ END
Bottom or right.
Space around the inside edge of a container.
The solver's answer: the container's size and each item's rectangle.
int natH
Natural size, as measured this pass.
Definition GuiLayout.h:111
int baseH
Natural size before layout resized it.
Definition GuiLayout.h:112
int assignedH
Size layout last gave it.
Definition GuiLayout.h:113
float gapSize
Fixed size of a gap.
Definition GuiLayout.h:110
int lastH
Natural size at the last layout, to spot changes.
Definition GuiLayout.h:115
GuiElement * e
The child; null for a gap or flexible space.
Definition GuiLayout.h:108