Reland "Factorize box layout functions. (#185)"" (#187)

This reverts commit a7095970bc.
This commit is contained in:
Arthur Sonzogni
2021-08-10 22:15:24 +02:00
committed by GitHub
parent 98f49a581c
commit 79b8928f6e
5 changed files with 141 additions and 166 deletions

View File

@@ -0,0 +1,85 @@
#include "ftxui/dom/box_helper.hpp"
namespace ftxui {
namespace box_helper {
namespace {
// Called when the size allowed is greater than the requested size. This
// distributes the extra spaces toward the flexible elements, in relative
// proportions.
void ComputeGrow(std::vector<Element>* elements,
int extra_space,
int flex_grow_sum) {
for (Element& element : *elements) {
int added_space =
extra_space * element.flex_grow / std::max(flex_grow_sum, 1);
extra_space -= added_space;
flex_grow_sum -= element.flex_grow;
element.size = element.min_size + added_space;
}
}
// Called when the size allowed is lower than the requested size, and the
// shrinkable element can absorbe the (negative) extra_space. This distribute
// the extra_space toward those.
void ComputeShrinkEasy(std::vector<Element>* elements,
int extra_space,
int flex_shrink_sum) {
for (Element& element : *elements) {
int added_space = extra_space * element.min_size * element.flex_shrink /
std::max(flex_shrink_sum, 1);
extra_space -= added_space;
flex_shrink_sum -= element.flex_shrink * element.min_size;
element.size = element.min_size + added_space;
}
}
// Called when the size allowed is lower than the requested size, and the
// shrinkable element can not absorbe the (negative) extra_space. This assign
// zero to shrinkable elements and distribute the remaining (negative)
// extra_space toward the other non shrinkable elements.
void ComputeShrinkHard(std::vector<Element>* elements,
int extra_space,
int size) {
for (Element& element : *elements) {
if (element.flex_shrink) {
element.size = 0;
continue;
}
int added_space = extra_space * element.min_size / std::max(1, size);
extra_space -= added_space;
size -= element.min_size;
element.size = element.min_size + added_space;
}
}
} // namespace
void Compute(std::vector<Element>* elements, int target_size) {
int size = 0;
int flex_grow_sum = 0;
int flex_shrink_sum = 0;
int flex_shrink_size = 0;
for (auto& element : *elements) {
flex_grow_sum += element.flex_grow;
flex_shrink_sum += element.min_size * element.flex_shrink;
if (element.flex_shrink)
flex_shrink_size += element.min_size;
size += element.min_size;
}
int extra_space = target_size - size;
if (extra_space >= 0)
ComputeGrow(elements, extra_space, flex_grow_sum);
else if (flex_shrink_size + extra_space >= 0)
ComputeShrinkEasy(elements, extra_space, flex_shrink_sum);
else
ComputeShrinkHard(elements, extra_space + flex_shrink_size,
size - flex_shrink_size);
}
} // namespace box_helper
} // namespace ftxui