Simplify the requirement struct.

This commit is contained in:
ArthurSonzogni 2020-06-01 16:13:29 +02:00 committed by Arthur Sonzogni
parent 3490d56662
commit 7f7775ba62
15 changed files with 92 additions and 95 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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