Add hflow.

This commit is contained in:
Arthur Sonzogni 2019-01-22 23:42:57 +01:00
parent 456ede70fd
commit 610b86183b
10 changed files with 161 additions and 2 deletions

View File

@ -73,7 +73,7 @@ class MyComponent : public Component {
separator(), separator(),
Render(L"radiobox", radiobox), Render(L"radiobox", radiobox),
separator(), separator(),
Render(L"input", input) Render(L"input", input) | size(WIDTH, EQUAL, 20)
) | border; ) | border;
} }
}; };

View File

@ -16,4 +16,6 @@ example(style_dim)
example(style_gallery) example(style_gallery)
example(style_inverted) example(style_inverted)
example(style_underlined) example(style_underlined)
example(size)
example(vbox_hbox) example(vbox_hbox)
example(hflow)

51
examples/dom/hflow.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "ftxui/screen/screen.hpp"
#include "ftxui/screen/string.hpp"
#include "ftxui/dom/elements.hpp"
#include <iostream>
int main(int argc, const char *argv[])
{
using namespace ftxui;
auto make_box = [](size_t dimx, size_t dimy) {
std::wstring title = to_wstring(dimx) + L"x" + to_wstring(dimy);
return
window(
text(title) | hcenter | bold,
text(L"content") | hcenter | dim
) | size(WIDTH, EQUAL, dimx)
| size(HEIGHT, EQUAL, dimy)
;
};
auto document =
hflow(
make_box(7,7),
make_box(7,5),
make_box(5,7),
make_box(10,4),
make_box(10,4),
make_box(10,4),
make_box(10,4),
make_box(11,4),
make_box(11,4),
make_box(11,4),
make_box(11,4),
make_box(12,4),
make_box(12,5),
make_box(12,4),
make_box(13,4),
make_box(13,3),
make_box(13,3),
make_box(10,3)
) | size(WIDTH, GREATER_THAN, 20)
| border
| size(HEIGHT, GREATER_THAN, 30)
| size(WIDTH, LESS_THAN, 50)
;
auto screen = Screen::TerminalOutput(document);
Render(screen, document.get());
std::cout << screen.ToString() << std::endl;
return 0;
}

30
examples/dom/size.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "ftxui/screen/screen.hpp"
#include "ftxui/screen/string.hpp"
#include "ftxui/dom/elements.hpp"
#include <iostream>
int main(int argc, const char *argv[])
{
using namespace ftxui;
auto make_box = [](const std::wstring title) {
return
window(
text(title) | hcenter | bold,
text(L"content") | hcenter | dim
);
};
Elements content;
for(int x = 3; x<30; ++x) {
content.push_back(
make_box(to_wstring(x))
| size(WIDTH, EQUAL, x)
);
}
auto document = hbox(std::move(content));
auto screen = Screen::FitDocument(document);
Render(screen, document.get());
std::cout << screen.ToString() << std::endl;
return 0;
}

View File

@ -19,6 +19,7 @@ add_library(dom
src/ftxui/dom/frame.cpp src/ftxui/dom/frame.cpp
src/ftxui/dom/gauge.cpp src/ftxui/dom/gauge.cpp
src/ftxui/dom/hbox.cpp src/ftxui/dom/hbox.cpp
src/ftxui/dom/hflow.cpp
src/ftxui/dom/inverted.cpp src/ftxui/dom/inverted.cpp
src/ftxui/dom/node.cpp src/ftxui/dom/node.cpp
src/ftxui/dom/node_decorator.cpp src/ftxui/dom/node_decorator.cpp

View File

@ -33,9 +33,10 @@ Element bgcolor(Color, Element);
// --- Layout --- // --- Layout ---
// Horizontal, Vertical or stacked set of elements. // Horizontal, Vertical or stacked set of elements.
Element vbox(Elements);
Element hbox(Elements); Element hbox(Elements);
Element vbox(Elements);
Element dbox(Elements); Element dbox(Elements);
Element hflow(Elements);
// -- Flexibility --- // -- Flexibility ---
// Define how to share the remaining space when not all of it is used inside a // Define how to share the remaining space when not all of it is used inside a
@ -73,6 +74,7 @@ Decorator operator|(Decorator, Decorator);
TAKE_ANY_ARGS(vbox) TAKE_ANY_ARGS(vbox)
TAKE_ANY_ARGS(hbox) TAKE_ANY_ARGS(hbox)
TAKE_ANY_ARGS(dbox) TAKE_ANY_ARGS(dbox)
TAKE_ANY_ARGS(hflow)
}; // namespace ftxui }; // namespace ftxui

View File

@ -33,6 +33,7 @@ class Screen {
// Constructor using the terminal. // Constructor using the terminal.
static Screen TerminalFullscreen(); static Screen TerminalFullscreen();
static Screen TerminalOutput(std::unique_ptr<Node>& element); static Screen TerminalOutput(std::unique_ptr<Node>& element);
static Screen FitDocument(std::unique_ptr<Node>& element);
// Node write into the screen using Screen::at. // Node write into the screen using Screen::at.
wchar_t& at(size_t x, size_t y); wchar_t& at(size_t x, size_t y);

View File

@ -0,0 +1,59 @@
#include "ftxui/dom/node.hpp"
#include "ftxui/dom/elements.hpp"
namespace ftxui {
class HFlow : public Node {
public:
HFlow(Elements children) : Node(std::move(children)) {}
~HFlow() {}
void ComputeRequirement() override {
requirement_.min.x = 0;
requirement_.min.y = 0;
requirement_.flex.x = 1;
requirement_.flex.y = 0;
for(auto& child : children)
child->ComputeRequirement();
}
void SetBox(Box box) override {
Node::SetBox(box);
// The position of the first component.
int x = box.x_min;
int y = box.y_min;
int y_next = y; // The position of next row of elements.
for (auto& child : children) {
Requirement requirement = child->requirement();
// Does it fit the end of the row?
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)
break; // No? Ignore the element.
Box children_box;
children_box.x_min = x;
children_box.x_max = x + requirement.min.x;
children_box.y_min = y;
children_box.y_max = y + requirement.min.y;
child->SetBox(children_box);
x = x + requirement.min.x + 1;
y_next = std::max(y_next, y + requirement.min.y + 1);
}
}
};
std::unique_ptr<Node> hflow(Elements children) {
return std::make_unique<HFlow>(std::move(children));
}
}; // namespace ftxui

View File

@ -39,6 +39,8 @@ class Size : public Node {
void SetBox(Box box) override { void SetBox(Box box) override {
Node::SetBox(box); Node::SetBox(box);
if (constraint_ == LESS_THAN)
box.x_max = std::min(box.x_min + value_ + 1, box.x_max);
children[0]->SetBox(box); children[0]->SetBox(box);
} }

View File

@ -109,6 +109,17 @@ Screen Screen::TerminalOutput(std::unique_ptr<Node>& element) {
return Screen(size.dimx, element->requirement().min.y); return Screen(size.dimx, element->requirement().min.y);
} }
// static
Screen Screen::FitDocument(std::unique_ptr<Node>& element) {
element->ComputeRequirement();
Terminal::Dimensions size = Terminal::Size();
return
Screen(
std::min(size.dimx, element->requirement().min.x),
std::min(size.dimy, element->requirement().min.y)
);
}
std::string Screen::ResetPosition() { std::string Screen::ResetPosition() {
std::stringstream ss; std::stringstream ss;
ss << MOVE_LEFT << CLEAR_LINE; ss << MOVE_LEFT << CLEAR_LINE;