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