mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-26 04:31:34 +08:00
Simplify the requirement struct.
This commit is contained in:
parent
3490d56662
commit
7f7775ba62
@ -11,23 +11,20 @@ namespace ftxui {
|
||||
|
||||
struct Requirement {
|
||||
// The required size to fully draw the element.
|
||||
struct {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
} min;
|
||||
int min_x = 0;
|
||||
int min_y = 0;
|
||||
|
||||
// How much flexibility is given to the component.
|
||||
struct {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
} flex;
|
||||
int flex_x = 0;
|
||||
int flex_y = 0;
|
||||
|
||||
// Frame.
|
||||
// Focus management to support the frame/focus/select element.
|
||||
enum Selection {
|
||||
NORMAL = 0,
|
||||
SELECTED = 1,
|
||||
FOCUSED = 2,
|
||||
} selection = NORMAL;
|
||||
};
|
||||
Selection selection = NORMAL;
|
||||
Box selected_box;
|
||||
};
|
||||
|
||||
|
@ -300,7 +300,7 @@ void ScreenInteractive::Draw(Component* component) {
|
||||
case Dimension::TerminalOutput:
|
||||
document->ComputeRequirement();
|
||||
dimx = Terminal::Size().dimx;
|
||||
dimy = document->requirement().min.y;
|
||||
dimy = document->requirement().min_y;
|
||||
break;
|
||||
case Dimension::Fullscreen:
|
||||
dimx = Terminal::Size().dimx;
|
||||
@ -309,8 +309,8 @@ void ScreenInteractive::Draw(Component* component) {
|
||||
case Dimension::FitComponent:
|
||||
auto terminal = Terminal::Size();
|
||||
document->ComputeRequirement();
|
||||
dimx = std::min(document->requirement().min.x, terminal.dimx);
|
||||
dimy = std::min(document->requirement().min.y, terminal.dimy);
|
||||
dimx = std::min(document->requirement().min_x, terminal.dimx);
|
||||
dimy = std::min(document->requirement().min_y, terminal.dimy);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -27,11 +27,11 @@ class Border : public Node {
|
||||
void ComputeRequirement() override {
|
||||
Node::ComputeRequirement();
|
||||
requirement_ = children[0]->requirement();
|
||||
requirement_.min.x += 2;
|
||||
requirement_.min.y += 2;
|
||||
requirement_.min_x += 2;
|
||||
requirement_.min_y += 2;
|
||||
if (children.size() == 2) {
|
||||
requirement_.min.x =
|
||||
std::max(requirement_.min.x, children[1]->requirement().min.x + 2);
|
||||
requirement_.min_x =
|
||||
std::max(requirement_.min_x, children[1]->requirement().min_x + 2);
|
||||
}
|
||||
requirement_.selected_box.x_min++;
|
||||
requirement_.selected_box.x_max++;
|
||||
|
@ -15,16 +15,16 @@ class DBox : public Node {
|
||||
~DBox() {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 0;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.flex_y = 0;
|
||||
for (auto& child : children) {
|
||||
child->ComputeRequirement();
|
||||
requirement_.min.x =
|
||||
std::max(requirement_.min.x, child->requirement().min.x);
|
||||
requirement_.min.y =
|
||||
std::max(requirement_.min.y, child->requirement().min.y);
|
||||
requirement_.min_x =
|
||||
std::max(requirement_.min_x, child->requirement().min_x);
|
||||
requirement_.min_y =
|
||||
std::max(requirement_.min_y, child->requirement().min_y);
|
||||
|
||||
if (requirement_.selection < child->requirement().selection) {
|
||||
requirement_.selection = child->requirement().selection;
|
||||
|
@ -13,14 +13,14 @@ class Flex : public Node {
|
||||
Flex(Element child) : Node(unpack(std::move(child))) {}
|
||||
~Flex() override {}
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
if (!children.empty()) {
|
||||
children[0]->ComputeRequirement();
|
||||
requirement_ = children[0]->requirement();
|
||||
}
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 1;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.flex_y = 1;
|
||||
}
|
||||
|
||||
void SetBox(Box box) override {
|
||||
@ -36,14 +36,14 @@ class NotFlex : public Flex {
|
||||
NotFlex(Element child) : Flex(std::move(child)) {}
|
||||
~NotFlex() override {}
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
if (!children.empty()) {
|
||||
children[0]->ComputeRequirement();
|
||||
requirement_ = children[0]->requirement();
|
||||
}
|
||||
requirement_.flex.x = 0;
|
||||
requirement_.flex.y = 0;
|
||||
requirement_.flex_x = 0;
|
||||
requirement_.flex_y = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,8 +23,8 @@ class Select : public Node {
|
||||
auto& selected_box = requirement_.selected_box;
|
||||
selected_box.x_min = 0;
|
||||
selected_box.y_min = 0;
|
||||
selected_box.x_max = requirement_.min.x;
|
||||
selected_box.y_max = requirement_.min.y;
|
||||
selected_box.x_max = requirement_.min_x;
|
||||
selected_box.y_max = requirement_.min_y;
|
||||
requirement_.selection = Requirement::SELECTED;
|
||||
};
|
||||
|
||||
@ -76,8 +76,8 @@ class Frame : public Node {
|
||||
int external_dimx = box.x_max - box.x_min;
|
||||
int external_dimy = box.y_max - box.y_min;
|
||||
|
||||
int internal_dimx = std::max(requirement_.min.x, external_dimx);
|
||||
int internal_dimy = std::max(requirement_.min.y, external_dimy);
|
||||
int internal_dimx = std::max(requirement_.min_x, external_dimx);
|
||||
int internal_dimy = std::max(requirement_.min_y, external_dimy);
|
||||
|
||||
auto& selected_box = requirement_.selected_box;
|
||||
int focused_dimx = selected_box.x_max - selected_box.x_min;
|
||||
@ -96,13 +96,13 @@ class Frame : public Node {
|
||||
|
||||
// int dx = box.x_max - box.x_min;
|
||||
// int dy = box.y_max - box.y_min;
|
||||
// int cdx = std::min(children[0].requirement().min.x
|
||||
// int cdx = std::min(children[0].requirement().min_x
|
||||
|
||||
// Box children_box;
|
||||
// children_box.x_min =
|
||||
// if (box.x_max - box.x_min >= children[0].requirement().min.x && //
|
||||
// if (box.x_max - box.x_min >= children[0].requirement().min_x && //
|
||||
|
||||
// box.y_max - box.y_min >= children[0].requirement().min.y) {
|
||||
// box.y_max - box.y_min >= children[0].requirement().min_y) {
|
||||
// children_[0]->SetBox(box);
|
||||
// dx = 0;
|
||||
// dy = 0;
|
||||
|
@ -15,8 +15,8 @@ class Gauge : public Node {
|
||||
~Gauge() override {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.min.y = 1;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.min_y = 1;
|
||||
}
|
||||
|
||||
void Render(Screen& screen) override {
|
||||
|
@ -14,10 +14,10 @@ class Graph : public Node {
|
||||
~Graph() override {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 1;
|
||||
requirement_.min.x = 1;
|
||||
requirement_.min.y = 1;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.flex_y = 1;
|
||||
requirement_.min_x = 1;
|
||||
requirement_.min_y = 1;
|
||||
}
|
||||
|
||||
void Render(Screen& screen) override {
|
||||
|
@ -15,21 +15,21 @@ class HBox : public Node {
|
||||
~HBox() {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 0;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.flex_y = 0;
|
||||
for (auto& child : children) {
|
||||
child->ComputeRequirement();
|
||||
if (requirement_.selection < child->requirement().selection) {
|
||||
requirement_.selection = child->requirement().selection;
|
||||
requirement_.selected_box = child->requirement().selected_box;
|
||||
requirement_.selected_box.x_min += requirement_.min.x;
|
||||
requirement_.selected_box.x_max += requirement_.min.x;
|
||||
requirement_.selected_box.x_min += requirement_.min_x;
|
||||
requirement_.selected_box.x_max += requirement_.min_x;
|
||||
}
|
||||
requirement_.min.x += child->requirement().min.x;
|
||||
requirement_.min.y =
|
||||
std::max(requirement_.min.y, child->requirement().min.y);
|
||||
requirement_.min_x += child->requirement().min_x;
|
||||
requirement_.min_y =
|
||||
std::max(requirement_.min_y, child->requirement().min_y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,10 +38,10 @@ class HBox : public Node {
|
||||
|
||||
int flex_sum = 0;
|
||||
for (auto& child : children)
|
||||
flex_sum += child->requirement().flex.x;
|
||||
flex_sum += child->requirement().flex_x;
|
||||
|
||||
int space = box.x_max - box.x_min + 1;
|
||||
int extra_space = space - requirement_.min.x;
|
||||
int extra_space = space - requirement_.min_x;
|
||||
|
||||
int remaining_flex = flex_sum;
|
||||
int remaining_extra_space = extra_space;
|
||||
@ -51,13 +51,13 @@ class HBox : public Node {
|
||||
Box child_box = box;
|
||||
child_box.x_min = x;
|
||||
|
||||
child_box.x_max = x + child->requirement().min.x - 1;
|
||||
child_box.x_max = x + child->requirement().min_x - 1;
|
||||
|
||||
if (child->requirement().flex.x) {
|
||||
int added_space = remaining_extra_space * child->requirement().flex.x /
|
||||
if (child->requirement().flex_x) {
|
||||
int added_space = remaining_extra_space * child->requirement().flex_x /
|
||||
remaining_flex;
|
||||
remaining_extra_space -= added_space;
|
||||
remaining_flex -= child->requirement().flex.x;
|
||||
remaining_flex -= child->requirement().flex_x;
|
||||
child_box.x_max += added_space;
|
||||
}
|
||||
child_box.x_max = std::min(child_box.x_max, box.x_max);
|
||||
|
@ -15,10 +15,10 @@ class HFlow : public Node {
|
||||
~HFlow() {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 1;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
requirement_.flex_x = 1;
|
||||
requirement_.flex_y = 1;
|
||||
for (auto& child : children)
|
||||
child->ComputeRequirement();
|
||||
}
|
||||
@ -35,25 +35,25 @@ class HFlow : public Node {
|
||||
Requirement requirement = child->requirement();
|
||||
|
||||
// Does it fit the end of the row?
|
||||
if (x + requirement.min.x > box.x_max) {
|
||||
if (x + requirement.min_x > box.x_max) {
|
||||
// No? Use the next row.
|
||||
x = box.x_min;
|
||||
y = y_next;
|
||||
}
|
||||
|
||||
// Does the current row big enough to contain the element?
|
||||
if (y + requirement.min.y > box.y_max + 1)
|
||||
if (y + requirement.min_y > box.y_max + 1)
|
||||
break; // No? Ignore the element.
|
||||
|
||||
Box children_box;
|
||||
children_box.x_min = x;
|
||||
children_box.x_max = x + requirement.min.x - 1;
|
||||
children_box.x_max = x + requirement.min_x - 1;
|
||||
children_box.y_min = y;
|
||||
children_box.y_max = y + requirement.min.y - 1;
|
||||
children_box.y_max = y + requirement.min_y - 1;
|
||||
child->SetBox(children_box);
|
||||
|
||||
x = x + requirement.min.x;
|
||||
y_next = std::max(y_next, y + requirement.min.y);
|
||||
x = x + requirement.min_x;
|
||||
y_next = std::max(y_next, y + requirement.min_y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -13,8 +13,8 @@ class Separator : public Node {
|
||||
Separator() {}
|
||||
~Separator() override {}
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 1;
|
||||
requirement_.min.y = 1;
|
||||
requirement_.min_x = 1;
|
||||
requirement_.min_y = 1;
|
||||
}
|
||||
|
||||
void Render(Screen& screen) override {
|
||||
|
@ -23,7 +23,7 @@ class Size : public Node {
|
||||
Node::ComputeRequirement();
|
||||
requirement_ = children[0]->requirement();
|
||||
|
||||
auto& value = direction_ == WIDTH ? requirement_.min.x : requirement_.min.y;
|
||||
auto& value = direction_ == WIDTH ? requirement_.min_x : requirement_.min_y;
|
||||
|
||||
switch (constraint_) {
|
||||
case LESS_THAN:
|
||||
@ -38,9 +38,9 @@ class Size : public Node {
|
||||
}
|
||||
|
||||
if (direction_ == WIDTH)
|
||||
requirement_.flex.x = 0;
|
||||
requirement_.flex_x = 0;
|
||||
else
|
||||
requirement_.flex.y = 0;
|
||||
requirement_.flex_y = 0;
|
||||
}
|
||||
|
||||
void SetBox(Box box) override {
|
||||
|
@ -15,8 +15,8 @@ class Text : public Node {
|
||||
~Text() {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = wstring_width(text_);
|
||||
requirement_.min.y = 1;
|
||||
requirement_.min_x = wstring_width(text_);
|
||||
requirement_.min_y = 1;
|
||||
}
|
||||
|
||||
void Render(Screen& screen) override {
|
||||
|
@ -16,21 +16,21 @@ class VBox : public Node {
|
||||
~VBox() {}
|
||||
|
||||
void ComputeRequirement() {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 0;
|
||||
requirement_.flex.y = 1;
|
||||
requirement_.min_x = 0;
|
||||
requirement_.min_y = 0;
|
||||
requirement_.flex_x = 0;
|
||||
requirement_.flex_y = 1;
|
||||
for (auto& child : children) {
|
||||
child->ComputeRequirement();
|
||||
if (requirement_.selection < child->requirement().selection) {
|
||||
requirement_.selection = child->requirement().selection;
|
||||
requirement_.selected_box = child->requirement().selected_box;
|
||||
requirement_.selected_box.y_min += requirement_.min.y;
|
||||
requirement_.selected_box.y_max += requirement_.min.y;
|
||||
requirement_.selected_box.y_min += requirement_.min_y;
|
||||
requirement_.selected_box.y_max += requirement_.min_y;
|
||||
}
|
||||
requirement_.min.y += child->requirement().min.y;
|
||||
requirement_.min.x =
|
||||
std::max(requirement_.min.x, child->requirement().min.x);
|
||||
requirement_.min_y += child->requirement().min_y;
|
||||
requirement_.min_x =
|
||||
std::max(requirement_.min_x, child->requirement().min_x);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +39,10 @@ class VBox : public Node {
|
||||
|
||||
int flex_sum = 0;
|
||||
for (auto& child : children)
|
||||
flex_sum += child->requirement().flex.y;
|
||||
flex_sum += child->requirement().flex_y;
|
||||
|
||||
int space = box.y_max - box.y_min + 1;
|
||||
int extra_space = space - requirement_.min.y;
|
||||
int extra_space = space - requirement_.min_y;
|
||||
|
||||
int remaining_flex = flex_sum;
|
||||
int remaining_extra_space = extra_space;
|
||||
@ -52,13 +52,13 @@ class VBox : public Node {
|
||||
Box child_box = box;
|
||||
child_box.y_min = y;
|
||||
|
||||
child_box.y_max = y + child->requirement().min.y - 1;
|
||||
child_box.y_max = y + child->requirement().min_y - 1;
|
||||
|
||||
if (child->requirement().flex.y) {
|
||||
int added_space = remaining_extra_space * child->requirement().flex.y /
|
||||
if (child->requirement().flex_y) {
|
||||
int added_space = remaining_extra_space * child->requirement().flex_y /
|
||||
remaining_flex;
|
||||
remaining_extra_space -= added_space;
|
||||
remaining_flex -= child->requirement().flex.y;
|
||||
remaining_flex -= child->requirement().flex_y;
|
||||
child_box.y_max += added_space;
|
||||
}
|
||||
child_box.y_max = std::min(child_box.y_max, box.y_max);
|
||||
|
@ -55,8 +55,8 @@ Dimension Dimension::Fixed(int v) {
|
||||
Dimension Dimension::Fit(std::shared_ptr<Node>& e) {
|
||||
e->ComputeRequirement();
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return Dimension{std::min(e->requirement().min.x, size.dimx),
|
||||
std::min(e->requirement().min.y, size.dimy)};
|
||||
return Dimension{std::min(e->requirement().min_x, size.dimx),
|
||||
std::min(e->requirement().min_y, size.dimy)};
|
||||
}
|
||||
|
||||
Dimension Dimension::Full() {
|
||||
|
Loading…
Reference in New Issue
Block a user