libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiLayoutSolver.h
1/****************************************************************************
2 * libgui
3 * Daryl Borth 2026
4 * GuiLayoutSolver.h
5 *
6 * Platform-agnostic layout math: given the natural sizes of some items and a
7 * few rules, work out where each one goes. The layout containers (GuiRow,
8 * GuiColumn, GuiGrid, GuiOverlay) are thin adapters that feed GuiElements to
9 * these functions and apply the answers. Everything here is plain numbers,
10 * so it is tested on a host machine.
11 *
12 * Coordinates are relative to the container's top-left corner.
13 ***************************************************************************/
14#pragma once
15#include <vector>
16#include "GuiGeometry.h"
17
20enum class LAYOUT_ALIGN {
22 CENTRE,
25};
26
35
38struct GuiInsets {
39 float left, top, right, bottom;
40 GuiInsets(float all = 0.0f) : left(all), top(all), right(all), bottom(all) {}
41 GuiInsets(float horizontal, float vertical) : left(horizontal), top(vertical), right(horizontal), bottom(vertical) {}
42 GuiInsets(float l, float t, float r, float b) : left(l), top(t), right(r), bottom(b) {}
43};
44
47struct GuiStackItem {
48 float w, h;
49 float grow;
52 GuiStackItem() : w(0), h(0), grow(0), useContainerAlign(true), align(LAYOUT_ALIGN::START) {}
53};
54
57struct GuiStackSpec {
58 bool vertical;
59 GuiInsets padding;
60 float spacing;
61 float fixedW, fixedH;
62 LAYOUT_JUSTIFY justify;
63 LAYOUT_ALIGN alignItems;
64 GuiStackSpec() : vertical(false), spacing(0), fixedW(0), fixedH(0), justify(LAYOUT_JUSTIFY::START), alignItems(LAYOUT_ALIGN::START) {}
65};
66
69struct GuiLayoutResult {
70 float width, height;
71 std::vector<GuiRect> rects;
72 GuiLayoutResult() : width(0), height(0) {}
73};
74
79GuiLayoutResult GuiSolveStack(const GuiStackSpec& spec, const std::vector<GuiStackItem>& items);
80
83struct GuiGridItem {
84 float w, h;
86 GuiGridItem() : w(0), h(0), alignH(LAYOUT_ALIGN::START), alignV(LAYOUT_ALIGN::START) {}
87};
88
91struct GuiGridSpec {
92 int columns;
93 GuiInsets padding;
94 float spacingX, spacingY;
95 float fixedW, fixedH;
96 GuiGridSpec() : columns(1), spacingX(0), spacingY(0), fixedW(0), fixedH(0) {}
97};
98
102GuiLayoutResult GuiSolveGrid(const GuiGridSpec& spec, const std::vector<GuiGridItem>& items);
103
106struct GuiOverlayItem {
107 float w, h;
108 LAYOUT_ALIGN alignH, alignV;
110 GuiOverlayItem() : w(0), h(0), alignH(LAYOUT_ALIGN::CENTRE), alignV(LAYOUT_ALIGN::CENTRE), background(false) {}
111};
112
115struct GuiOverlaySpec {
116 GuiInsets padding;
117 float fixedW, fixedH;
118 GuiOverlaySpec() : fixedW(0), fixedH(0) {}
119};
120
123GuiLayoutResult GuiSolveOverlay(const GuiOverlaySpec& spec, const std::vector<GuiOverlayItem>& items);
124
127enum class NAV_DIR { LEFT, RIGHT, UP, DOWN };
128
133 bool selectable;
134};
135
144int GuiNavigate(const std::vector<GuiNavItem>& items, int current, NAV_DIR dir);
@ UP
D-pad arrows: a circle with a triangle.
Definition GuiGlyph.h:20
NAV_DIR
Directions for moving the selection.
LAYOUT_ALIGN
How an item sits across the main direction of a stack, or inside a grid cell.
GuiLayoutResult GuiSolveGrid(const GuiGridSpec &spec, const std::vector< GuiGridItem > &items)
Lays items out in rows.
int GuiNavigate(const std::vector< GuiNavItem > &items, int current, NAV_DIR dir)
Picks which item the selection moves to.
GuiLayoutResult GuiSolveStack(const GuiStackSpec &spec, const std::vector< GuiStackItem > &items)
Lays items out along one axis.
GuiLayoutResult GuiSolveOverlay(const GuiOverlaySpec &spec, const std::vector< GuiOverlayItem > &items)
Stacks items on top of each other in one box.
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_BETWEEN
First item at the start, last at the end, equal gaps between.
LAYOUT_ALIGN alignV
Placement inside the cell.
Rules for a grid, filled row by row.
float fixedH
Container size; 0 = fit.
Space around the inside edge of a container.
The solver's answer: the container's size and each item's rectangle.
An item that selection can move between.
GuiRect r
On-screen rectangle.
bool background
Fills the whole box, ignores padding, and does not count toward the fit size.
Rules for an overlay: children share one box.
float fixedH
Container size; 0 = fit.
An axis-aligned rectangle (top-left origin) in design-canvas pixels.
Definition GuiGeometry.h:30
float h
Natural size (for a gap: its fixed size along the main axis).
float grow
Share of leftover main-axis space this item takes (0 = none).
bool useContainerAlign
true: use the stack's alignItems; false: use align.
LAYOUT_ALIGN align
Cross-axis alignment when not using the container's.
Rules for a row or column.
float spacing
Gap between neighbouring items.
bool vertical
true = column, false = row.
float fixedH
Container size; 0 = fit.