Add the Renderer component.

This commit is contained in:
ArthurSonzogni 2021-05-13 11:44:47 +02:00
parent 6d75cb2748
commit c9aa1805eb
No known key found for this signature in database
GPG Key ID: 41D98248C074CD6C
9 changed files with 400 additions and 324 deletions

View File

@ -99,6 +99,7 @@ add_library(component
src/ftxui/component/menu.cpp src/ftxui/component/menu.cpp
src/ftxui/component/radiobox.cpp src/ftxui/component/radiobox.cpp
src/ftxui/component/radiobox.cpp src/ftxui/component/radiobox.cpp
src/ftxui/component/renderer.cpp
src/ftxui/component/screen_interactive.cpp src/ftxui/component/screen_interactive.cpp
src/ftxui/component/slider.cpp src/ftxui/component/slider.cpp
src/ftxui/component/terminal_input_parser.cpp src/ftxui/component/terminal_input_parser.cpp

View File

@ -1,43 +1,36 @@
#include <string> // for operator+, to_wstring, allocator, wstring #include <string> // for operator+, to_wstring, allocator, wstring
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Make #include "ftxui/component/component.hpp" // for Button, Make
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/container.hpp" // for Container #include "ftxui/component/container.hpp" // for Container
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, Element, gauge, text, operator|, vbox, border
using namespace ftxui; using namespace ftxui;
class MyComponent : public ComponentBase { int main(int argc, const char* argv[]) {
private: int value = 50;
std::wstring label_add = L"Increase"; std::wstring label_dec = L"decrease";
std::wstring label_rm = L"Decrease"; std::wstring label_inc = L"increase";
int value_ = 50;
public: // The tree of components. This defines how to navigate using the keyboard.
MyComponent() { auto buttons = Container::Horizontal({
Add(Container::Horizontal({ Button(&label_dec, [&] { value--; }),
Button(&label_rm, [&] { value_--; }), Button(&label_inc, [&] { value++; }),
Button(&label_add, [&] { value_++; }), });
}));
}
Element Render() override { // Modify the way to render them on screen:
auto component = Renderer(buttons, [&] {
return vbox({ return vbox({
text(L"Value = " + std::to_wstring(value_)), text(L"value = " + std::to_wstring(value)),
separator(), separator(),
gauge(value_ * 0.01f), gauge(value * 0.01f),
separator(), separator(),
ComponentBase::Render(), buttons->Render(),
}) | }) |
border; border;
} });
};
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::FitComponent(); auto screen = ScreenInteractive::FitComponent();
screen.Loop(Make<MyComponent>()); screen.Loop(component);
return 0; return 0;
} }

View File

@ -6,8 +6,7 @@
using namespace ftxui; using namespace ftxui;
class MyComponent : public ComponentBase { int main(int argc, const char* argv[]) {
private:
std::wstring build_examples_label = L"Build examples"; std::wstring build_examples_label = L"Build examples";
std::wstring build_tests_label = L"Build tests"; std::wstring build_tests_label = L"Build tests";
std::wstring use_webassembly_label = L"Use WebAssembly"; std::wstring use_webassembly_label = L"Use WebAssembly";
@ -16,19 +15,14 @@ class MyComponent : public ComponentBase {
bool build_tests_state = false; bool build_tests_state = false;
bool use_webassembly_state = true; bool use_webassembly_state = true;
Component container = Container::Vertical({ auto component = Container::Vertical({
Checkbox(&build_examples_label, &build_examples_state), Checkbox(&build_examples_label, &build_examples_state),
Checkbox(&build_tests_label, &build_tests_state), Checkbox(&build_tests_label, &build_tests_state),
Checkbox(&use_webassembly_label, &use_webassembly_state), Checkbox(&use_webassembly_label, &use_webassembly_state),
}); });
public:
MyComponent() { Add(container); }
};
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::TerminalOutput(); auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(Make<MyComponent>()); screen.Loop(component);
return 0; return 0;
} }

View File

