60 void SymmetryXY(
Global& g) {
64 std::swap(b.min_size_x, b.min_size_y);
65 std::swap(b.flex_grow_x, b.flex_grow_y);
66 std::swap(b.flex_shrink_x, b.flex_shrink_y);
68 std::swap(b.dim_x, b.dim_y);
72 void SymmetryX(
Global& g) {
75 b.x = g.
size_x - b.x - b.dim_x;
79 void SymmetryY(
Global& g) {
82 b.y = g.
size_y - b.y - b.dim_y;
87 std::vector<Block*> blocks;
90 void SetX(
Global& global, std::vector<Line> lines) {
91 for (
auto& line : lines) {
92 std::vector<box_helper::Element> elements;
93 elements.reserve(line.blocks.size());
94 for (
auto* block : line.blocks) {
96 element.
min_size = block->min_size_x;
103 elements.push_back(element);
111 for (
size_t i = 0; i < line.blocks.size(); ++i) {
112 line.blocks[i]->dim_x = elements[i].size;
113 line.blocks[i]->x = x;
114 x += elements[i].size;
121 void SetY(
Global& g, std::vector<Line> lines) {
122 std::vector<box_helper::Element> elements;
123 elements.reserve(lines.size());
124 for (
auto& line : lines) {
126 element.
flex_shrink = line.blocks.front()->flex_shrink_y;
127 element.
flex_grow = line.blocks.front()->flex_grow_y;
128 for (
auto* block : line.blocks) {
133 elements.push_back(element);
140 std::vector<int> ys(elements.size());
142 for (
size_t i = 0; i < elements.size(); ++i) {
144 y += elements[i].size;
147 int remaining_space = std::max(0, g.
size_y - y);
154 for (
size_t i = 0; i < ys.size(); ++i) {
155 ys[i] += remaining_space;
161 for (
size_t i = 0; i < ys.size(); ++i) {
162 ys[i] += remaining_space / 2;
168 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
169 const int shifted = remaining_space * (i + 0) / (i + 1);
171 const int consumed = remaining_space - shifted;
172 elements[i].size += consumed;
173 remaining_space -= consumed;
179 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 1; --i) {
180 ys[i] += remaining_space;
181 remaining_space = remaining_space * (i - 1) / i;
187 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
188 ys[i] += remaining_space * (2 * i + 1) / (2 * i + 2);
189 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
195 for (
int i =
static_cast<int>(ys.size()) - 1; i >= 0; --i) {
196 ys[i] += remaining_space * (i + 1) / (i + 2);
197 remaining_space = remaining_space * (i + 1) / (i + 2);
204 for (
size_t i = 0; i < lines.size(); ++i) {
205 auto& element = elements[i];
206 for (
auto* block : lines[i].blocks) {
208 block->flex_grow_y != 0 ||
211 stretch ? element.size : std::min(element.size, block->min_size_y);
220 block->y = ys[i] + (element.size -
size) / 2;
226 block->y = ys[i] + element.size -
size;
233 block->dim_y = element.size;
241 void JustifyContent(
Global& g, std::vector<Line> lines) {
242 for (
auto& line : lines) {
243 Block* last = line.blocks.back();
251 for (
auto* block : line.blocks) {
252 block->x += remaining_space;
258 for (
auto* block : line.blocks) {
259 block->x += remaining_space / 2;
265 for (
int i = (
int)line.blocks.size() - 1; i >= 1; --i) {
266 line.blocks[i]->x += remaining_space;
267 remaining_space = remaining_space * (i - 1) / i;
273 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
274 line.blocks[i]->x += remaining_space * (2 * i + 1) / (2 * i + 2);
275 remaining_space = remaining_space * (2 * i) / (2 * i + 2);
281 for (
int i = (
int)line.blocks.size() - 1; i >= 0; --i) {
282 line.blocks[i]->x += remaining_space * (i + 1) / (i + 2);
283 remaining_space = remaining_space * (i + 1) / (i + 2);
291 void Compute1(
Global& global);
292 void Compute2(
Global& global);
293 void Compute3(
Global& global);
295 void Compute1(
Global& global) {
305 void Compute2(
Global& global) {
315 void Compute3(
Global& global) {
317 std::vector<Line> lines;
321 line.blocks.reserve(global.
blocks.size());
322 for (
auto& block : global.
blocks) {
325 if (x + block.min_size_x > global.
size_x) {
327 if (!line.blocks.empty()) {
328 lines.push_back(std::move(line));
333 block.line = lines.size();
334 block.line_position = line.blocks.size();
335 line.blocks.push_back(&block);
338 if (!line.blocks.empty()) {
339 lines.push_back(std::move(line));
345 JustifyContent(global, lines);
void Compute(std::vector< Element > *elements, int target_size)
void Compute(Global &global)
std::vector< Block > blocks
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
AlignContent align_content
@ Center
items are centered along the cross axis.
@ FlexStart
items are placed at the start of the cross axis.
@ FlexEnd
items are placed at the end of the cross axis.
@ SpaceBetween
items are evenly distributed in the cross axis.
@ Stretch
items are stretched to fill the cross axis.
@ Column
Flex items are laid out in a column.
@ Row
Flex items are laid out in a row.
@ RowInversed
Flex items are laid out in a row, but in reverse order.
@ NoWrap
Flex items will all try to fit onto one line.
@ Wrap
Flex items will wrap onto multiple lines.
@ Center
items are centered along the cross axis.
@ FlexStart
items are placed at the start of the cross axis.
@ FlexEnd
items are placed at the end of the cross axis.
@ Stretch
items are stretched to fill the cross axis.
JustifyContent justify_content
@ Center
Items are centered along the line.
@ FlexStart
Items are aligned to the start of flexbox's direction.
@ FlexEnd
Items are aligned to the end of flexbox's direction.
@ SpaceBetween
Items are evenly distributed in the line; first item is on the start.
@ Stretch
Items are stretched to fill the line.