35class GridBox :
public Node {
37 explicit GridBox(std::vector<Elements> lines) : lines_(std::move(lines)) {
38 y_size =
static_cast<int>(lines_.size());
39 for (
const auto& line : lines_) {
40 x_size = std::max(x_size,
int(line.size()));
44 for (
auto& line : lines_) {
45 while (line.size() <
size_t(x_size)) {
51 void ComputeRequirement()
override {
52 requirement_.min_x = 0;
53 requirement_.min_y = 0;
54 requirement_.flex_grow_x = 0;
55 requirement_.flex_grow_y = 0;
56 requirement_.flex_shrink_x = 0;
57 requirement_.flex_shrink_y = 0;
59 for (
auto& line : lines_) {
60 for (
auto& cell : line) {
61 cell->ComputeRequirement();
66 std::vector<int> size_x(x_size, 0);
67 std::vector<int> size_y(y_size, 0);
68 for (
int x = 0; x < x_size; ++x) {
69 for (
int y = 0; y < y_size; ++y) {
70 size_x[x] = std::max(size_x[x], lines_[y][x]->requirement().min_x);
71 size_y[y] = std::max(size_y[y], lines_[y][x]->requirement().min_y);
75 requirement_.min_x = Integrate(size_x);
76 requirement_.min_y = Integrate(size_y);
79 requirement_.selection = Requirement::NORMAL;
80 for (
int x = 0; x < x_size; ++x) {
81 for (
int y = 0; y < y_size; ++y) {
82 if (requirement_.selection >= lines_[y][x]->requirement().selection) {
85 requirement_.selection = lines_[y][x]->requirement().selection;
86 requirement_.selected_box = lines_[y][x]->requirement().selected_box;
87 requirement_.selected_box.x_min += size_x[x];
88 requirement_.selected_box.x_max += size_x[x];
89 requirement_.selected_box.y_min += size_y[y];
90 requirement_.selected_box.y_max += size_y[y];
95 void SetBox(Box box)
override {
98 box_helper::Element init;
100 init.flex_grow = 1024;
101 init.flex_shrink = 1024;
102 std::vector<box_helper::Element> elements_x(x_size, init);
103 std::vector<box_helper::Element> elements_y(y_size, init);
105 for (
int y = 0; y < y_size; ++y) {
106 for (
int x = 0; x < x_size; ++x) {
107 const auto& cell = lines_[y][x];
108 const auto& requirement = cell->requirement();
109 auto& e_x = elements_x[x];
110 auto& e_y = elements_y[y];
111 e_x.min_size = std::max(e_x.min_size, requirement.min_x);
112 e_y.min_size = std::max(e_y.min_size, requirement.min_y);
113 e_x.flex_grow = std::min(e_x.flex_grow, requirement.flex_grow_x);
114 e_y.flex_grow = std::min(e_y.flex_grow, requirement.flex_grow_y);
115 e_x.flex_shrink = std::min(e_x.flex_shrink, requirement.flex_shrink_x);
116 e_y.flex_shrink = std::min(e_y.flex_shrink, requirement.flex_shrink_y);
120 const int target_size_x = box.x_max - box.x_min + 1;
121 const int target_size_y = box.y_max - box.y_min + 1;
122 box_helper::Compute(&elements_x, target_size_x);
123 box_helper::Compute(&elements_y, target_size_y);
127 for (
int iy = 0; iy < y_size; ++iy) {
129 y += elements_y[iy].size;
134 for (
int ix = 0; ix < x_size; ++ix) {
136 x += elements_x[ix].size;
138 lines_[iy][ix]->SetBox(box_x);
143 void Render(Screen& screen)
override {
144 for (
auto& line : lines_) {
145 for (
auto& cell : line) {
146 cell->Render(screen);
153 std::vector<Elements> lines_;
184 return std::make_shared<GridBox>(std::move(
lines));
std::shared_ptr< Node > Element
std::shared_ptr< T > Make(Args &&... args)
Element gridbox(std::vector< Elements > lines)
A container displaying a grid of elements.
Element filler()
An element that will take expand proportionally to the space left in a container.
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.