@ -1,9 +1,7 @@
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
#include <memory> // for unique_ptr, make_unique, __shared_ptr_access #include <memory> // for unique_ptr, make_unique, __shared_ptr_access
#include <string> // for operator+, wstring #include <string> // for operator+, wstring
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Checkbox, Make #include "ftxui/component/component.hpp" // for Checkbox, Make
#include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/container.hpp" // for Container #include "ftxui/component/container.hpp" // for Container
@ -13,49 +11,28 @@
using namespace ftxui; using namespace ftxui;
struct CheckboxAndState { struct CheckboxState {
std::wstring label; std::wstring label;
bool state; bool checked;
Component component;
};
std::unique_ptr<CheckboxAndState> MakeCheckbox(std::wstring label) {
auto out = std::make_unique<CheckboxAndState>();
out->label = label;
out->state = false;
out->component = Checkbox(&out->label, &out->state);
return out;
}
class MyComponent : public ComponentBase {
public:
MyComponent() {
Add(container);
checkbox.resize(30);
for (int i = 0; i < checkbox.size(); ++i) {
checkbox[i] = MakeCheckbox(L"CheckBox " + to_wstring(i));
container->Add(checkbox[i]->component);
}
}
// clang-format off
Element Render() override {
Elements content;
return vbox(container->Render())
| frame
| size(HEIGHT, LESS_THAN, 10)
| border;
}
private:
std::vector<std::unique_ptr<CheckboxAndState>> checkbox;
Component container = Container::Vertical();
}; };
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
int size = 30;
std::vector<CheckboxState> states(size);
auto container = Container::Vertical({});
for(int i = 0; i<size; ++i) {
states[i].checked = false;
states[i].label = L"Checkbox " + to_wstring(i);
container->Add(Checkbox(&states[i].label, &states[i].checked));
}
auto component = Renderer(container, [&] {
return container->Render() | frame | ftxui::size(HEIGHT, LESS_THAN, 10) |
border;
});
auto screen = ScreenInteractive::FitComponent(); auto screen = ScreenInteractive::FitComponent();
auto my_component = Make<MyComponent>(); screen.Loop(component);
screen.Loop(my_component);
return 0; return 0;
} }

View File

