mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-12-16 01:48:56 +08:00
Factorize box layout functions. (#185)
|hbox| and |vbox| are similar. They are just the same component, but drawing in a different direction. This patchs factorize the layout logic. Goal is to reduce code size and reuse it for the |gridbox| dom element. Bug: https://github.com/ArthurSonzogni/FTXUI/issues/114
This commit is contained in:
85
src/ftxui/dom/box_helper.cpp
Normal file
85
src/ftxui/dom/box_helper.cpp
Normal 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
|
||||
Reference in New Issue
Block a user