mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-22 18:59:59 +08:00
Fix: Forward gridbox
selected box. (#408)
This was discovered in: https://github.com/ArthurSonzogni/FTXUI/issues/407
This commit is contained in:
parent
219daf46ff
commit
ed5b4cec49
@ -7,6 +7,9 @@ current (development)
|
|||||||
### DOM
|
### DOM
|
||||||
- Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
|
- Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
|
||||||
`flexbox`
|
`flexbox`
|
||||||
|
- Bugfix: Fix the selected/focused area. It used to be 1 cell larger/longer than
|
||||||
|
requested
|
||||||
|
- Bugfix: Forward the selected/focused area from the child in gridbox.
|
||||||
|
|
||||||
### Screen
|
### Screen
|
||||||
- Feature: add `Box::Union(a,b) -> Box`
|
- Feature: add `Box::Union(a,b) -> Box`
|
||||||
|
@ -449,9 +449,9 @@ TEST(FlexboxTest, Focus) {
|
|||||||
Screen screen(1, 3);
|
Screen screen(1, 3);
|
||||||
Render(screen, document);
|
Render(screen, document);
|
||||||
EXPECT_EQ(screen.ToString(),
|
EXPECT_EQ(screen.ToString(),
|
||||||
"7\r\n"
|
|
||||||
"-\r\n"
|
"-\r\n"
|
||||||
"8"
|
"7\r\n"
|
||||||
|
"-"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ class Select : public Node {
|
|||||||
auto& selected_box = requirement_.selected_box;
|
auto& selected_box = requirement_.selected_box;
|
||||||
selected_box.x_min = 0;
|
selected_box.x_min = 0;
|
||||||
selected_box.y_min = 0;
|
selected_box.y_min = 0;
|
||||||
selected_box.x_max = requirement_.min_x;
|
selected_box.x_max = requirement_.min_x - 1;
|
||||||
selected_box.y_max = requirement_.min_y;
|
selected_box.y_max = requirement_.min_y - 1;
|
||||||
requirement_.selection = Requirement::SELECTED;
|
requirement_.selection = Requirement::SELECTED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,6 +13,23 @@
|
|||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
class Screen;
|
class Screen;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Accumulate the values of a list U[n] into v[n]. So that:
|
||||||
|
// V[0] = 0;
|
||||||
|
// V[n+1] = v[n] + U[n]
|
||||||
|
// return the sum of U[n].
|
||||||
|
int Integrate(std::vector<int>& elements) {
|
||||||
|
int accu = 0;
|
||||||
|
for (auto& i : elements) {
|
||||||
|
int old_accu = accu;
|
||||||
|
accu += i;
|
||||||
|
i = old_accu;
|
||||||
|
}
|
||||||
|
return accu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GridBox : public Node {
|
class GridBox : public Node {
|
||||||
public:
|
public:
|
||||||
explicit GridBox(std::vector<Elements> lines) : lines_(std::move(lines)) {
|
explicit GridBox(std::vector<Elements> lines) : lines_(std::move(lines)) {
|
||||||
@ -38,35 +55,37 @@ class GridBox : public Node {
|
|||||||
for (auto& line : lines_) {
|
for (auto& line : lines_) {
|
||||||
for (auto& cell : line) {
|
for (auto& cell : line) {
|
||||||
cell->ComputeRequirement();
|
cell->ComputeRequirement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine focus based on the focused child.
|
// Compute the size of each columns/row.
|
||||||
if (requirement_.selection >= cell->requirement().selection) {
|
std::vector<int> size_x(x_size, 0);
|
||||||
|
std::vector<int> size_y(y_size, 0);
|
||||||
|
for (int x = 0; x < x_size; ++x) {
|
||||||
|
for (int y = 0; y < y_size; ++y) {
|
||||||
|
size_x[x] = std::max(size_x[x], lines_[y][x]->requirement().min_x);
|
||||||
|
size_y[y] = std::max(size_y[y], lines_[y][x]->requirement().min_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirement_.min_x = Integrate(size_x);
|
||||||
|
requirement_.min_y = Integrate(size_y);
|
||||||
|
|
||||||
|
// Forward the selected/focused child state:
|
||||||
|
requirement_.selection = Requirement::NORMAL;
|
||||||
|
for (int x = 0; x < x_size; ++x) {
|
||||||
|
for (int y = 0; y < y_size; ++y) {
|
||||||
|
if (requirement_.selection >= lines_[y][x]->requirement().selection) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
requirement_.selection = cell->requirement().selection;
|
requirement_.selection = lines_[y][x]->requirement().selection;
|
||||||
requirement_.selected_box = cell->requirement().selected_box;
|
requirement_.selected_box = lines_[y][x]->requirement().selected_box;
|
||||||
requirement_.selected_box.x_min += requirement_.min_x;
|
requirement_.selected_box.x_min += size_x[x];
|
||||||
requirement_.selected_box.x_max += requirement_.min_x;
|
requirement_.selected_box.x_max += size_x[x];
|
||||||
|
requirement_.selected_box.y_min += size_y[y];
|
||||||
|
requirement_.selected_box.y_max += size_y[y];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work on the x-axis.
|
|
||||||
for (int x = 0; x < x_size; ++x) {
|
|
||||||
int min_x = 0;
|
|
||||||
for (int y = 0; y < y_size; ++y) {
|
|
||||||
min_x = std::max(min_x, lines_[y][x]->requirement().min_x);
|
|
||||||
}
|
|
||||||
requirement_.min_x += min_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Work on the y-axis.
|
|
||||||
for (int y = 0; y < y_size; ++y) {
|
|
||||||
int min_y = 0;
|
|
||||||
for (int x = 0; x < x_size; ++x) {
|
|
||||||
min_y = std::max(min_y, lines_[y][x]->requirement().min_y);
|
|
||||||
}
|
|
||||||
requirement_.min_y += min_y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBox(Box box) override {
|
void SetBox(Box box) override {
|
||||||
|
@ -596,6 +596,25 @@ TEST(GridboxTest, MissingCells) {
|
|||||||
" ");
|
" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GridboxTest, Focus) {
|
||||||
|
auto root = gridbox({
|
||||||
|
{cell("1"), cell("2"), cell("3"), cell("4")},
|
||||||
|
{cell("5"), cell("6"), cell("7"), cell("8")},
|
||||||
|
{cell("9"), cell("10"), cell("11"), cell("12")},
|
||||||
|
{cell("13"), cell("14") | focus, cell("15"), cell("16")},
|
||||||
|
{cell("17"), cell("18"), cell("19"), cell("20")},
|
||||||
|
});
|
||||||
|
|
||||||
|
root |= frame;
|
||||||
|
|
||||||
|
Screen screen(4, 3);
|
||||||
|
Render(screen, root);
|
||||||
|
EXPECT_EQ(screen.ToString(),
|
||||||
|
"╭──╮\r\n"
|
||||||
|
"│14│\r\n"
|
||||||
|
"╰──╯");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
|
||||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||||
|
Loading…
Reference in New Issue
Block a user