Modify selection requirement

This commit is contained in:
horrifyingHorse 2024-12-27 04:45:59 +05:30 committed by ArthurSonzogni
parent 8519e9b0f3
commit 5765956519
No known key found for this signature in database
GPG Key ID: 41D98248C074CD6C
10 changed files with 44 additions and 29 deletions

View File

@ -122,7 +122,9 @@ Decorator selectionStyle(std::function<void(Pixel&)> style);
// --- Layout is // --- Layout is
// Horizontal, Vertical or stacked set of elements. // Horizontal, Vertical or stacked set of elements.
Element hbox(Elements); Element hbox(Elements);
Element hbox(Elements, int);
Element vbox(Elements); Element vbox(Elements);
Element vbox(Elements, int);
Element dbox(Elements); Element dbox(Elements);
Element flexbox(Elements, FlexboxConfig config = FlexboxConfig()); Element flexbox(Elements, FlexboxConfig config = FlexboxConfig());
Element gridbox(std::vector<Elements> lines); Element gridbox(std::vector<Elements> lines);

View File

@ -20,12 +20,7 @@ struct Requirement {
int flex_shrink_y = 0; int flex_shrink_y = 0;
// Focus management to support the frame/focus/select element. // Focus management to support the frame/focus/select element.
enum Selection { bool is_selected = false;
NORMAL = 0,
SELECTED = 1,
FOCUSED = 2,
};
Selection selection = NORMAL;
Box selected_box; Box selected_box;
}; };

View File