@ -12,111 +12,117 @@
using namespace ftxui; using namespace ftxui;
class MyComponent : public ComponentBase { // Display a component nicely with a title on the left.
const std::vector<std::wstring> menu_entries_ = { Component Wrap(std::wstring name, Component component) {
return Renderer(component, [name, component] {
return hbox({
text(name) | size(WIDTH, EQUAL, 8),
separator(),
component->Render() | xflex,
}) |
xflex;
});
}
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::FitComponent();
// -- Menu ----------------------------------------------------------------------
const std::vector<std::wstring> menu_entries = {
L"Menu 1", L"Menu 1",
L"Menu 2", L"Menu 2",
L"Menu 3", L"Menu 3",
L"Menu 4", L"Menu 4",
}; };
int menu_selected_ = 0; int menu_selected = 0;
Component menu_ = Menu(&menu_entries_, &menu_selected_); auto menu = Menu(&menu_entries, &menu_selected);
menu = Wrap(L"Menu", menu);
int toggle_selected_ = 0; // -- Toggle------------------------------------------------------------------
std::vector<std::wstring> toggle_entries_ = { int toggle_selected = 0;
std::vector<std::wstring> toggle_entries = {
L"Toggle_1", L"Toggle_1",
L"Toggle_2", L"Toggle_2",
}; };
Component toggle_ = Toggle(&toggle_entries_, &toggle_selected_); auto toggle = Toggle(&toggle_entries, &toggle_selected);
toggle = Wrap(L"Toggle", toggle);
std::wstring checkbox_1_label_ = L"checkbox1"; // -- Checkbox ---------------------------------------------------------------
std::wstring checkbox_2_label_ = L"checkbox2"; std::wstring checkbox_1_label = L"checkbox1";
bool checkbox_1_selected_ = false; std::wstring checkbox_2_label = L"checkbox2";
bool checkbox_2_selected_ = false; bool checkbox_1_selected = false;
bool checkbox_2_selected = false;
Component checkbox_container_ = Container::Vertical({ auto checkboxes = Container::Vertical({
Checkbox(&checkbox_1_label_, &checkbox_1_selected_), Checkbox(&checkbox_1_label, &checkbox_1_selected),
Checkbox(&checkbox_2_label_, &checkbox_2_selected_), Checkbox(&checkbox_2_label, &checkbox_2_selected),
}); });
checkboxes = Wrap(L"Checkbox", checkboxes);
int radiobox_selected_ = 0; // -- Radiobox ---------------------------------------------------------------
std::vector<std::wstring> radiobox_entries_ = { int radiobox_selected = 0;
std::vector<std::wstring> radiobox_entries = {
L"Radiobox 1", L"Radiobox 1",
L"Radiobox 2", L"Radiobox 2",
L"Radiobox 3", L"Radiobox 3",
L"Radiobox 4", L"Radiobox 4",
}; };
Component radiobox_ = Radiobox(&radiobox_entries_, &radiobox_selected_); auto radiobox = Radiobox(&radiobox_entries, &radiobox_selected);
radiobox = Wrap(L"Radiobox", radiobox);
std::wstring input_label_; // -- Input ------------------------------------------------------------------
std::wstring input_placeholder_ = L"input"; std::wstring input_label;
Component input_ = Input(&input_label_, &input_placeholder_); std::wstring input_placeholder = L"input";
auto input = Input(&input_label, &input_placeholder);
input = Wrap(L"Input", input);
std::wstring button_label_ = L"Quit"; // -- Button -----------------------------------------------------------------
std::wstring button_label = L"Quit";
std::function<void()> on_button_clicked_; std::function<void()> on_button_clicked_;
Component button_ = Button(&button_label_, [this] { on_button_clicked_(); }); auto button = Button(&button_label, screen.ExitLoopClosure());
button = Wrap(L"Button", button);
int slider_value_1_ = 12; // -- Slider -----------------------------------------------------------------
int slider_value_2_ = 56; int slider_value_1 = 12;
int slider_value_3_ = 128; int slider_value_2 = 56;
Component slider_container_ = Container::Vertical({ int slider_value_3 = 128;
Slider(L"R:", &slider_value_1_, 0, 256, 1), auto sliders = Container::Vertical({
Slider(L"G:", &slider_value_2_, 0, 256, 1), Slider(L"R:", &slider_value_1, 0, 256, 1),
Slider(L"B:", &slider_value_3_, 0, 256, 1), Slider(L"G:", &slider_value_2, 0, 256, 1),
Slider(L"B:", &slider_value_3, 0, 256, 1),
});
sliders = Wrap(L"Slider", sliders);
// -- Layout -----------------------------------------------------------------
auto layout = Container::Vertical({
menu,
toggle,
checkboxes,
radiobox,
input,
sliders,
button,
}); });
public: auto component = Renderer(layout, [&] {
MyComponent(std::function<void(void)> on_quit) : on_quit_(on_quit) { return vbox({
Add(Container::Vertical({ menu->Render(),
menu_,
toggle_,
checkbox_container_,
radiobox_,
input_,
slider_container_,
button_,
}));
}
Element Render(std::wstring name, Element element) {
return hbox({
text(name) | size(WIDTH, EQUAL, 8),
separator(), separator(),
element | xflex, toggle->Render(),
separator(),
checkboxes->Render(),
separator(),
radiobox->Render(),
separator(),
input->Render(),
separator(),
sliders->Render(),
separator(),
button->Render(),
}) | }) |
xflex; xflex | size(WIDTH, GREATER_THAN, 40) | border;
} });
Element Render(std::wstring name, Component& component) {
return Render(name, component->Render());
}
Element Render() override {
return //
vbox({
Render(L"menu", menu_),
separator(),
Render(L"toggle", toggle_),
separator(),
Render(L"checkbox", checkbox_container_),
separator(),
Render(L"radiobox", radiobox_),
separator(),
Render(L"input", input_) | size(WIDTH, LESS_THAN, 50),
separator(),
Render(L"slider", slider_container_),
separator(),
Render(L"button", button_),
}) |
xflex | size(WIDTH, GREATER_THAN, 40) | border;
}
std::function<void()> on_quit_;
};
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::FitComponent();
auto component = Make<MyComponent>(screen.ExitLoopClosure());
screen.Loop(component); screen.Loop(component);
return 0; return 0;

