mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-22 18:59:59 +08:00
Add the Renderer component.
This commit is contained in:
parent
6d75cb2748
commit
c9aa1805eb
@ -99,6 +99,7 @@ add_library(component
|
||||
src/ftxui/component/menu.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/slider.cpp
|
||||
src/ftxui/component/terminal_input_parser.cpp
|
||||
|
@ -1,43 +1,36 @@
|
||||
#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_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/container.hpp" // for Container
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for separator, Element, gauge, text, operator|, vbox, border
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
class MyComponent : public ComponentBase {
|
||||
private:
|
||||
std::wstring label_add = L"Increase";
|
||||
std::wstring label_rm = L"Decrease";
|
||||
int value_ = 50;
|
||||
int main(int argc, const char* argv[]) {
|
||||
int value = 50;
|
||||
std::wstring label_dec = L"decrease";
|
||||
std::wstring label_inc = L"increase";
|
||||
|
||||
public:
|
||||
MyComponent() {
|
||||
Add(Container::Horizontal({
|
||||
Button(&label_rm, [&] { value_--; }),
|
||||
Button(&label_add, [&] { value_++; }),
|
||||
}));
|
||||
}
|
||||
// The tree of components. This defines how to navigate using the keyboard.
|
||||
auto buttons = Container::Horizontal({
|
||||
Button(&label_dec, [&] { value--; }),
|
||||
Button(&label_inc, [&] { value++; }),
|
||||
});
|
||||
|
||||
Element Render() override {
|
||||
// Modify the way to render them on screen:
|
||||
auto component = Renderer(buttons, [&] {
|
||||
return vbox({
|
||||
text(L"Value = " + std::to_wstring(value_)),
|
||||
text(L"value = " + std::to_wstring(value)),
|
||||
separator(),
|
||||
gauge(value_ * 0.01f),
|
||||
gauge(value * 0.01f),
|
||||
separator(),
|
||||
ComponentBase::Render(),
|
||||
buttons->Render(),
|
||||
}) |
|
||||
border;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::FitComponent();
|
||||
screen.Loop(Make<MyComponent>());
|
||||
screen.Loop(component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
class MyComponent : public ComponentBase {
|
||||
private:
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::wstring build_examples_label = L"Build examples";
|
||||
std::wstring build_tests_label = L"Build tests";
|
||||
std::wstring use_webassembly_label = L"Use WebAssembly";
|
||||
@ -16,19 +15,14 @@ class MyComponent : public ComponentBase {
|
||||
bool build_tests_state = false;
|
||||
bool use_webassembly_state = true;
|
||||
|
||||
Component container = Container::Vertical({
|
||||
auto component = Container::Vertical({
|
||||
Checkbox(&build_examples_label, &build_examples_state),
|
||||
Checkbox(&build_tests_label, &build_tests_state),
|
||||
Checkbox(&use_webassembly_label, &use_webassembly_state),
|
||||
});
|
||||
|
||||
public:
|
||||
MyComponent() { Add(container); }
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
screen.Loop(Make<MyComponent>());
|
||||
screen.Loop(component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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 <string> // for operator+, wstring
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Make
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/container.hpp" // for Container
|
||||
@ -13,49 +11,28 @@
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
struct CheckboxAndState {
|
||||
struct CheckboxState {
|
||||
std::wstring label;
|
||||
bool state;
|
||||
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();
|
||||
bool checked;
|
||||
};
|
||||
|
||||
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 my_component = Make<MyComponent>();
|
||||
screen.Loop(my_component);
|
||||
screen.Loop(component);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,111 +12,117 @@
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
class MyComponent : public ComponentBase {
|
||||
const std::vector<std::wstring> menu_entries_ = {
|
||||
// Display a component nicely with a title on the left.
|
||||
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 2",
|
||||
L"Menu 3",
|
||||
L"Menu 4",
|
||||
};
|
||||
int menu_selected_ = 0;
|
||||
Component menu_ = Menu(&menu_entries_, &menu_selected_);
|
||||
int menu_selected = 0;
|
||||
auto menu = Menu(&menu_entries, &menu_selected);
|
||||
menu = Wrap(L"Menu", menu);
|
||||
|
||||
int toggle_selected_ = 0;
|
||||
std::vector<std::wstring> toggle_entries_ = {
|
||||
// -- Toggle------------------------------------------------------------------
|
||||
int toggle_selected = 0;
|
||||
std::vector<std::wstring> toggle_entries = {
|
||||
L"Toggle_1",
|
||||
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";
|
||||
std::wstring checkbox_2_label_ = L"checkbox2";
|
||||
bool checkbox_1_selected_ = false;
|
||||
bool checkbox_2_selected_ = false;
|
||||
// -- Checkbox ---------------------------------------------------------------
|
||||
std::wstring checkbox_1_label = L"checkbox1";
|
||||
std::wstring checkbox_2_label = L"checkbox2";
|
||||
bool checkbox_1_selected = false;
|
||||
bool checkbox_2_selected = false;
|
||||
|
||||
Component checkbox_container_ = Container::Vertical({
|
||||
Checkbox(&checkbox_1_label_, &checkbox_1_selected_),
|
||||
Checkbox(&checkbox_2_label_, &checkbox_2_selected_),
|
||||
auto checkboxes = Container::Vertical({
|
||||
Checkbox(&checkbox_1_label, &checkbox_1_selected),
|
||||
Checkbox(&checkbox_2_label, &checkbox_2_selected),
|
||||
});
|
||||
checkboxes = Wrap(L"Checkbox", checkboxes);
|
||||
|
||||
int radiobox_selected_ = 0;
|
||||
std::vector<std::wstring> radiobox_entries_ = {
|
||||
// -- Radiobox ---------------------------------------------------------------
|
||||
int radiobox_selected = 0;
|
||||
std::vector<std::wstring> radiobox_entries = {
|
||||
L"Radiobox 1",
|
||||
L"Radiobox 2",
|
||||
L"Radiobox 3",
|
||||
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_;
|
||||
std::wstring input_placeholder_ = L"input";
|
||||
Component input_ = Input(&input_label_, &input_placeholder_);
|
||||
// -- Input ------------------------------------------------------------------
|
||||
std::wstring input_label;
|
||||
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_;
|
||||
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;
|
||||
int slider_value_2_ = 56;
|
||||
int slider_value_3_ = 128;
|
||||
Component slider_container_ = Container::Vertical({
|
||||
Slider(L"R:", &slider_value_1_, 0, 256, 1),
|
||||
Slider(L"G:", &slider_value_2_, 0, 256, 1),
|
||||
Slider(L"B:", &slider_value_3_, 0, 256, 1),
|
||||
// -- Slider -----------------------------------------------------------------
|
||||
int slider_value_1 = 12;
|
||||
int slider_value_2 = 56;
|
||||
int slider_value_3 = 128;
|
||||
auto sliders = Container::Vertical({
|
||||
Slider(L"R:", &slider_value_1, 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:
|
||||
MyComponent(std::function<void(void)> on_quit) : on_quit_(on_quit) {
|
||||
Add(Container::Vertical({
|
||||
menu_,
|
||||
toggle_,
|
||||
checkbox_container_,
|
||||
radiobox_,
|
||||
input_,
|
||||
slider_container_,
|
||||
button_,
|
||||
}));
|
||||
}
|
||||
|
||||
Element Render(std::wstring name, Element element) {
|
||||
return hbox({
|
||||
text(name) | size(WIDTH, EQUAL, 8),
|
||||
auto component = Renderer(layout, [&] {
|
||||
return vbox({
|
||||
menu->Render(),
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -20,32 +20,32 @@
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
int shift = 0;
|
||||
class Graph {
|
||||
public:
|
||||
std::vector<int> operator()(int width, int height) {
|
||||
std::vector<int> output(width);
|
||||
for (int i = 0; i < width; ++i) {
|
||||
float v = 0;
|
||||
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;
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
|
||||
int shift = 0;
|
||||
|
||||
class Graph {
|
||||
public:
|
||||
Graph(int* shift) : shift_(shift) {}
|
||||
std::vector<int> operator()(int width, int height) {
|
||||
std::vector<int> output(width);
|
||||
for (int i = 0; i < width; ++i) {
|
||||
float v = 0;
|
||||
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;
|
||||
|
||||
public:
|
||||
HTopComponent() {}
|
||||
~HTopComponent() override {}
|
||||
|
||||
Element Render() override {
|
||||
Graph my_graph(&shift);
|
||||
auto htop = Renderer([&] {
|
||||
auto frequency = vbox({
|
||||
text(L"Frequency [Mhz]") | hcenter,
|
||||
hbox({
|
||||
@ -98,52 +98,50 @@ class HTopComponent : public ComponentBase {
|
||||
ram | flex,
|
||||
}) |
|
||||
flex | border;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const std::vector<std::wstring> compiler_entries = {
|
||||
L"gcc",
|
||||
L"clang",
|
||||
L"emcc",
|
||||
L"game_maker",
|
||||
L"Ada compilers",
|
||||
L"ALGOL 60 compilers",
|
||||
L"ALGOL 68 compilers",
|
||||
L"Assemblers (Intel *86)",
|
||||
L"Assemblers (Motorola 68*)",
|
||||
L"Assemblers (Zilog Z80)",
|
||||
L"Assemblers (other)",
|
||||
L"BASIC Compilers",
|
||||
L"BASIC interpreters",
|
||||
L"Batch compilers",
|
||||
L"C compilers",
|
||||
L"Source-to-source compilers",
|
||||
L"C++ compilers",
|
||||
L"C# compilers",
|
||||
L"COBOL compilers",
|
||||
L"Common Lisp compilers",
|
||||
L"D compilers",
|
||||
L"DIBOL/DBL compilers",
|
||||
L"ECMAScript interpreters",
|
||||
L"Eiffel compilers",
|
||||
L"Fortran compilers",
|
||||
L"Go compilers",
|
||||
L"Haskell compilers",
|
||||
L"Java compilers",
|
||||
L"Pascal compilers",
|
||||
L"Perl Interpreters",
|
||||
L"PHP compilers",
|
||||
L"PL/I compilers",
|
||||
L"Python compilers",
|
||||
L"Scheme compilers and interpreters",
|
||||
L"Smalltalk compilers",
|
||||
L"Tcl Interpreters",
|
||||
L"VMS Interpreters",
|
||||
L"Rexx Interpreters",
|
||||
L"CLI compilers",
|
||||
};
|
||||
const std::vector<std::wstring> compiler_entries = {
|
||||
L"gcc",
|
||||
L"clang",
|
||||
L"emcc",
|
||||
L"game_maker",
|
||||
L"Ada compilers",
|
||||
L"ALGOL 60 compilers",
|
||||
L"ALGOL 68 compilers",
|
||||
L"Assemblers (Intel *86)",
|
||||
L"Assemblers (Motorola 68*)",
|
||||
L"Assemblers (Zilog Z80)",
|
||||
L"Assemblers (other)",
|
||||
L"BASIC Compilers",
|
||||
L"BASIC interpreters",
|
||||
L"Batch compilers",
|
||||
L"C compilers",
|
||||
L"Source-to-source compilers",
|
||||
L"C++ compilers",
|
||||
L"C# compilers",
|
||||
L"COBOL compilers",
|
||||
L"Common Lisp compilers",
|
||||
L"D compilers",
|
||||
L"DIBOL/DBL compilers",
|
||||
L"ECMAScript interpreters",
|
||||
L"Eiffel compilers",
|
||||
L"Fortran compilers",
|
||||
L"Go compilers",
|
||||
L"Haskell compilers",
|
||||
L"Java compilers",
|
||||
L"Pascal compilers",
|
||||
L"Perl Interpreters",
|
||||
L"PHP compilers",
|
||||
L"PL/I compilers",
|
||||
L"Python compilers",
|
||||
L"Scheme compilers and interpreters",
|
||||
L"Smalltalk compilers",
|
||||
L"Tcl Interpreters",
|
||||
L"VMS Interpreters",
|
||||
L"Rexx Interpreters",
|
||||
L"CLI compilers",
|
||||
};
|
||||
|
||||
class CompilerComponent : public ComponentBase {
|
||||
int compiler_selected = 0;
|
||||
Component compiler = Radiobox(&compiler_entries, &compiler_selected);
|
||||
|
||||
@ -178,28 +176,48 @@ class CompilerComponent : public ComponentBase {
|
||||
Checkbox(&options_label[3], &options_state[3]),
|
||||
});
|
||||
|
||||
public:
|
||||
~CompilerComponent() override {}
|
||||
CompilerComponent() {
|
||||
Add(Container::Horizontal({
|
||||
compiler,
|
||||
flags,
|
||||
Container::Vertical({
|
||||
executable_,
|
||||
Container::Horizontal({
|
||||
input_add,
|
||||
input,
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
auto compiler_component = Container::Horizontal({
|
||||
compiler,
|
||||
flags,
|
||||
Container::Vertical({
|
||||
executable_,
|
||||
Container::Horizontal({
|
||||
input_add,
|
||||
input,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
InputBase::From(input_add)->on_enter = [this] {
|
||||
input_entries.push_back(input_add_content);
|
||||
input_add_content = L"";
|
||||
};
|
||||
}
|
||||
InputBase::From(input_add)->on_enter = [&] {
|
||||
input_entries.push_back(input_add_content);
|
||||
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 flags_win = window(text(L"Flags"), flags->Render());
|
||||
auto executable_win = window(text(L"Executable:"), executable_->Render());
|
||||
@ -227,50 +245,21 @@ class CompilerComponent : public ComponentBase {
|
||||
}),
|
||||
filler(),
|
||||
}),
|
||||
hflow(RenderCommandLine()) | flex_grow,
|
||||
hflow(render_command()) | flex_grow,
|
||||
}) |
|
||||
flex_grow | border;
|
||||
}
|
||||
});
|
||||
|
||||
Elements RenderCommandLine() {
|
||||
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 {
|
||||
auto spinner_tab_renderer = Renderer([&] {
|
||||
Elements entries;
|
||||
for (int i = 0; i < 22; ++i) {
|
||||
if (i != 0)
|
||||
entries.push_back(spinner(i, shift / 2) | bold |
|
||||
size(WIDTH, GREATER_THAN, 2) | border);
|
||||
entries.push_back(spinner(i, shift / 2) | bold |
|
||||
size(WIDTH, GREATER_THAN, 2) | border);
|
||||
}
|
||||
return hflow(std::move(entries)) | border;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
class ColorComponent : public ComponentBase {
|
||||
Element Render() override {
|
||||
auto color_tab_renderer = Renderer([] {
|
||||
return hbox({
|
||||
vbox({
|
||||
color(Color::Default, text(L"Default")),
|
||||
@ -312,79 +301,67 @@ class ColorComponent : public ComponentBase {
|
||||
}),
|
||||
}) |
|
||||
hcenter | border;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
class GaugeComponent : public ComponentBase {
|
||||
Element RenderGauge(int delta) {
|
||||
auto render_gauge = [&shift](int delta) {
|
||||
float progress = (shift + delta) % 1000 / 1000.f;
|
||||
return hbox({
|
||||
text(std::to_wstring(int(progress * 100)) + L"% ") |
|
||||
size(WIDTH, EQUAL, 5),
|
||||
gauge(progress),
|
||||
});
|
||||
}
|
||||
Element Render() override {
|
||||
};
|
||||
|
||||
auto gauge_component = Renderer([render_gauge] {
|
||||
return vbox({
|
||||
RenderGauge(0) | color(Color::Black),
|
||||
RenderGauge(100) | color(Color::GrayDark),
|
||||
RenderGauge(50) | color(Color::GrayLight),
|
||||
RenderGauge(6894) | color(Color::White),
|
||||
render_gauge(0) | color(Color::Black),
|
||||
render_gauge(100) | color(Color::GrayDark),
|
||||
render_gauge(50) | color(Color::GrayLight),
|
||||
render_gauge(6894) | color(Color::White),
|
||||
separator(),
|
||||
RenderGauge(6841) | color(Color::Blue),
|
||||
RenderGauge(9813) | color(Color::BlueLight),
|
||||
RenderGauge(98765) | color(Color::Cyan),
|
||||
RenderGauge(98) | color(Color::CyanLight),
|
||||
RenderGauge(9846) | color(Color::Green),
|
||||
RenderGauge(1122) | color(Color::GreenLight),
|
||||
RenderGauge(84) | color(Color::Magenta),
|
||||
RenderGauge(645) | color(Color::MagentaLight),
|
||||
RenderGauge(568) | color(Color::Red),
|
||||
RenderGauge(2222) | color(Color::RedLight),
|
||||
RenderGauge(220) | color(Color::Yellow),
|
||||
RenderGauge(348) | color(Color::YellowLight),
|
||||
render_gauge(6841) | color(Color::Blue),
|
||||
render_gauge(9813) | color(Color::BlueLight),
|
||||
render_gauge(98765) | color(Color::Cyan),
|
||||
render_gauge(98) | color(Color::CyanLight),
|
||||
render_gauge(9846) | color(Color::Green),
|
||||
render_gauge(1122) | color(Color::GreenLight),
|
||||
render_gauge(84) | color(Color::Magenta),
|
||||
render_gauge(645) | color(Color::MagentaLight),
|
||||
render_gauge(568) | color(Color::Red),
|
||||
render_gauge(2222) | color(Color::RedLight),
|
||||
render_gauge(220) | color(Color::Yellow),
|
||||
render_gauge(348) | color(Color::YellowLight),
|
||||
}) |
|
||||
border;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
class Tab : public ComponentBase {
|
||||
public:
|
||||
int tab_index = 0;
|
||||
std::vector<std::wstring> tab_entries = {
|
||||
L"htop", L"color", L"spinner", L"gauge", L"compiler",
|
||||
};
|
||||
Component tab_selection = Toggle(&tab_entries, &tab_index);
|
||||
Component container =
|
||||
Container::Tab(&tab_index,
|
||||
{
|
||||
std::make_shared<HTopComponent>(),
|
||||
std::make_shared<ColorComponent>(),
|
||||
std::make_shared<SpinnerComponent>(),
|
||||
std::make_shared<GaugeComponent>(),
|
||||
std::make_shared<CompilerComponent>(),
|
||||
});
|
||||
auto tab_selection = Toggle(&tab_entries, &tab_index);
|
||||
auto tab_content = Container::Tab(&tab_index, {
|
||||
htop,
|
||||
color_tab_renderer,
|
||||
spinner_tab_renderer,
|
||||
gauge_component,
|
||||
compiler_renderer,
|
||||
});
|
||||
|
||||
Component main_container = Container::Vertical({
|
||||
auto main_container = Container::Vertical({
|
||||
tab_selection,
|
||||
container,
|
||||
tab_content,
|
||||
});
|
||||
|
||||
Tab() { Add(main_container); }
|
||||
|
||||
Element Render() override {
|
||||
auto main_renderer = Renderer(main_container, [&] {
|
||||
return vbox({
|
||||
text(L"FTXUI Demo") | bold | hcenter,
|
||||
tab_selection->Render() | hcenter,
|
||||
container->Render() | flex,
|
||||
tab_content->Render() | flex,
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
|
||||
std::thread update([&screen]() {
|
||||
std::thread update([&screen, &shift]() {
|
||||
for (;;) {
|
||||
using namespace std::chrono_literals;
|
||||
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(tab);
|
||||
screen.Loop(main_renderer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
83
examples/component/slider_rgb.cpp
Normal file
83
examples/component/slider_rgb.cpp
Normal 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.
|
@ -26,6 +26,8 @@ Component Input(std::wstring* content, const std::wstring* placeholder);
|
||||
Component Menu(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 Renderer(Component child, std::function<Element()>);
|
||||
Component Renderer(std::function<Element()>);
|
||||
|
||||
template <class T> // T = {int, float}
|
||||
Component Slider(std::wstring label, T* value, T min, T max, T increment);
|
||||
|
44
src/ftxui/component/renderer.cpp
Normal file
44
src/ftxui/component/renderer.cpp
Normal 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.
|
Loading…
Reference in New Issue
Block a user