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
// 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<Elements> lines);

View File

@ -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;
};

View File

@ -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<VerticalContainer>(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);

View File

@ -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;
}
}

View File

@ -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:

View File

@ -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_;

View File

@ -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 {

View File

@ -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];

View File

@ -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<HBox>(std::move(children));
}
Element hbox(Elements children, int index) {
return std::make_shared<HBox>(std::move(children), index);
}
} // namespace ftxui

View File

@ -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<VBox>(std::move(children));
}
Element vbox(Elements children, int index) {
return std::make_shared<VBox>(std::move(children), index);
}
} // namespace ftxui