@ -107,7 +107,7 @@ class VerticalContainer : public ContainerBase {
if (elements.empty()) { if (elements.empty()) {
return text("Empty container") | reflect(box_); 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 { bool EventHandler(Event event) override {
@ -191,7 +191,7 @@ class HorizontalContainer : public ContainerBase {
if (elements.empty()) { if (elements.empty()) {
return text("Empty container"); return text("Empty container");
} }
return hbox(std::move(elements)); return hbox(std::move(elements), *selector_);
} }
bool EventHandler(Event event) override { bool EventHandler(Event event) override {
@ -334,7 +334,7 @@ Component Vertical(Components children) {
/// children_2, /// children_2,
/// children_3, /// children_3,
/// children_4, /// children_4,
/// }); /// }, &selected_children);
/// ``` /// ```
Component Vertical(Components children, int* selector) { Component Vertical(Components children, int* selector) {
return std::make_shared<VerticalContainer>(std::move(children), selector); return std::make_shared<VerticalContainer>(std::move(children), selector);
@ -355,7 +355,7 @@ Component Vertical(Components children, int* selector) {
/// children_2, /// children_2,
/// children_3, /// children_3,
/// children_4, /// children_4,
/// }, &selected_children); /// });
/// ``` /// ```
Component Horizontal(Components children) { Component Horizontal(Components children) {
return Horizontal(std::move(children), nullptr); return Horizontal(std::move(children), nullptr);

View File

@ -27,7 +27,7 @@ class DBox : public Node {
requirement_.flex_grow_y = 0; requirement_.flex_grow_y = 0;
requirement_.flex_shrink_x = 0; requirement_.flex_shrink_x = 0;
requirement_.flex_shrink_y = 0; requirement_.flex_shrink_y = 0;
requirement_.selection = Requirement::NORMAL; requirement_.is_selected = false;
for (auto& child : children_) { for (auto& child : children_) {
child->ComputeRequirement(); child->ComputeRequirement();
requirement_.min_x = requirement_.min_x =
@ -35,8 +35,8 @@ class DBox : public Node {
requirement_.min_y = requirement_.min_y =
std::max(requirement_.min_y, child->requirement().min_y); std::max(requirement_.min_y, child->requirement().min_y);
if (requirement_.selection < child->requirement().selection) { if (!requirement_.is_selected && child->requirement().is_selected) {
requirement_.selection = child->requirement().selection; requirement_.is_selected = true;
requirement_.selected_box = child->requirement().selected_box; requirement_.selected_box = child->requirement().selected_box;
} }
} }

View File

@ -104,7 +104,7 @@ class Flexbox : public Node {
Layout(global, true); Layout(global, true);
// Reset: // Reset:
requirement_.selection = Requirement::Selection::NORMAL; requirement_.is_selected = false;
requirement_.selected_box = Box(); requirement_.selected_box = Box();
requirement_.min_x = 0; requirement_.min_x = 0;
requirement_.min_y = 0; requirement_.min_y = 0;
@ -130,10 +130,11 @@ class Flexbox : public Node {
// Find the selection: // Find the selection:
for (size_t i = 0; i < children_.size(); ++i) { 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; continue;
} }
requirement_.selection = children_[i]->requirement().selection; requirement_.is_selected = true;
Box selected_box = children_[i]->requirement().selected_box; Box selected_box = children_[i]->requirement().selected_box;
// Shift |selected_box| according to its position inside this component: // Shift |selected_box| according to its position inside this component:

View File

@ -36,7 +36,7 @@ Decorator focusPositionRelative(float x, float y) {
void ComputeRequirement() override { void ComputeRequirement() override {
NodeDecorator::ComputeRequirement(); NodeDecorator::ComputeRequirement();
requirement_.selection = Requirement::Selection::NORMAL; requirement_.is_selected = false;
Box& box = requirement_.selected_box; Box& box = requirement_.selected_box;
box.x_min = int(float(requirement_.min_x) * x_); box.x_min = int(float(requirement_.min_x) * x_);
@ -75,7 +75,7 @@ Decorator focusPosition(int x, int y) {
void ComputeRequirement() override { void ComputeRequirement() override {
NodeDecorator::ComputeRequirement(); NodeDecorator::ComputeRequirement();
requirement_.selection = Requirement::Selection::NORMAL; requirement_.is_selected = false;
Box& box = requirement_.selected_box; Box& box = requirement_.selected_box;
box.x_min = x_; box.x_min = x_;

View File

@ -27,7 +27,7 @@ class Select : public Node {
selected_box.y_min = 0; selected_box.y_min = 0;
selected_box.x_max = requirement_.min_x - 1; selected_box.x_max = requirement_.min_x - 1;
selected_box.y_max = requirement_.min_y - 1; selected_box.y_max = requirement_.min_y - 1;
requirement_.selection = Requirement::SELECTED; requirement_.is_selected = true;
} }
void SetBox(Box box) override { void SetBox(Box box) override {
@ -42,7 +42,6 @@ class Focus : public Select {
void ComputeRequirement() override { void ComputeRequirement() override {
Select::ComputeRequirement(); Select::ComputeRequirement();
requirement_.selection = Requirement::FOCUSED;
} }
void Render(Screen& screen) override { void Render(Screen& screen) override {

View File

@ -76,13 +76,14 @@ class GridBox : public Node {
requirement_.min_y = Integrate(size_y); requirement_.min_y = Integrate(size_y);
// Forward the selected/focused child state: // Forward the selected/focused child state:
requirement_.selection = Requirement::NORMAL; requirement_.is_selected = false;
for (int x = 0; x < x_size; ++x) { for (int x = 0; x < x_size; ++x) {
for (int y = 0; y < y_size; ++y) { 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; continue;
} }
requirement_.selection = lines_[y][x]->requirement().selection; requirement_.is_selected = true;
requirement_.selected_box = lines_[y][x]->requirement().selected_box; requirement_.selected_box = lines_[y][x]->requirement().selected_box;
requirement_.selected_box.x_min += size_x[x]; requirement_.selected_box.x_min += size_x[x];
requirement_.selected_box.x_max += size_x[x]; requirement_.selected_box.x_max += size_x[x];

View File

@ -19,7 +19,10 @@ namespace {
class HBox : public Node { class HBox : public Node {
public: public:
explicit HBox(Elements children) : Node(std::move(children)) {} explicit HBox(Elements children) : Node(std::move(children)) {}
explicit HBox(Elements children, int index)
: Node(std::move(children)), index_(index) {}
private:
void ComputeRequirement() override { void ComputeRequirement() override {
requirement_.min_x = 0; requirement_.min_x = 0;
requirement_.min_y = 0; requirement_.min_y = 0;
@ -27,11 +30,11 @@ class HBox : public Node {
requirement_.flex_grow_y = 0; requirement_.flex_grow_y = 0;
requirement_.flex_shrink_x = 0; requirement_.flex_shrink_x = 0;
requirement_.flex_shrink_y = 0; requirement_.flex_shrink_y = 0;
requirement_.selection = Requirement::NORMAL; requirement_.is_selected = false;
for (auto& child : children_) { for (auto& child : children_) {
child->ComputeRequirement(); child->ComputeRequirement();
if (requirement_.selection < child->requirement().selection) { if (children_[index_] == child && child->requirement().is_selected) {
requirement_.selection = child->requirement().selection; requirement_.is_selected = true;
requirement_.selected_box = child->requirement().selected_box; requirement_.selected_box = child->requirement().selected_box;
requirement_.selected_box.x_min += requirement_.min_x; requirement_.selected_box.x_min += requirement_.min_x;
requirement_.selected_box.x_max += requirement_.min_x; requirement_.selected_box.x_max += requirement_.min_x;
@ -77,6 +80,7 @@ class HBox : public Node {
child->Select(selection_saturated); child->Select(selection_saturated);
} }
} }
int index_ = 0;
}; };
} // namespace } // namespace
@ -97,4 +101,8 @@ Element hbox(Elements children) {
return std::make_shared<HBox>(std::move(children)); return std::make_shared<HBox>(std::move(children));
} }
Element hbox(Elements children, int index) {
return std::make_shared<HBox>(std::move(children), index);
}
} // namespace ftxui } // namespace ftxui

View File

@ -19,7 +19,10 @@ namespace {
class VBox : public Node { class VBox : public Node {
public: public:
explicit VBox(Elements children) : Node(std::move(children)) {} explicit VBox(Elements children) : Node(std::move(children)) {}
explicit VBox(Elements children, int index)
: Node(std::move(children)), index_(index) {}
private:
void ComputeRequirement() override { void ComputeRequirement() override {
requirement_.min_x = 0; requirement_.min_x = 0;
requirement_.min_y = 0; requirement_.min_y = 0;
@ -27,11 +30,11 @@ class VBox : public Node {
requirement_.flex_grow_y = 0; requirement_.flex_grow_y = 0;
requirement_.flex_shrink_x = 0; requirement_.flex_shrink_x = 0;
requirement_.flex_shrink_y = 0; requirement_.flex_shrink_y = 0;
requirement_.selection = Requirement::NORMAL; requirement_.is_selected = false;
for (auto& child : children_) { for (auto& child : children_) {
child->ComputeRequirement(); child->ComputeRequirement();
if (requirement_.selection < child->requirement().selection) { if (children_[index_] == child && child->requirement().is_selected) {
requirement_.selection = child->requirement().selection; requirement_.is_selected = true;
requirement_.selected_box = child->requirement().selected_box; requirement_.selected_box = child->requirement().selected_box;
requirement_.selected_box.y_min += requirement_.min_y; requirement_.selected_box.y_min += requirement_.min_y;
requirement_.selected_box.y_max += requirement_.min_y; requirement_.selected_box.y_max += requirement_.min_y;
@ -78,6 +81,8 @@ class VBox : public Node {
child->Select(selection_saturated); child->Select(selection_saturated);
} }
} }
int index_ = 0;
}; };
} // namespace } // namespace
@ -98,4 +103,8 @@ Element vbox(Elements children) {
return std::make_shared<VBox>(std::move(children)); return std::make_shared<VBox>(std::move(children));
} }
Element vbox(Elements children, int index) {
return std::make_shared<VBox>(std::move(children), index);
}
} // namespace ftxui } // namespace ftxui