mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-25 20:27:31 +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/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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
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 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);
|
||||||
|
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