View File

@ -20,32 +20,32 @@
using namespace ftxui; using namespace ftxui;
int shift = 0; int main(int argc, const char* argv[]) {
class Graph { auto screen = ScreenInteractive::Fullscreen();
public:
std::vector<int> operator()(int width, int height) { int shift = 0;
std::vector<int> output(width);
for (int i = 0; i < width; ++i) { class Graph {
float v = 0; public:
v += 0.1f * sin((i + shift) * 0.1f); Graph(int* shift) : shift_(shift) {}
v += 0.2f * sin((i + shift + 10) * 0.15f); std::vector<int> operator()(int width, int height) {
v += 0.1f * sin((i + shift) * 0.03f); std::vector<int> output(width);
v *= height; for (int i = 0; i < width; ++i) {
v += 0.5f * height; float v = 0;
output[i] = (int)v; v += 0.1f * sin((i + *shift_) * 0.1f);
v += 0.2f * sin((i + *shift_ + 10) * 0.15f);
v += 0.1f * sin((i + *shift_) * 0.03f);
v *= height;
v += 0.5f * height;
output[i] = (int)v;
}
return output;
} }
return output; int* shift_;
} };
};
class HTopComponent : public ComponentBase { Graph my_graph(&shift);
Graph my_graph; auto htop = Renderer([&] {
public:
HTopComponent() {}
~HTopComponent() override {}
Element Render() override {
auto frequency = vbox({ auto frequency = vbox({
text(L"Frequency [Mhz]") | hcenter, text(L"Frequency [Mhz]") | hcenter,
hbox({ hbox({
@ -98,52 +98,50 @@ class HTopComponent : public ComponentBase {
ram | flex, ram | flex,
}) | }) |
flex | border; flex | border;
} });
};
const std::vector<std::wstring> compiler_entries = { const std::vector<std::wstring> compiler_entries = {
L"gcc", L"gcc",
L"clang", L"clang",
L"emcc", L"emcc",
L"game_maker", L"game_maker",
L"Ada compilers", L"Ada compilers",
L"ALGOL 60 compilers", L"ALGOL 60 compilers",
L"ALGOL 68 compilers", L"ALGOL 68 compilers",
L"Assemblers (Intel *86)", L"Assemblers (Intel *86)",
L"Assemblers (Motorola 68*)", L"Assemblers (Motorola 68*)",
L"Assemblers (Zilog Z80)", L"Assemblers (Zilog Z80)",
L"Assemblers (other)", L"Assemblers (other)",
L"BASIC Compilers", L"BASIC Compilers",
L"BASIC interpreters", L"BASIC interpreters",
L"Batch compilers", L"Batch compilers",
L"C compilers", L"C compilers",
L"Source-to-source compilers", L"Source-to-source compilers",
L"C++ compilers", L"C++ compilers",
L"C# compilers", L"C# compilers",
L"COBOL compilers", L"COBOL compilers",
L"Common Lisp compilers", L"Common Lisp compilers",
L"D compilers", L"D compilers",
L"DIBOL/DBL compilers", L"DIBOL/DBL compilers",
L"ECMAScript interpreters", L"ECMAScript interpreters",
L"Eiffel compilers", L"Eiffel compilers",
L"Fortran compilers", L"Fortran compilers",
L"Go compilers", L"Go compilers",
L"Haskell compilers", L"Haskell compilers",
L"Java compilers", L"Java compilers",
L"Pascal compilers", L"Pascal compilers",
L"Perl Interpreters", L"Perl Interpreters",
L"PHP compilers", L"PHP compilers",
L"PL/I compilers", L"PL/I compilers",
L"Python compilers", L"Python compilers",
L"Scheme compilers and interpreters", L"Scheme compilers and interpreters",
L"Smalltalk compilers", L"Smalltalk compilers",
L"Tcl Interpreters", L"Tcl Interpreters",
L"VMS Interpreters", L"VMS Interpreters",
L"Rexx Interpreters", L"Rexx Interpreters",
L"CLI compilers", L"CLI compilers",
}; };
class CompilerComponent : public ComponentBase {
int compiler_selected = 0; int compiler_selected = 0;
Component compiler = Radiobox(&compiler_entries, &compiler_selected); Component compiler = Radiobox(&compiler_entries, &compiler_selected);
@ -178,28 +176,48 @@ class CompilerComponent : public ComponentBase {
Checkbox(&options_label[3], &options_state[3]), Checkbox(&options_label[3], &options_state[3]),
}); });
public: auto compiler_component = Container::Horizontal({
~CompilerComponent() override {} compiler,
CompilerComponent() { flags,
Add(Container::Horizontal({ Container::Vertical({
compiler, executable_,
flags, Container::Horizontal({
Container::Vertical({ input_add,
executable_, input,
Container::Horizontal({ }),
input_add, }),
input, });
}),
}),
}));
InputBase::From(input_add)->on_enter = [this] { InputBase::From(input_add)->on_enter = [&] {
input_entries.push_back(input_add_content); input_entries.push_back(input_add_content);
input_add_content = L""; input_add_content = L"";
}; };
}
Element Render() override { auto render_command = [&] {
Elements line;
// Compiler
line.push_back(text(compiler_entries[compiler_selected]) | bold);
// flags
for (int i = 0; i < 4; ++i) {
if (options_state[i]) {
line.push_back(text(L" "));
line.push_back(text(options_label[i]) | dim);
}
}
// Executable
if (!executable_content_.empty()) {
line.push_back(text(L" -O ") | bold);
line.push_back(text(executable_content_) | color(Color::BlueLight) |
bold);
}
// Input
for (auto& it : input_entries) {
line.push_back(text(L" " + it) | color(Color::RedLight));
}
return line;
};
auto compiler_renderer = Renderer(compiler_component, [&] {
auto compiler_win = window(text(L"Compiler"), compiler->Render() | frame); auto compiler_win = window(text(L"Compiler"), compiler->Render() | frame);
auto flags_win = window(text(L"Flags"), flags->Render()); auto flags_win = window(text(L"Flags"), flags->Render());
auto executable_win = window(text(L"Executable:"), executable_->Render()); auto executable_win = window(text(L"Executable:"), executable_->Render());
@ -227,50 +245,21 @@ class CompilerComponent : public ComponentBase {
}), }),
filler(), filler(),
}), }),
hflow(RenderCommandLine()) | flex_grow, hflow(render_command()) | flex_grow,
}) | }) |
flex_grow | border; flex_grow | border;
} });
Elements RenderCommandLine() { auto spinner_tab_renderer = Renderer([&] {
Elements line;
// Compiler
line.push_back(text(compiler_entries[compiler_selected]) | bold);
// flags
for (int i = 0; i < 4; ++i) {
if (options_state[i]) {
line.push_back(text(L" "));
line.push_back(text(options_label[i]) | dim);
}
}
// Executable
if (!executable_content_.empty()) {
line.push_back(text(L" -O ") | bold);
line.push_back(text(executable_content_) | color(Color::BlueLight) |
bold);
}
// Input
for (auto& it : input_entries) {
line.push_back(text(L" " + it) | color(Color::RedLight));
}
return line;
}
};
class SpinnerComponent : public ComponentBase {
Element Render() override {
Elements entries; Elements entries;
for (int i = 0; i < 22; ++i) { for (int i = 0; i < 22; ++i) {
if (i != 0) entries.push_back(spinner(i, shift / 2) | bold |
entries.push_back(spinner(i, shift / 2) | bold | size(WIDTH, GREATER_THAN, 2) | border);
size(WIDTH, GREATER_THAN, 2) | border);
} }
return hflow(std::move(entries)) | border; return hflow(std::move(entries)) | border;
} });
};
class ColorComponent : public ComponentBase { auto color_tab_renderer = Renderer([] {
Element Render() override {
return hbox({ return hbox({
vbox({ vbox({
color(Color::Default, text(L"Default")), color(Color::Default, text(L"Default")),
@ -312,79 +301,67 @@ class ColorComponent : public ComponentBase {
}), }),
}) | }) |
hcenter | border; hcenter | border;
} });
};
class GaugeComponent : public ComponentBase { auto render_gauge = [&shift](int delta) {
Element RenderGauge(int delta) {
float progress = (shift + delta) % 1000 / 1000.f; float progress = (shift + delta) % 1000 / 1000.f;
return hbox({ return hbox({
text(std::to_wstring(int(progress * 100)) + L"% ") | text(std::to_wstring(int(progress * 100)) + L"% ") |
size(WIDTH, EQUAL, 5), size(WIDTH, EQUAL, 5),
gauge(progress), gauge(progress),
}); });
} };
Element Render() override {
auto gauge_component = Renderer([render_gauge] {
return vbox({ return vbox({
RenderGauge(0) | color(Color::Black), render_gauge(0) | color(Color::Black),
RenderGauge(100) | color(Color::GrayDark), render_gauge(100) | color(Color::GrayDark),
RenderGauge(50) | color(Color::GrayLight), render_gauge(50) | color(Color::GrayLight),
RenderGauge(6894) | color(Color::White), render_gauge(6894) | color(Color::White),
separator(), separator(),
RenderGauge(6841) | color(Color::Blue), render_gauge(6841) | color(Color::Blue),
RenderGauge(9813) | color(Color::BlueLight), render_gauge(9813) | color(Color::BlueLight),
RenderGauge(98765) | color(Color::Cyan), render_gauge(98765) | color(Color::Cyan),
RenderGauge(98) | color(Color::CyanLight), render_gauge(98) | color(Color::CyanLight),
RenderGauge(9846) | color(Color::Green), render_gauge(9846) | color(Color::Green),
RenderGauge(1122) | color(Color::GreenLight), render_gauge(1122) | color(Color::GreenLight),
RenderGauge(84) | color(Color::Magenta), render_gauge(84) | color(Color::Magenta),
RenderGauge(645) | color(Color::MagentaLight), render_gauge(645) | color(Color::MagentaLight),
RenderGauge(568) | color(Color::Red), render_gauge(568) | color(Color::Red),
RenderGauge(2222) | color(Color::RedLight), render_gauge(2222) | color(Color::RedLight),
RenderGauge(220) | color(Color::Yellow), render_gauge(220) | color(Color::Yellow),
RenderGauge(348) | color(Color::YellowLight), render_gauge(348) | color(Color::YellowLight),
}) | }) |
border; border;
}; });
};
class Tab : public ComponentBase {
public:
int tab_index = 0; int tab_index = 0;
std::vector<std::wstring> tab_entries = { std::vector<std::wstring> tab_entries = {
L"htop", L"color", L"spinner", L"gauge", L"compiler", L"htop", L"color", L"spinner", L"gauge", L"compiler",
}; };
Component tab_selection = Toggle(&tab_entries, &tab_index); auto tab_selection = Toggle(&tab_entries, &tab_index);
Component container = auto tab_content = Container::Tab(&tab_index, {
Container::Tab(&tab_index, htop,
{ color_tab_renderer,
std::make_shared<HTopComponent>(), spinner_tab_renderer,
std::make_shared<ColorComponent>(), gauge_component,
std::make_shared<SpinnerComponent>(), compiler_renderer,
std::make_shared<GaugeComponent>(), });
std::make_shared<CompilerComponent>(),
});
Component main_container = Container::Vertical({ auto main_container = Container::Vertical({
tab_selection, tab_selection,
container, tab_content,
}); });
Tab() { Add(main_container); } auto main_renderer = Renderer(main_container, [&] {
Element Render() override {
return vbox({ return vbox({
text(L"FTXUI Demo") | bold | hcenter, text(L"FTXUI Demo") | bold | hcenter,
tab_selection->Render() | hcenter, tab_selection->Render() | hcenter,
container->Render() | flex, tab_content->Render() | flex,
}); });
} });
};
int main(int argc, const char* argv[]) { std::thread update([&screen, &shift]() {
auto screen = ScreenInteractive::Fullscreen();
std::thread update([&screen]() {
for (;;) { for (;;) {
using namespace std::chrono_literals; using namespace std::chrono_literals;
std::this_thread::sleep_for(0.05s); std::this_thread::sleep_for(0.05s);
@ -393,8 +370,7 @@ int main(int argc, const char* argv[]) {
} }
}); });
Component tab = std::make_shared<Tab>(); screen.Loop(main_renderer);
screen.Loop(tab);
return 0; return 0;
} }

View File

@ -0,0 +1,83 @@
#include <functional> // for function
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for operator+, to_wstring, char_traits
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider, Make
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/container.hpp" // for Container
#include "ftxui/component/event.hpp" // for Event, Event::Escape, Event::Return
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, operator|, Element, size, text, vbox, xflex, bgcolor, hbox, GREATER_THAN, WIDTH, border, HEIGHT, LESS_THAN
#include "ftxui/screen/color.hpp" // for Color
using namespace ftxui;
Element ColorTile(int red, int green, int blue) {
return text(L"") | size(WIDTH, GREATER_THAN, 14) |
size(HEIGHT, GREATER_THAN, 7) | bgcolor(Color::RGB(red, green, blue));
}
Element ColorString(int red, int green, int blue) {
return text(L"RGB = (" + //
std::to_wstring(red) + L"," + //
std::to_wstring(green) + L"," + //
std::to_wstring(blue) + L")" //
);
}
class MyComponent : public ComponentBase {
private:
int* red_;
int* green_;
int* blue_;
Component slider_red_ = Slider(L"Red :", red_, 0, 255, 1);
Component slider_green_ = Slider(L"Green:", green_, 0, 255, 1);
Component slider_blue_ = Slider(L"Blue :", blue_, 0, 255, 1);
std::function<void(void)> quit_;
public:
MyComponent(int* red, int* green, int* blue, std::function<void(void)> quit)
: red_(red), green_(green), blue_(blue), quit_(quit) {
Add(Container::Vertical({
slider_red_,
slider_green_,
slider_blue_,
}));
}
Element Render() {
return hbox({
ColorTile(*red_, *green_, *blue_),
separator(),
vbox({
slider_red_->Render(),
separator(),
slider_green_->Render(),
separator(),
slider_blue_->Render(),
separator(),
ColorString(*red_, *green_, *blue_),
}) | xflex,
}) |
border | size(WIDTH, LESS_THAN, 80);
}
bool OnEvent(Event event) {
if (event == Event::Return || event == Event::Escape)
quit_();
return ComponentBase::OnEvent(event);
}
};
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::TerminalOutput();
int red = 128;
int green = 25;
int blue = 100;
screen.Loop(Make<MyComponent>(&red, &green, &blue, screen.ExitLoopClosure()));
}
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -26,6 +26,8 @@ Component Input(std::wstring* content, const std::wstring* placeholder);
Component Menu(const std::vector<std::wstring>* entries, int* selected_); Component Menu(const std::vector<std::wstring>* entries, int* selected_);
Component Radiobox(const std::vector<std::wstring>* entries, int* selected_); Component Radiobox(const std::vector<std::wstring>* entries, int* selected_);
Component Toggle(const std::vector<std::wstring>* entries, int* selected); Component Toggle(const std::vector<std::wstring>* entries, int* selected);
Component Renderer(Component child, std::function<Element()>);
Component Renderer(std::function<Element()>);
template <class T> // T = {int, float} template <class T> // T = {int, float}
Component Slider(std::wstring label, T* value, T min, T max, T increment); Component Slider(std::wstring label, T* value, T min, T max, T increment);

View File

@ -0,0 +1,44 @@
#include <functional> // for function
#include <memory> // for shared_ptr
#include "ftxui/component/component.hpp" // for Make
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/dom/elements.hpp" // for Element
namespace ftxui {
/// @brief A component rendering Element from a function.
/// @ingroup component.
class RendererBase : public ComponentBase {
public:
// Access this interface from a Component
static RendererBase* From(Component component) {
return static_cast<RendererBase*>(component.get());
}
// Constructor.
RendererBase(std::function<Element()> render) : render_(std::move(render)) {}
~RendererBase() override = default;
// Component implementation.
Element Render() override { return render_(); }
protected:
std::function<Element()> render_;
};
Component Renderer(std::function<Element()> render) {
return Make<RendererBase>(std::move(render));
}
Component Renderer(Component child, std::function<Element()> render) {
Component renderer = Renderer(std::move(render));
renderer->Add(std::move(child));
return renderer;
}
} // namespace ftxui
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.