FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
box_helper.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
5
6#include <algorithm> // for max
7#include <cstdint>
8#include <vector> // for vector
9
11
12namespace {
13
14int SafeRatio(int value, int numerator, int denominator) {
15 return static_cast<int>(
16 static_cast<int64_t>(value) * static_cast<int64_t>(numerator) /
17 std::max(static_cast<int64_t>(denominator), static_cast<int64_t>(1)));
18}
19
20// Called when the size allowed is greater than the requested size. This
21// distributes the extra spaces toward the flexible elements, in relative
22// proportions.
23void ComputeGrow(std::vector<Element>* elements,
24 int extra_space,
25 int flex_grow_sum) {
26 for (Element& element : *elements) {
27 const int added_space =
28 SafeRatio(extra_space, element.flex_grow, flex_grow_sum);
29 extra_space -= added_space;
30 flex_grow_sum -= element.flex_grow;
31 element.size = element.min_size + added_space;
32 }
33}
34
35// Called when the size allowed is lower than the requested size, and the
36// shrinkable element can absorbe the (negative) extra_space. This distribute
37// the extra_space toward those.
38void ComputeShrinkEasy(std::vector<Element>* elements,
39 int extra_space,
40 int flex_shrink_sum) {
41 for (Element& element : *elements) {
42 const int added_space = SafeRatio(
43 extra_space, element.min_size * element.flex_shrink, flex_shrink_sum);
44 extra_space -= added_space;
45 flex_shrink_sum -= element.flex_shrink * element.min_size;
46 element.size = element.min_size + added_space;
47 }
48}
49
50// Called when the size allowed is lower than the requested size, and the
51// shrinkable element can not absorb the (negative) extra_space. This assigns
52// zero to shrinkable elements and distribute the remaining (negative)
53// extra_space toward the other non shrinkable elements.
54void ComputeShrinkHard(std::vector<Element>* elements,
55 int extra_space,
56 int size) {
57 for (Element& element : *elements) {
58 if (element.flex_shrink != 0) {
59 element.size = 0;
60 continue;
61 }
62
63 const int added_space = SafeRatio(extra_space, element.min_size, size);
64
65 extra_space -= added_space;
66 size -= element.min_size;
67
68 element.size = element.min_size + added_space;
69 }
70}
71
72} // namespace
73
74void Compute(std::vector<Element>* elements, int target_size) {
75 int size = 0;
76 int flex_grow_sum = 0;
77 int flex_shrink_sum = 0;
78 int flex_shrink_size = 0;
79
80 for (auto& element : *elements) {
81 flex_grow_sum += element.flex_grow;
82 flex_shrink_sum += element.min_size * element.flex_shrink;
83 if (element.flex_shrink != 0) {
84 flex_shrink_size += element.min_size;
85 }
86 size += element.min_size;
87 }
88
89 const int extra_space = target_size - size;
90 if (extra_space >= 0) {
91 ComputeGrow(elements, extra_space, flex_grow_sum);
92 } else if (flex_shrink_size + extra_space >= 0) {
93 ComputeShrinkEasy(elements, extra_space, flex_shrink_sum);
94
95 } else {
96 ComputeShrinkHard(elements, extra_space + flex_shrink_size,
97 size - flex_shrink_size);
98 }
99}
100
101} // namespace ftxui::box_helper
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
void Compute(std::vector< Element > *elements, int target_size)