28 const size_t n = items.size();
29 out.rects.assign(n,
GuiRect{ 0, 0, 0, 0 });
32 const float padMainStart = v ? spec.padding.top : spec.padding.left;
33 const float padMainEnd = v ? spec.padding.bottom : spec.padding.right;
34 const float padCrossStart = v ? spec.padding.left : spec.padding.top;
35 const float padCrossEnd = v ? spec.padding.right : spec.padding.bottom;
36 const float fixedMain = v ? spec.
fixedH : spec.fixedW;
37 const float fixedCross = v ? spec.fixedW : spec.
fixedH;
39 float sumMain = 0.0f, maxCross = 0.0f, growSum = 0.0f;
40 for(
size_t i = 0; i < n; i++)
42 sumMain += v ? items[i].h : items[i].w;
43 maxCross = std::max(maxCross, v ? items[i].w : items[i].h);
44 growSum += std::max(items[i].grow, 0.0f);
47 sumMain += spec.
spacing * (float)(n - 1);
49 const float totalMain = fixedMain > 0.0f ? fixedMain : sumMain + padMainStart + padMainEnd;
50 const float totalCross = fixedCross > 0.0f ? fixedCross : maxCross + padCrossStart + padCrossEnd;
51 out.width = v ? totalCross : totalMain;
52 out.height = v ? totalMain : totalCross;
54 const float innerCross = std::max(0.0f, totalCross - padCrossStart - padCrossEnd);
55 float freeMain = totalMain - padMainStart - padMainEnd - sumMain;
57 float offset = 0.0f, extraGap = 0.0f;
58 std::vector<float> mainSize(n);
59 for(
size_t i = 0; i < n; i++)
60 mainSize[i] = v ? items[i].h : items[i].w;
66 for(
size_t i = 0; i < n; i++)
67 mainSize[i] += freeMain * std::max(items[i].grow, 0.0f) / growSum;
81 float pos = padMainStart + offset;
82 for(
size_t i = 0; i < n; i++)
84 const LAYOUT_ALIGN align = items[i].useContainerAlign ? spec.alignItems : items[i].align;
85 float cross = v ? items[i].w : items[i].h;
88 const float crossPos = placeAcross(align, padCrossStart, innerCross, cross);
91 if(v) { r.
x = crossPos; r.
y = pos; r.
w = cross; r.
h = mainSize[i]; }
92 else { r.
x = pos; r.
y = crossPos; r.
w = mainSize[i]; r.
h = cross; }
94 pos += mainSize[i] + spec.
spacing + extraGap;
102 const int cols = std::max(1, spec.columns);
103 const size_t n = items.size();
104 out.rects.assign(n,
GuiRect{ 0, 0, 0, 0 });
105 const int rows = n == 0 ? 0 : (int)((n + cols - 1) / cols);
107 std::vector<float> colW((
size_t)cols, 0.0f), rowH((
size_t)std::max(rows, 0), 0.0f);
108 for(
size_t i = 0; i < n; i++)
110 const size_t c = i % cols, r = i / cols;
111 colW[c] = std::max(colW[c], items[i].w);
112 rowH[r] = std::max(rowH[r], items[i].h);
115 const float padH = spec.padding.left + spec.padding.right;
116 const float padV = spec.padding.top + spec.padding.bottom;
117 if(spec.fixedW > 0.0f)
119 const float each = std::max(0.0f, (spec.fixedW - padH - spec.spacingX * (
float)(cols - 1)) / (
float)cols);
120 for(
int c = 0; c < cols; c++)
121 colW[(
size_t)c] = each;
124 float sumW = 0.0f, sumH = 0.0f;
125 for(
int c = 0; c < cols; c++)
126 sumW += colW[(
size_t)c];
127 for(
int r = 0; r < rows; r++)
128 sumH += rowH[(
size_t)r];
129 sumW += spec.spacingX * (float)(cols - 1);
131 sumH += spec.spacingY * (float)(rows - 1);
133 out.width = spec.fixedW > 0.0f ? spec.fixedW : sumW + padH;
134 out.height = spec.
fixedH > 0.0f ? spec.
fixedH : sumH + padV;
136 std::vector<float> colX((
size_t)cols), rowY((
size_t)std::max(rows, 0));
137 float x = spec.padding.left;
138 for(
int c = 0; c < cols; c++)
141 x += colW[(size_t)c] + spec.spacingX;
143 float y = spec.padding.top;
144 for(
int r = 0; r < rows; r++)
147 y += rowH[(size_t)r] + spec.spacingY;
150 for(
size_t i = 0; i < n; i++)
152 const size_t c = i % cols, r = i / cols;
156 rect.
x = placeAcross(items[i].alignH, colX[c], colW[c], w);
157 rect.
y = placeAcross(items[i].alignV, rowY[r], rowH[r], h);
168 const size_t n = items.size();
169 out.rects.assign(n,
GuiRect{ 0, 0, 0, 0 });
171 float maxW = 0.0f, maxH = 0.0f;
172 for(
size_t i = 0; i < n; i++)
174 if(items[i].background)
176 maxW = std::max(maxW, items[i].w);
177 maxH = std::max(maxH, items[i].h);
179 const float padH = spec.padding.left + spec.padding.right;
180 const float padV = spec.padding.top + spec.padding.bottom;
181 out.width = spec.fixedW > 0.0f ? spec.fixedW : maxW + padH;
182 out.height = spec.
fixedH > 0.0f ? spec.
fixedH : maxH + padV;
184 const float innerW = std::max(0.0f, out.width - padH);
185 const float innerH = std::max(0.0f, out.height - padV);
186 for(
size_t i = 0; i < n; i++)
188 if(items[i].background)
190 out.rects[i] =
GuiRect{ 0, 0, out.width, out.height };
195 out.rects[i] =
GuiRect{ placeAcross(items[i].alignH, spec.padding.left, innerW, w), placeAcross(items[i].alignV, spec.padding.top, innerH, h), w, h };
223 const int n = (int)items.size();
224 const bool horizontal = dir == NAV_DIR::LEFT || dir == NAV_DIR::RIGHT;
225 const float sign = (dir == NAV_DIR::RIGHT || dir == NAV_DIR::DOWN) ? 1.0f : -1.0f;
228 if(current < 0 || current >= n)
231 float bx = 0, by = 0;
232 for(
int i = 0; i < n; i++)
234 if(!items[i].selectable)
237 centreOf(items[i].r, cx, cy);
238 if(best < 0 || cy < by - 1.0f || (fabsf(cy - by) <= 1.0f && cx < bx))
249 centreOf(items[current].r, ccx, ccy);
250 const GuiRect& cur = items[current].r;
254 float bestScore = 0.0f;
255 for(
int i = 0; i < n; i++)
257 if(i == current || !items[i].selectable)
260 centreOf(items[i].r, cx, cy);
261 const float along = horizontal ? (cx - ccx) * sign : (cy - ccy) * sign;
265 const float ov = horizontal ? overlapOrGap(cur.
y, cur.
y + cur.
h, r.y, r.y + r.h) : overlapOrGap(cur.
x, cur.
x + cur.
w, r.x, r.x + r.w);
266 const float across = ov > 0.0f ? 0.0f : -ov;
267 const float offAxis = fabsf(horizontal ? cy - ccy : cx - ccx);
268 const float score = along + 4.0f * across + 0.01f * offAxis;
269 if(best < 0 || score < bestScore)
275 if(best >= 0 || !horizontal)
279 for(
int i = 0; i < n; i++)
281 if(i == current || !items[i].selectable)
284 centreOf(items[i].r, cx, cy);
285 const bool otherRow = sign > 0 ? (cy > cur.
y + cur.
h) : (cy < cur.
y);
294 centreOf(items[best].r, bx, by);
295 const bool closerRow = sign > 0 ? (cy < by - 1.0f) : (cy > by + 1.0f);
296 const bool sameRow = fabsf(cy - by) <= 1.0f;
297 const bool betterInRow = sign > 0 ? (cx < bx) : (cx > bx);
298 if(closerRow || (sameRow && betterInRow))