-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBox.cpp
More file actions
100 lines (93 loc) · 3.32 KB
/
Box.cpp
File metadata and controls
100 lines (93 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "Box.h"
#include <SDL3/SDL.h>
#include "TextManager.h"
#include <utility>
namespace UI
{
void Box::render(SDL_Renderer *renderer, TextManager *textManager, Context ctx)
{
auto roundingFunction = scrollForce.y >= 0 ? std::floorf : std::ceilf;
scrollForce.y = roundingFunction(scrollForce.y * 10) / 11.4f;
scrollForce.x += scrollForce.y;
SDL_FRect rectangle{
getBounds().x,
getBounds().y + ctx.offset.y + scrollForce.x,
getBounds().w,
getBounds().h};
SDL_SetRenderDrawColor(
renderer,
style.backgroundColor.x,
style.backgroundColor.y,
style.backgroundColor.z,
style.backgroundColor.w);
SDL_RenderFillRect(renderer, &rectangle);
ctx.offset.y += scrollForce.x;
ctx.offset.y += getBounds().y;
ctx.offset.x += getBounds().x;
for (auto &child : getChildren())
{
child->render(renderer, textManager, ctx);
}
};
/**
* Takes available space in a row and redistributes based
* on flex values.
*/
void Box::layoutChildrenEvenly(int i, int j, float availableWidth, float gap)
{
size_t rowChildrenCount = j - i;
float totalFlexGrow{0};
for (int k{i}; k < j; k++)
{
totalFlexGrow += children.at(k)->style.flex;
};
float spacePerChildren = gap / totalFlexGrow;
float x{};
for (int k{i}; k < j; k++)
{
auto &rowChild = children.at(k);
rowChild->setBounds({x,
rowChild->getBounds().y,
rowChild->getBounds().w + (spacePerChildren * rowChild->style.flex),
rowChild->getBounds().h});
x = rowChild->getBounds().x + rowChild->getBounds().w;
}
}
void Box::measure(TextManager *textManager, float availableWidth, float availableHeight)
{
float startingX{}, startingY{};
availableWidth -= style.paddingX * 2;
float x{startingX + style.paddingX}, y{startingY + style.paddingX};
float rowHeight{0}, totalHeight{0};
int begin{0};
setBounds({startingX, startingY, availableWidth, getBounds().h});
for (size_t i{0}; i < children.size(); i++)
{
auto &child = children.at(i);
child->measure(textManager, availableWidth, availableHeight);
if (x + child->getBounds().w > availableWidth)
{
Box::layoutChildrenEvenly(begin, i, availableWidth, availableWidth - x);
x = startingX;
y += rowHeight;
totalHeight += rowHeight;
rowHeight = 0;
begin = i;
}
rowHeight = std::max(rowHeight, child->getBounds().h);
child->setBounds({x,
y,
child->getBounds().w,
child->getBounds().h});
x += child->getBounds().w;
}
Box::layoutChildrenEvenly(begin, children.size(), availableWidth, availableWidth - x);
totalHeight += rowHeight;
setBounds({
startingX,
startingY,
getBounds().w,
totalHeight,
});
}
}