From 5765956519f07aa6b0bbc213a2b89c32e22daaec Mon Sep 17 00:00:00 2001 From: horrifyingHorse Date: Fri, 27 Dec 2024 04:45:59 +0530 Subject: [PATCH] Modify selection requirement --- include/ftxui/dom/elements.hpp | 2 ++ include/ftxui/dom/requirement.hpp | 7 +------ src/ftxui/component/container.cpp | 8 ++++---- src/ftxui/dom/dbox.cpp | 6 +++--- src/ftxui/dom/flexbox.cpp | 7 ++++--- src/ftxui/dom/focus.cpp | 4 ++-- src/ftxui/dom/frame.cpp | 3 +-- src/ftxui/dom/gridbox.cpp | 7 ++++--- src/ftxui/dom/hbox.cpp | 14 +++++++++++--- src/ftxui/dom/vbox.cpp | 15 ++++++++++++--- 10 files changed, 44 insertions(+), 29 deletions(-) diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index fa16080e..8b5d9632 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -122,7 +122,9 @@ Decorator selectionStyle(std::function style); // --- Layout is // Horizontal, Vertical or stacked set of elements. Element hbox(Elements); +Element hbox(Elements, int); Element vbox(Elements); +Element vbox(Elements, int); Element dbox(Elements); Element flexbox(Elements, FlexboxConfig config = FlexboxConfig()); Element gridbox(std::vector lines); diff --git a/include/ftxui/dom/requirement.hpp b/include/ftxui/dom/requirement.hpp index 1b0a8842..cd3553c9 100644 --- a/include/ftxui/dom/requirement.hpp +++ b/include/ftxui/dom/requirement.hpp @@ -20,12 +20,7 @@ struct Requirement { int flex_shrink_y = 0; // Focus management to support the frame/focus/select element. - enum Selection { - NORMAL = 0, - SELECTED = 1, - FOCUSED = 2, - }; - Selection selection = NORMAL; + bool is_selected = false; Box selected_box; }; diff --git a/src/ftxui/component/container.cpp b/src/ftxui/component/container.cpp index 410bb9f5..49c212d7 100644 --- a/src/ftxui/component/container.cpp +++ b/src/ftxui/component/container.cpp @@ -107,7 +107,7 @@ class VerticalContainer : public ContainerBase { if (elements.empty()) { return text("Empty container") | reflect(box_); } - return vbox(std::move(elements)) | reflect(box_); + return vbox(std::move(elements), *selector_) | reflect(box_); } bool EventHandler(Event event) override { @@ -191,7 +191,7 @@ class HorizontalContainer : public ContainerBase { if (elements.empty()) { return text("Empty container"); } - return hbox(std::move(elements)); + return hbox(std::move(elements), *selector_); } bool EventHandler(Event event) override { @@ -334,7 +334,7 @@ Component Vertical(Components children) { /// children_2, /// children_3, /// children_4, -/// }); +/// }, &selected_children); /// ``` Component Vertical(Components children, int* selector) { return std::make_shared(std::move(children), selector); @@ -355,7 +355,7 @@ Component Vertical(Components children, int* selector) { /// children_2, /// children_3, /// children_4, -/// }, &selected_children); +/// }); /// ``` Component Horizontal(Components children) { return Horizontal(std::move(children), nullptr); diff --git a/src/ftxui/dom/dbox.cpp b/src/ftxui/dom/dbox.cpp index c6e752e7..39e352f7 100644 --- a/src/ftxui/dom/dbox.cpp +++ b/src/ftxui/dom/dbox.cpp @@ -27,7 +27,7 @@ class DBox : public Node { requirement_.flex_grow_y = 0; requirement_.flex_shrink_x = 0; requirement_.flex_shrink_y = 0; - requirement_.selection = Requirement::NORMAL; + requirement_.is_selected = false; for (auto& child : children_) { child->ComputeRequirement(); requirement_.min_x = @@ -35,8 +35,8 @@ class DBox : public Node { requirement_.min_y = std::max(requirement_.min_y, child->requirement().min_y); - if (requirement_.selection < child->requirement().selection) { - requirement_.selection = child->requirement().selection; + if (!requirement_.is_selected && child->requirement().is_selected) { + requirement_.is_selected = true; requirement_.selected_box = child->requirement().selected_box; } } diff --git a/src/ftxui/dom/flexbox.cpp b/src/ftxui/dom/flexbox.cpp index 336527b1..18a84968 100644 --- a/src/ftxui/dom/flexbox.cpp +++ b/src/ftxui/dom/flexbox.cpp @@ -104,7 +104,7 @@ class Flexbox : public Node { Layout(global, true); // Reset: - requirement_.selection = Requirement::Selection::NORMAL; + requirement_.is_selected = false; requirement_.selected_box = Box(); requirement_.min_x = 0; requirement_.min_y = 0; @@ -130,10 +130,11 @@ class Flexbox : public Node { // Find the selection: for (size_t i = 0; i < children_.size(); ++i) { - if (requirement_.selection >= children_[i]->requirement().selection) { + if (requirement_.is_selected || + !children_[i]->requirement().is_selected) { continue; } - requirement_.selection = children_[i]->requirement().selection; + requirement_.is_selected = true; Box selected_box = children_[i]->requirement().selected_box; // Shift |selected_box| according to its position inside this component: diff --git a/src/ftxui/dom/focus.cpp b/src/ftxui/dom/focus.cpp index b0d6cca4..809fac2f 100644 --- a/src/ftxui/dom/focus.cpp +++ b/src/ftxui/dom/focus.cpp @@ -36,7 +36,7 @@ Decorator focusPositionRelative(float x, float y) { void ComputeRequirement() override { NodeDecorator::ComputeRequirement(); - requirement_.selection = Requirement::Selection::NORMAL; + requirement_.is_selected = false; Box& box = requirement_.selected_box; box.x_min = int(float(requirement_.min_x) * x_); @@ -75,7 +75,7 @@ Decorator focusPosition(int x, int y) { void ComputeRequirement() override { NodeDecorator::ComputeRequirement(); - requirement_.selection = Requirement::Selection::NORMAL; + requirement_.is_selected = false; Box& box = requirement_.selected_box; box.x_min = x_; diff --git a/src/ftxui/dom/frame.cpp b/src/ftxui/dom/frame.cpp index 17619eed..0b9db190 100644 --- a/src/ftxui/dom/frame.cpp +++ b/src/ftxui/dom/frame.cpp @@ -27,7 +27,7 @@ class Select : public Node { selected_box.y_min = 0; selected_box.x_max = requirement_.min_x - 1; selected_box.y_max = requirement_.min_y - 1; - requirement_.selection = Requirement::SELECTED; + requirement_.is_selected = true; } void SetBox(Box box) override { @@ -42,7 +42,6 @@ class Focus : public Select { void ComputeRequirement() override { Select::ComputeRequirement(); - requirement_.selection = Requirement::FOCUSED; } void Render(Screen& screen) override { diff --git a/src/ftxui/dom/gridbox.cpp b/src/ftxui/dom/gridbox.cpp index ec8f1e6e..f02c461e 100644 --- a/src/ftxui/dom/gridbox.cpp +++ b/src/ftxui/dom/gridbox.cpp @@ -76,13 +76,14 @@ class GridBox : public Node { requirement_.min_y = Integrate(size_y); // Forward the selected/focused child state: - requirement_.selection = Requirement::NORMAL; + requirement_.is_selected = false; for (int x = 0; x < x_size; ++x) { for (int y = 0; y < y_size; ++y) { - if (requirement_.selection >= lines_[y][x]->requirement().selection) { + if (requirement_.is_selected || + !lines_[y][x]->requirement().is_selected) { continue; } - requirement_.selection = lines_[y][x]->requirement().selection; + requirement_.is_selected = true; requirement_.selected_box = lines_[y][x]->requirement().selected_box; requirement_.selected_box.x_min += size_x[x]; requirement_.selected_box.x_max += size_x[x]; diff --git a/src/ftxui/dom/hbox.cpp b/src/ftxui/dom/hbox.cpp index bc08b0fc..37bc6d21 100644 --- a/src/ftxui/dom/hbox.cpp +++ b/src/ftxui/dom/hbox.cpp @@ -19,7 +19,10 @@ namespace { class HBox : public Node { public: explicit HBox(Elements children) : Node(std::move(children)) {} + explicit HBox(Elements children, int index) + : Node(std::move(children)), index_(index) {} + private: void ComputeRequirement() override { requirement_.min_x = 0; requirement_.min_y = 0; @@ -27,11 +30,11 @@ class HBox : public Node { requirement_.flex_grow_y = 0; requirement_.flex_shrink_x = 0; requirement_.flex_shrink_y = 0; - requirement_.selection = Requirement::NORMAL; + requirement_.is_selected = false; for (auto& child : children_) { child->ComputeRequirement(); - if (requirement_.selection < child->requirement().selection) { - requirement_.selection = child->requirement().selection; + if (children_[index_] == child && child->requirement().is_selected) { + requirement_.is_selected = true; requirement_.selected_box = child->requirement().selected_box; requirement_.selected_box.x_min += requirement_.min_x; requirement_.selected_box.x_max += requirement_.min_x; @@ -77,6 +80,7 @@ class HBox : public Node { child->Select(selection_saturated); } } + int index_ = 0; }; } // namespace @@ -97,4 +101,8 @@ Element hbox(Elements children) { return std::make_shared(std::move(children)); } +Element hbox(Elements children, int index) { + return std::make_shared(std::move(children), index); +} + } // namespace ftxui diff --git a/src/ftxui/dom/vbox.cpp b/src/ftxui/dom/vbox.cpp index 27134568..743e655a 100644 --- a/src/ftxui/dom/vbox.cpp +++ b/src/ftxui/dom/vbox.cpp @@ -19,7 +19,10 @@ namespace { class VBox : public Node { public: explicit VBox(Elements children) : Node(std::move(children)) {} + explicit VBox(Elements children, int index) + : Node(std::move(children)), index_(index) {} + private: void ComputeRequirement() override { requirement_.min_x = 0; requirement_.min_y = 0; @@ -27,11 +30,11 @@ class VBox : public Node { requirement_.flex_grow_y = 0; requirement_.flex_shrink_x = 0; requirement_.flex_shrink_y = 0; - requirement_.selection = Requirement::NORMAL; + requirement_.is_selected = false; for (auto& child : children_) { child->ComputeRequirement(); - if (requirement_.selection < child->requirement().selection) { - requirement_.selection = child->requirement().selection; + if (children_[index_] == child && child->requirement().is_selected) { + requirement_.is_selected = true; requirement_.selected_box = child->requirement().selected_box; requirement_.selected_box.y_min += requirement_.min_y; requirement_.selected_box.y_max += requirement_.min_y; @@ -78,6 +81,8 @@ class VBox : public Node { child->Select(selection_saturated); } } + + int index_ = 0; }; } // namespace @@ -98,4 +103,8 @@ Element vbox(Elements children) { return std::make_shared(std::move(children)); } +Element vbox(Elements children, int index) { + return std::make_shared(std::move(children), index); +} + } // namespace ftxui