button
Demo
#include <memory>
#include <string>
auto option = ButtonOption::Animated();
auto element = text(s.label);
if (s.focused) {
element |= bold;
}
return element | center | borderEmpty | flex;
};
return option;
}
int value = 50;
auto btn_dec_01 = Button(
"-1", [&] { value -= 1; },
Style());
auto btn_inc_01 = Button(
"+1", [&] { value += 1; },
Style());
auto btn_dec_10 = Button(
"-10", [&] { value -= 10; },
Style());
auto btn_inc_10 = Button(
"+10", [&] { value += 10; },
Style());
int row = 0;
auto buttons = Container::Vertical({
Container::Horizontal({btn_dec_01, btn_inc_01}, &row) | flex,
Container::Horizontal({btn_dec_10, btn_inc_10}, &row) | flex,
});
auto component = Renderer(buttons, [&] {
return vbox({
text("value = " + std::to_string(value)),
separator(),
buttons->Render() | flex,
}) |
flex | border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
L'espace de noms FTXUI ftxui::
arguments pour la transformation depuis |ButtonOption|, |CheckboxOption|, |RadioboxOption|,...
button_animated
Demo
#include <memory>
#include <string>
int value = 50;
auto buttons = Container::Horizontal({
Button(
"Decrease", [&] { value--; }, ButtonOption::Animated(Color::Red)),
Button(
"Reset", [&] { value = 50; }, ButtonOption::Animated(Color::Green)),
Button(
"Increase", [&] { value++; }, ButtonOption::Animated(Color::Blue)),
});
auto component = Renderer(buttons, [&] {
return vbox({
vbox({
text("value = " + std::to_string(value)),
separator(),
gauge(value * 0.01f),
}) | border,
buttons->Render(),
});
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
button_in_frame
Demo
#include <memory>
#include <string>
int counter = 0;
auto on_click = [&] { counter++; };
auto style = ButtonOption::Animated(Color::Default, Color::GrayDark,
Color::Default, Color::White);
auto container = Container::Vertical({});
for (int i = 0; i < 30; ++i) {
auto button = Button("Button " + std::to_string(i), on_click, style);
container->Add(button);
}
auto renderer = Renderer(container, [&] {
return vbox({
hbox({
text("Counter:"),
text(std::to_string(counter)),
}),
separator(),
container->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 20),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
button_style
Demo
#include <string>
int value = 0;
auto action = [&] { value++; };
auto action_renderer =
Renderer([&] { return text("count = " + std::to_string(value)); });
auto buttons =
Container::Vertical({
action_renderer,
Renderer([] { return separator(); }),
Container::Horizontal({
Container::Vertical({
Button("Ascii 1", action, ButtonOption::Ascii()),
Button("Ascii 2", action, ButtonOption::Ascii()),
Button("Ascii 3", action, ButtonOption::Ascii()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Simple 1", action, ButtonOption::Simple()),
Button("Simple 2", action, ButtonOption::Simple()),
Button("Simple 3", action, ButtonOption::Simple()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Animated 1", action, ButtonOption::Animated()),
Button("Animated 2", action, ButtonOption::Animated()),
Button("Animated 3", action, ButtonOption::Animated()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Animated 4", action,
ButtonOption::Animated(Color::Red)),
Button("Animated 5", action,
ButtonOption::Animated(Color::Green)),
Button("Animated 6", action,
ButtonOption::Animated(Color::Blue)),
}),
}),
}) |
border;
auto screen = ScreenInteractive::FitComponent();
return 0;
}
canvas_animated
Demo
#include <cmath>
#include <memory>
#include <string>
#include <utility>
#include <vector>
int mouse_x = 0;
int mouse_y = 0;
auto renderer_line_braille = Renderer([&] {
c.DrawText(0, 0, "Plusieurs lignes (braille)");
c.DrawPointLine(mouse_x, mouse_y, 80, 10, Color::Red);
c.DrawPointLine(80, 10, 80, 40, Color::Blue);
c.DrawPointLine(80, 40, mouse_x, mouse_y, Color::Green);
return canvas(std::move(c));
});
auto renderer_line_block = Renderer([&] {
c.DrawText(0, 0, "Plusieurs lignes (bloc)");
c.DrawBlockLine(mouse_x, mouse_y, 80, 10, Color::Red);
c.DrawBlockLine(80, 10, 80, 40, Color::Blue);
c.DrawBlockLine(80, 40, mouse_x, mouse_y, Color::Green);
return canvas(std::move(c));
});
auto renderer_circle_braille = Renderer([&] {
c.DrawText(0, 0, "Un cercle (braille)");
c.DrawPointCircle(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
auto renderer_circle_block = Renderer([&] {
c.DrawText(0, 0, "Un cercle (bloc)");
c.DrawBlockCircle(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
auto renderer_circle_filled_braille = Renderer([&] {
c.DrawText(0, 0, "Un cercle rempli (braille)");
c.DrawPointCircleFilled(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
auto renderer_circle_filled_block = Renderer([&] {
c.DrawText(0, 0, "Un cercle rempli (bloc)");
c.DrawBlockCircleFilled(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
auto renderer_ellipse_braille = Renderer([&] {
c.DrawText(0, 0, "Une ellipse (braille)");
c.DrawPointEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
auto renderer_ellipse_block = Renderer([&] {
c.DrawText(0, 0, "Une ellipse (bloc)");
c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
auto renderer_ellipse_filled_braille = Renderer([&] {
c.DrawText(0, 0, "Une ellipse remplie (braille)");
c.DrawPointEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
mouse_y / 2);
return canvas(std::move(c));
});
auto renderer_ellipse_filled_block = Renderer([&] {
c.DrawText(0, 0, "Une ellipse remplie (bloc)");
c.DrawBlockEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
mouse_y / 2);
c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
auto renderer_text = Renderer([&] {
c.DrawText(0, 0, "Un morceau de texte");
c.DrawText(mouse_x, mouse_y, "Ceci est un morceau de texte avec des effets",
});
return canvas(std::move(c));
});
auto renderer_plot_1 = Renderer([&] {
c.DrawText(0, 0, "Un graphique");
std::vector<int> ys(100);
for (int x = 0; x < 100; x++) {
float dx = float(x - mouse_x);
float dy = 50.f;
ys[x] = int(dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42));
}
for (int x = 1; x < 99; x++) {
c.DrawPointLine(x, ys[x], x + 1, ys[x + 1]);
}
return canvas(std::move(c));
});
auto renderer_plot_2 = Renderer([&] {
c.DrawText(0, 0, "Un graphique symétrique rempli");
std::vector<int> ys(100);
for (int x = 0; x < 100; x++) {
ys[x] = int(30 +
10 * cos(x * 0.2 - mouse_x * 0.05) +
5 * sin(x * 0.4) +
5 * sin(x * 0.3 - mouse_y * 0.05));
}
for (int x = 0; x < 100; x++) {
c.DrawPointLine(x, 50 + ys[x], x, 50 - ys[x], Color::Red);
}
return canvas(std::move(c));
});
auto renderer_plot_3 = Renderer([&] {
c.DrawText(0, 0, "Un tracé gaussien 2D");
int size = 15;
float my = (mouse_y - 90) / -5.f;
float mx = (mouse_x - 3 * my) / 5.f;
std::vector<std::vector<float>> ys(size, std::vector<float>(size));
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
float dx = x - mx;
float dy = y - my;
ys[y][x] = -1.5 + 3.0 * std::exp(-0.2f * (dx * dx + dy * dy));
}
}
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
if (x != 0) {
c.DrawPointLine(
5 * (x - 1) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x - 1],
5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
}
if (y != 0) {
c.DrawPointLine(
5 * (x - 0) + 3 * (y - 1), 90 - 5 * (y - 1) - 5 * ys[y - 1][x],
5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
}
}
}
return canvas(std::move(c));
});
int selected_tab = 12;
auto tab = Container::Tab(
{
renderer_line_braille,
renderer_line_block,
renderer_circle_braille,
renderer_circle_block,
renderer_circle_filled_braille,
renderer_circle_filled_block,
renderer_ellipse_braille,
renderer_ellipse_block,
renderer_ellipse_filled_braille,
renderer_ellipse_filled_block,
renderer_plot_1,
renderer_plot_2,
renderer_plot_3,
renderer_text,
},
&selected_tab);
auto tab_with_mouse = CatchEvent(tab, [&](
Event e) {
mouse_x = (e.
mouse().x - 1) * 2;
mouse_y = (e.
mouse().y - 1) * 4;
}
return false;
});
std::vector<std::string> tab_titles = {
"ligne (braille)",
"ligne (bloc)",
"cercle (braille)",
"cercle (bloc)",
"cercle rempli (braille)",
"cercle rempli (bloc)",
"ellipse (braille)",
"ellipse (bloc)",
"ellipse remplie (braille)",
"ellipse remplie (bloc)",
"graphique_1 simple",
"graphique_2 rempli",
"graphique_3 3D",
"texte",
};
auto tab_toggle = Menu(&tab_titles, &selected_tab);
auto component = Container::Horizontal({
tab_with_mouse,
tab_toggle,
});
auto component_renderer = Renderer(component, [&] {
return hbox({
tab_with_mouse->Render(),
separator(),
tab_toggle->Render(),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(component_renderer);
return 0;
}
Représente un événement. Il peut s'agir d'un événement de touche, d'un redimensionnement de terminal,...
Canvas est un tampon dessinable associé aux opérations de dessin.
Un caractère Unicode et son style associé.
checkbox
Demo
#include <array>
#include <iostream>
#include <memory>
#include <string>
bool download = false;
bool upload = false;
bool ping = false;
auto container = Container::Vertical({
Checkbox("Download", &download),
Checkbox("Upload", &upload),
Checkbox("Ping", &ping),
});
auto screen = ScreenInteractive::FitComponent();
std::cout << "---" << std::endl;
std::cout << "Download: " << download << std::endl;
std::cout << "Upload: " << upload << std::endl;
std::cout << "Ping: " << ping << std::endl;
std::cout << "---" << std::endl;
return 0;
}
checkbox_in_frame
Demo
#include <array>
#include <memory>
#include <string>
std::array<bool, 30> states;
auto container = Container::Vertical({});
for (int i = 0; i < 30; ++i) {
states[i] = false;
container->Add(Checkbox("Checkbox" + std::to_string(i), &states[i]));
}
auto renderer = Renderer(container, [&] {
return container->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
collapsible
Demo
#include <memory>
#include <utility>
#include <vector>
Component vlist = Container::Vertical(std::move(children));
return Renderer(vlist, [vlist] {
return hbox({
text(" "),
vlist->Render(),
});
});
}
return std::make_shared<ComponentBase>();
}
auto component =
Collapsible("Réductible 1",
Collapsible("Réductible 1.1",
Collapsible(
"Réductible 1.1.1",
Empty()),
Collapsible(
"Réductible 1.1.2",
Empty()),
Collapsible(
"Réductible 1.1.3",
Empty()),
})),
Collapsible("Réductible 1.2",
Collapsible(
"Réductible 1.2.1",
Empty()),
Collapsible(
"Réductible 1.2.2",
Empty()),
Collapsible(
"Réductible 1.2.3",
Empty()),
})),
Collapsible("Réductible 1.3",
Collapsible(
"Réductible 1.3.1",
Empty()),
Collapsible(
"Réductible 1.3.2",
Empty()),
Collapsible(
"Réductible 1.3.3",
Empty()),
})),
}));
ScreenInteractive::FitComponent().Loop(component);
}
Component Inner(std::vector< Component > children)
std::shared_ptr< ComponentBase > Component
composition
Demo
#include <memory>
#include <string>
auto left_count = 0;
auto right_count = 0;
auto left_buttons = Container::Horizontal({
Button("Decrease", [&] { left_count--; }),
Button("Increase", [&] { left_count++; }),
});
auto right_buttons = Container::Horizontal({
Button("Decrease", [&] { right_count--; }),
Button("Increase", [&] { right_count++; }),
});
return vbox({
text("This is the left control"),
separator(),
text("Left button count: " + std::to_string(left_count)),
left_buttons->Render(),
}) |
border;
});
auto rightpane = Renderer(right_buttons, [&] {
return vbox({
text("This is the right control"),
separator(),
text("Right button count: " + std::to_string(right_count)),
right_buttons->Render(),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
custom_loop
Demo
#include <stdlib.h>
#include <chrono>
#include <memory>
#include <string>
#include <thread>
auto screen = ScreenInteractive::FitComponent();
int custom_loop_count = 0;
int frame_count = 0;
int event_count = 0;
auto component = Renderer([&] {
frame_count++;
return vbox({
text("Ceci démontre l'utilisation d'une ftxui::Loop personnalisée. Elle "),
text("s'exécute à 100 itérations par seconde. Les événements FTXUI "),
text("sont tous traités une fois par itération et une nouvelle image "),
text("est rendue si nécessaire"),
separator(),
text("ftxui event count: " + std::to_string(event_count)),
text("ftxui frame count: " + std::to_string(frame_count)),
text("Custom loop count: " + std::to_string(custom_loop_count)),
}) |
border;
});
component |= CatchEvent([&](
Event) ->
bool {
event_count++;
return false;
});
while (!loop.HasQuitted()) {
custom_loop_count++;
loop.RunOnce();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return EXIT_SUCCESS;
}
Loop est une classe qui gère la boucle d'événements pour un composant.
dropdown
Demo
#include <string>
#include <vector>
std::vector<std::string> entries = {
"tribute", "clearance", "ally", "bend", "electronics",
"module", "era", "cultural", "sniff", "nationalism",
"negotiation", "deliver", "figure", "east", "tribute",
"clearance", "ally", "bend", "electronics", "module",
"era", "cultural", "sniff", "nationalism", "negotiation",
"deliver", "figure", "east", "tribute", "clearance",
"ally", "bend", "electronics", "module", "era",
"cultural", "sniff", "nationalism", "negotiation", "deliver",
"figure", "east",
};
int selected_1 = 0;
int selected_2 = 0;
int selected_3 = 0;
int selected_4 = 0;
auto layout = Container::Vertical({
Container::Horizontal({
Dropdown(&entries, &selected_1),
Dropdown(&entries, &selected_2),
}),
Container::Horizontal({
Dropdown(&entries, &selected_3),
Dropdown(&entries, &selected_4),
}),
});
auto screen = ScreenInteractive::FitComponent();
}
dropdown_custom
Demo
#include <string>
#include <vector>
std::vector<std::string> entries = {
"tribute", "clearance", "ally", "bend", "electronics",
"module", "era", "cultural", "sniff", "nationalism",
"negotiation", "deliver", "figure", "east", "tribute",
"clearance", "ally", "bend", "electronics", "module",
"era", "cultural", "sniff", "nationalism", "negotiation",
"deliver", "figure", "east", "tribute", "clearance",
"ally", "bend", "electronics", "module", "era",
"cultural", "sniff", "nationalism", "negotiation", "deliver",
"figure", "east",
};
auto dropdown_1 = Dropdown({
.radiobox = {.entries = &entries},
.transform =
if (open) {
return vbox({
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10),
filler(),
});
}
return vbox({
checkbox,
filler(),
});
},
});
auto dropdown_2 = Dropdown({
.radiobox = {.entries = &entries},
.transform =
if (open) {
return vbox({
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) |
bgcolor(Color::Blue),
filler(),
});
}
return vbox({
filler(),
});
},
});
auto dropdown_3 = Dropdown({
.radiobox =
{
.entries = &entries,
.transform =
auto t = text(s.label) | borderEmpty;
if (s.active) {
t |= bold;
}
if (s.focused) {
t |= inverted;
}
return t;
},
},
.transform =
checkbox |= borderEmpty;
if (open) {
return vbox({
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 20) |
bgcolor(Color::Red),
filler(),
});
}
return vbox({
filler(),
});
},
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(Container::Horizontal({
dropdown_1,
dropdown_2,
dropdown_3,
}));
}
Element bgcolor(const LinearGradient &gradient, Element child)
Définit la couleur de fond d'un élément avec un effet de dégradé linéaire.
std::shared_ptr< Node > Element
flexbox_gallery
Demo
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
auto screen = ScreenInteractive::Fullscreen();
int direction_index = 0;
int wrap_index = 0;
int justify_content_index = 0;
int align_items_index = 0;
int align_content_index = 0;
std::vector<std::string> directions = {
"Row",
"RowInversed",
"Column",
"ColumnInversed",
};
std::vector<std::string> wraps = {
"NoWrap",
"Wrap",
"WrapInversed",
};
std::vector<std::string> justify_content = {
"FlexStart", "FlexEnd", "Center", "Stretch",
"SpaceBetween", "SpaceAround", "SpaceEvenly",
};
std::vector<std::string> align_items = {
"FlexStart",
"FlexEnd",
"Center",
"Stretch",
};
std::vector<std::string> align_content = {
"FlexStart", "FlexEnd", "Center", "Stretch",
"SpaceBetween", "SpaceAround", "SpaceEvenly",
};
auto radiobox_direction = Radiobox(&directions, &direction_index);
auto radiobox_wrap = Radiobox(&wraps, &wrap_index);
auto radiobox_justify_content =
Radiobox(&justify_content, &justify_content_index);
auto radiobox_align_items = Radiobox(&align_items, &align_items_index);
auto radiobox_align_content = Radiobox(&align_content, &align_content_index);
bool element_xflex_grow = false;
bool element_yflex_grow = false;
bool group_xflex_grow = true;
bool group_yflex_grow = true;
auto checkbox_element_xflex_grow =
Checkbox("element |= xflex_grow", &element_xflex_grow);
auto checkbox_element_yflex_grow =
Checkbox("element |= yflex_grow", &element_yflex_grow);
auto checkbox_group_xflex_grow =
Checkbox("group |= xflex_grow", &group_xflex_grow);
auto checkbox_group_yflex_grow =
Checkbox("group |= yflex_grow", &group_yflex_grow);
auto make_box = [&](
size_t dimx,
size_t dimy,
size_t index) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
auto element = window(text(title) | hcenter | bold,
text(std::to_string(index)) | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy) |
bgcolor(Color::HSV(index * 25, 255, 255)) |
if (element_xflex_grow) {
element = element | xflex_grow;
}
if (element_yflex_grow) {
element = element | yflex_grow;
}
return element;
};
auto content_renderer = Renderer([&] {
auto group = flexbox(
{
},
config);
group = group |
bgcolor(Color::Black);
group = group | notflex;
if (!group_xflex_grow) {
group = hbox(group, filler());
}
if (!group_yflex_grow) {
group = vbox(group, filler());
}
group = group | flex;
return group;
});
.
Set(FlexboxConfig::JustifyContent::Center)
.
Set(FlexboxConfig::AlignContent::Center);
int space_right = 10;
int space_bottom = 1;
content_renderer = ResizableSplitRight(
Renderer([&] { return flexbox({text("resizable")}, center); }),
content_renderer, &space_right);
content_renderer = ResizableSplitBottom(
Renderer([&] { return flexbox({text("resizable")}, center); }),
content_renderer, &space_bottom);
auto main_container = Container::Vertical({
Container::Horizontal({
radiobox_direction,
radiobox_wrap,
Container::Vertical({
checkbox_element_xflex_grow,
checkbox_element_yflex_grow,
checkbox_group_xflex_grow,
checkbox_group_yflex_grow,
}),
}),
Container::Horizontal({
radiobox_justify_content,
radiobox_align_items,
radiobox_align_content,
}),
content_renderer,
});
auto main_renderer = Renderer(main_container, [&] {
return vbox({
vbox({hbox({
window(text("FlexboxConfig::Direction"),
radiobox_direction->Render()),
window(text("FlexboxConfig::Wrap"), radiobox_wrap->Render()),
window(text("Misc:"),
vbox({
checkbox_element_xflex_grow->Render(),
checkbox_element_yflex_grow->Render(),
checkbox_group_xflex_grow->Render(),
checkbox_group_yflex_grow->Render(),
})),
}),
hbox({
window(text("FlexboxConfig::JustifyContent"),
radiobox_justify_content->Render()),
window(text("FlexboxConfig::AlignItems"),
radiobox_align_items->Render()),
window(text("FlexboxConfig::AlignContent"),
radiobox_align_content->Render()),
})}),
content_renderer->Render() | flex | border,
});
});
return 0;
}
Element make_box(int x, int y)
AlignContent align_content
JustifyContent justify_content
FlexboxConfig & Set(FlexboxConfig::Direction)
Définit la direction de la flexbox.
Element color(const LinearGradient &gradient, Element child)
Définit la couleur de premier plan d'un élément avec un effet de dégradé linéaire.
FlexboxConfig est une structure de configuration qui définit les propriétés de mise en page pour un c...
focus
Demo
#include <memory>
#include <string>
#include <vector>
std::string title = "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
return text(title) | center | size(WIDTH, EQUAL, 18) |
size(HEIGHT, EQUAL, 9) | border |
bgcolor(Color::HSV(x * 255 / 15, 255, y * 255 / 15));
};
std::vector<Elements> rows;
for (int i = 0; i < 15; i++) {
std::vector<Element> cols;
for (int j = 0; j < 15; j++) {
}
rows.push_back(cols);
}
return gridbox(rows);
};
float focus_x = 0.5f;
float focus_y = 0.5f;
auto slider_x = Slider("x", &focus_x, 0.f, 1.f, 0.01f);
auto slider_y = Slider("y", &focus_y, 0.f, 1.f, 0.01f);
auto renderer = Renderer(
Container::Vertical({
slider_x,
slider_y,
}),
[&] {
auto title = "focusPositionRelative(" +
std::to_string(focus_x) + ", " +
std::to_string(focus_y) + ")";
return vbox({
text(title),
separator(),
slider_x->Render(),
slider_y->Render(),
separator(),
make_grid() | focusPositionRelative(focus_x, focus_y) |
frame | flex,
}) |
border;
});
auto screen = ScreenInteractive::Fullscreen();
return 0;
}
focus_cursor
Demo
#include <string>
return Renderer([=](bool focused) {
if (focused) {
return hbox({
text("> " + label + " "),
focusCursor(text(" ")),
});
}
return text(" " + label + " ");
});
};
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(Container::Vertical({
Instance(
"focusCursorBlock", focusCursorBlock),
Instance(
"focusCursorBlockBlinking", focusCursorBlockBlinking),
Instance(
"focusCursorBar", focusCursorBar),
Instance(
"focusCursorBarBlinking", focusCursorBarBlinking),
Instance(
"focusCursorUnderline", focusCursorUnderline),
Instance(
"focusCursorUnderlineBlinking", focusCursorUnderlineBlinking),
}));
return 0;
}
Component Instance(std::string label, Decorator focusCursor)
std::function< Element(Element)> Decorator
gallery
Demo
#include <functional>
#include <memory>
#include <string>
#include <vector>
return Renderer(component, [name, component] {
return hbox({
text(name) | size(WIDTH, EQUAL, 8),
separator(),
component->Render() | xflex,
}) |
xflex;
});
}
auto screen = ScreenInteractive::FitComponent();
const std::vector<std::string> menu_entries = {
"Menu 1",
"Menu 2",
"Menu 3",
"Menu 4",
};
int menu_selected = 0;
auto menu = Menu(&menu_entries, &menu_selected);
menu =
Wrap(
"Menu", menu);
int toggle_selected = 0;
std::vector<std::string> toggle_entries = {
"Interrupteur_1",
"Interrupteur_2",
};
auto toggle = Toggle(&toggle_entries, &toggle_selected);
toggle =
Wrap(
"Toggle", toggle);
bool checkbox_1_selected = false;
bool checkbox_2_selected = false;
bool checkbox_3_selected = false;
bool checkbox_4_selected = false;
auto checkboxes = Container::Vertical({
Checkbox("case_a_cocher_1", &checkbox_1_selected),
Checkbox("case_a_cocher_2", &checkbox_2_selected),
Checkbox("case_a_cocher_3", &checkbox_3_selected),
Checkbox("case_a_cocher_4", &checkbox_4_selected),
});
checkboxes =
Wrap(
"Checkbox", checkboxes);
int radiobox_selected = 0;
std::vector<std::string> radiobox_entries = {
"Bouton radio 1",
"Bouton radio 2",
"Bouton radio 3",
"Bouton radio 4",
};
auto radiobox = Radiobox(&radiobox_entries, &radiobox_selected);
radiobox =
Wrap(
"Radiobox", radiobox);
std::string input_label;
auto input = Input(&input_label, "texte indicatif");
input =
Wrap(
"Input", input);
std::string button_label = "Quitter";
std::function<void()> on_button_clicked_;
auto button = Button(&button_label,
screen.ExitLoopClosure());
button =
Wrap(
"Button", button);
int slider_value_1 = 12;
int slider_value_2 = 56;
int slider_value_3 = 128;
auto sliders = Container::Vertical({
Slider("R:", &slider_value_1, 0, 256, 1),
Slider("G:", &slider_value_2, 0, 256, 1),
Slider("B:", &slider_value_3, 0, 256, 1),
});
sliders =
Wrap(
"Slider", sliders);
auto lorel_ipsum = Renderer([] {
return vbox({
text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "),
text("Sed do eiusmod tempor incididunt ut labore et dolore magna "
"aliqua. "),
text("Ut enim ad minim veniam, quis nostrud exercitation ullamco "
"laboris nisi ut aliquip ex ea commodo consequat. "),
text("Duis aute irure dolor in reprehenderit in voluptate velit esse "
"cillum dolore eu fugiat nulla pariatur. "),
text("Excepteur sint occaecat cupidatat non proident, sunt in culpa "
"qui officia deserunt mollit anim id est laborum. "),
});
});
lorel_ipsum =
Wrap(
"Lorel Ipsum", lorel_ipsum);
auto layout = Container::Vertical({
menu,
toggle,
checkboxes,
radiobox,
input,
sliders,
button,
lorel_ipsum,
});
auto component = Renderer(layout, [&] {
return vbox({
menu->Render(),
separator(),
toggle->Render(),
separator(),
checkboxes->Render(),
separator(),
radiobox->Render(),
separator(),
input->Render(),
separator(),
sliders->Render(),
separator(),
button->Render(),
separator(),
lorel_ipsum->Render(),
}) |
xflex | size(WIDTH, GREATER_THAN, 40) | border;
});
return 0;
}
Component Wrap(std::string name, Component component)
homescreen
Demo
#include <stddef.h>
#include <array>
#include <atomic>
#include <chrono>
#include <cmath>
#include <functional>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
#include "../dom/color_info_sorted_2d.ipp"
auto screen = ScreenInteractive::Fullscreen();
int shift = 0;
auto my_graph = [&shift](int width, int height) {
std::vector<int> output(width);
for (int i = 0; i < width; ++i) {
float v = 0.5f;
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;
output[i] = (int)v;
}
return output;
};
auto htop = Renderer([&] {
auto frequency = vbox({
text("Fréquence [Mhz]") | hcenter,
hbox({
vbox({
text("2400 "),
filler(),
text("1200 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | flex,
}) | flex,
});
auto utilization = vbox({
text("Utilisation [%]") | hcenter,
hbox({
vbox({
text("100 "),
filler(),
text("50 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) |
color(Color::RedLight),
}) | flex,
});
auto ram = vbox({
text("Ram [Mo]") | hcenter,
hbox({
vbox({
text("8192"),
filler(),
text("4096 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) |
color(Color::BlueLight),
}) | flex,
});
return hbox({
vbox({
frequency | flex,
separator(),
utilization | flex,
}) | flex,
separator(),
ram | flex,
}) |
flex;
});
const std::vector<std::string> compiler_entries = {
"gcc",
"clang",
"emcc",
"game_maker",
"Compilateurs Ada",
"Compilateurs ALGOL 60",
"Compilateurs ALGOL 68",
"Assembleurs (Intel *86)",
"Assembleurs (Motorola 68*)",
"Assembleurs (Zilog Z80)",
"Assembleurs (autres)",
"Compilateurs BASIC",
"Interprètes BASIC",
"Compilateurs Batch",
"Compilateurs C",
"Compilateurs source à source",
"Compilateurs C++",
"Compilateurs C#",
"Compilateurs COBOL",
"Compilateurs Common Lisp",
"Compilateurs D",
"Compilateurs DIBOL/DBL",
"Interprètes ECMAScript",
"Compilateurs Eiffel",
"Compilateurs Fortran",
"Compilateurs Go",
"Compilateurs Haskell",
"Compilateurs Java",
"Compilateurs Pascal",
"Interprètes Perl",
"Compilateurs PHP",
"Compilateurs PL/I",
"Compilateurs Python",
"Compilateurs et interprètes Scheme",
"Compilateurs Smalltalk",
"Interprètes Tcl",
"Interprètes VMS",
"Interprètes Rexx",
"Compilateurs CLI",
};
int compiler_selected = 0;
Component compiler = Radiobox(&compiler_entries, &compiler_selected);
std::array<std::string, 8> options_label = {
"-Wall",
"-Werror",
"-lpthread",
"-O3",
"-Wabi-tag",
"-Wno-class-conversion",
"-Wcomma-subscript",
"-Wno-conversion-null",
};
std::array<bool, 8> options_state = {
false, false, false, false, false, false, false, false,
};
std::vector<std::string> input_entries;
int input_selected = 0;
Component input = Menu(&input_entries, &input_selected);
std::string input_add_content;
input_option.on_enter = [&] {
input_entries.push_back(input_add_content);
input_add_content = "";
};
Component input_add = Input(&input_add_content,
"fichiers d'entrée", input_option);
std::string executable_content_ = "";
Component executable_ = Input(&executable_content_,
"exécutable");
Checkbox(&options_label[0], &options_state[0]),
Checkbox(&options_label[1], &options_state[1]),
Checkbox(&options_label[2], &options_state[2]),
Checkbox(&options_label[3], &options_state[3]),
Checkbox(&options_label[4], &options_state[4]),
Checkbox(&options_label[5], &options_state[5]),
Checkbox(&options_label[6], &options_state[6]),
Checkbox(&options_label[7], &options_state[7]),
});
auto compiler_component = Container::Horizontal({
compiler,
flags,
Container::Vertical({
executable_,
Container::Horizontal({
input_add,
input,
}),
}),
});
auto render_command = [&] {
line.push_back(text(compiler_entries[compiler_selected]) | bold);
for (int i = 0; i < 8; ++i) {
if (options_state[i]) {
line.push_back(text(" "));
line.push_back(text(options_label[i]) | dim);
}
}
if (!executable_content_.empty()) {
line.push_back(text(" -o ") | bold);
line.push_back(text(executable_content_) |
color(Color::BlueLight) |
bold);
}
for (auto& it : input_entries) {
line.push_back(text(
" " + it) |
color(Color::RedLight));
}
return line;
};
auto compiler_renderer = Renderer(compiler_component, [&] {
auto compiler_win = window(text("Compilateur"),
compiler->Render() | vscroll_indicator | frame);
auto flags_win =
window(text("Drapeaux"), flags->Render() | vscroll_indicator | frame);
auto executable_win = window(text("Exécutable:"), executable_->Render());
auto input_win =
window(text("Entrée"), hbox({
vbox({
hbox({
text("Ajouter: "),
input_add->Render(),
}) | size(WIDTH, EQUAL, 20) |
size(HEIGHT, EQUAL, 1),
filler(),
}),
separator(),
input->Render() | vscroll_indicator | frame |
size(HEIGHT, EQUAL, 3) | flex,
}));
return vbox({
hbox({
compiler_win,
flags_win,
vbox({
executable_win | size(WIDTH, EQUAL, 20),
input_win | size(WIDTH, EQUAL, 60),
}),
filler(),
}) | size(HEIGHT, LESS_THAN, 8),
hflow(render_command()) | flex_grow,
}) |
flex_grow;
});
auto spinner_tab_renderer = Renderer([&] {
for (int i = 0; i < 22; ++i) {
entries.push_back(spinner(i, shift / 5) | bold |
size(WIDTH, GREATER_THAN, 2) | border);
}
return hflow(std::move(entries));
});
auto color_tab_renderer = Renderer([] {
auto basic_color_display =
vbox({
text("Palette de 16 couleurs:"),
separator(),
hbox({
vbox({
color(Color::Default, text(
"Défaut")),
color(Color::Black, text(
"Noir")),
color(Color::GrayDark, text(
"GrisFoncé")),
color(Color::GrayLight, text(
"GrisClair")),
color(Color::White, text(
"Blanc")),
color(Color::Blue, text(
"Bleu")),
color(Color::BlueLight, text(
"BleuClair")),
color(Color::Cyan, text(
"Cyan")),
color(Color::CyanLight, text(
"CyanClair")),
color(Color::Green, text(
"Vert")),
color(Color::GreenLight, text(
"VertClair")),
color(Color::Magenta, text(
"Magenta")),
color(Color::MagentaLight, text(
"MagentaClair")),
color(Color::Red, text(
"Rouge")),
color(Color::RedLight, text(
"RougeClair")),
color(Color::Yellow, text(
"Jaune")),
color(Color::YellowLight, text(
"JauneClair")),
}),
vbox({
bgcolor(Color::Default, text(
"Défaut")),
bgcolor(Color::Black, text(
"Noir")),
bgcolor(Color::GrayDark, text(
"GrisFoncé")),
bgcolor(Color::GrayLight, text(
"GrisClair")),
bgcolor(Color::White, text(
"Blanc")),
bgcolor(Color::Blue, text(
"Bleu")),
bgcolor(Color::BlueLight, text(
"BleuClair")),
bgcolor(Color::Cyan, text(
"Cyan")),
bgcolor(Color::CyanLight, text(
"CyanClair")),
bgcolor(Color::Green, text(
"Vert")),
bgcolor(Color::GreenLight, text(
"VertClair")),
bgcolor(Color::Magenta, text(
"Magenta")),
bgcolor(Color::MagentaLight, text(
"MagentaClair")),
bgcolor(Color::Red, text(
"Rouge")),
bgcolor(Color::RedLight, text(
"RougeClair")),
bgcolor(Color::Yellow, text(
"Jaune")),
bgcolor(Color::YellowLight, text(
"JauneClair")),
}),
}),
}) |
border;
auto palette_256_color_display = text("Palette de 256 couleurs:");
{
for (auto& column : info_columns) {
for (auto& it : column) {
column_elements.push_back(
}
columns.push_back(hbox(std::move(column_elements)));
}
palette_256_color_display = vbox({
palette_256_color_display,
separator(),
vbox(columns),
}) |
border;
}
auto true_color_display = text("TrueColors: 24bits:");
{
int saturation = 255;
for (int value = 0; value < 255; value += 16) {
for (int hue = 0; hue < 255; hue += 6) {
line.push_back(text("▀")
|
color(Color::HSV(hue, saturation, value))
|
bgcolor(Color::HSV(hue, saturation, value + 8)));
}
array.push_back(hbox(std::move(line)));
}
true_color_display = vbox({
true_color_display,
separator(),
vbox(std::move(array)),
}) |
border;
}
return flexbox(
{
basic_color_display,
palette_256_color_display,
true_color_display,
},
});
auto render_gauge = [&shift](int delta) {
float progress = (shift + delta) % 500 / 500.f;
return hbox({
text(std::to_string(int(progress * 100)) + "% ") |
size(WIDTH, EQUAL, 5),
gauge(progress),
});
};
auto gauge_component = Renderer([render_gauge] {
return vbox({
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(),
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),
});
});
auto make_box = [](
size_t dimx,
size_t dimy) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
return window(text(title) | hcenter | bold,
text("contenu") | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
};
auto paragraph_renderer_left = Renderer([&] {
std::string str =
"Lorem Ipsum est simplement un faux texte de l'industrie de "
"l'impression et de la composition.\nLorem Ipsum a été le texte "
"factice standard de l'industrie depuis les années 1500, quand un "
"imprimeur inconnu a pris une galère de caractères et l'a brouillée "
"pour en faire un livre spécimen.";
return vbox({
window(text("Aligner à gauche:"), paragraphAlignLeft(str)),
window(text("Aligner au centre:"), paragraphAlignCenter(str)),
window(text("Aligner à droite:"), paragraphAlignRight(str)),
window(text("Justifier:"), paragraphAlignJustify(str)),
window(text("Côte à côte"), hbox({
paragraph(str),
separator(),
paragraph(str),
})),
window(text("Éléments de tailles différentes:"),
flexbox({
})),
}) |
vscroll_indicator | yframe | flex;
});
auto paragraph_renderer_right = Renderer([] {
return paragraph("<--- Cette barre verticale est redimensionnable avec la souris") |
center;
});
int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
auto paragraph_renderer_group =
ResizableSplitLeft(paragraph_renderer_left, paragraph_renderer_right,
¶graph_renderer_split_position);
auto paragraph_renderer_group_renderer =
Renderer(paragraph_renderer_group,
[&] { return paragraph_renderer_group->Render(); });
int tab_index = 0;
std::vector<std::string> tab_entries = {
"htop", "couleur", "spinner", "jauge", "compilateur", "paragraphe",
};
auto tab_selection =
Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
auto tab_content = Container::Tab(
{
htop,
color_tab_renderer,
spinner_tab_renderer,
gauge_component,
compiler_renderer,
paragraph_renderer_group_renderer,
},
&tab_index);
auto exit_button =
Button(
"Quitter", [&] {
screen.Exit(); }, ButtonOption::Animated());
auto main_container = Container::Vertical({
Container::Horizontal({
tab_selection,
exit_button,
}),
tab_content,
});
auto main_renderer = Renderer(main_container, [&] {
return vbox({
text("Démo FTXUI") | bold | hcenter,
hbox({
tab_selection->Render() | flex,
exit_button->Render(),
}),
tab_content->Render() | flex,
});
});
while (!loop.HasQuitted()) {
shift++;
screen.RequestAnimationFrame();
loop.RunOnce();
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 60));
}
return 0;
}
std::vector< std::vector< ftxui::ColorInfo > > ColorInfoSorted2D()
FlexboxConfig & SetGap(int gap_x, int gap_y)
Définit la direction de flex (flex direction) de la flexbox.
Color est une classe qui représente une couleur dans l'interface utilisateur du terminal.
std::vector< Element > Elements
input
Demo
#include <memory>
#include <string>
std::string first_name;
std::string last_name;
std::string password;
std::string phoneNumber;
Component input_first_name = Input(&first_name,
"first name");
Component input_last_name = Input(&last_name,
"last name");
Component input_password = Input(&password,
"password", password_option);
Component input_phone_number = Input(&phoneNumber,
"phone number");
input_phone_number |= CatchEvent([&](
Event event) {
return event.is_character() && !std::isdigit(event.
character()[0]);
});
input_phone_number |= CatchEvent([&](
Event event) {
return event.is_character() && phoneNumber.size() > 10;
});
auto component = Container::Vertical({
input_first_name,
input_last_name,
input_password,
input_phone_number,
});
auto renderer = Renderer(component, [&] {
return vbox({
hbox(text(" First name : "), input_first_name->Render()),
hbox(text(" Last name : "), input_last_name->Render()),
hbox(text(" Password : "), input_password->Render()),
hbox(text(" Phone num : "), input_phone_number->Render()),
separator(),
text("Hello " + first_name + " " + last_name),
text("Your password is " + password),
text("Your phone number is " + phoneNumber),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
}
std::string character() const
Ref< bool > password
Obscurcit le contenu de l'entrée en utilisant '*'.
input_in_frame
Demo
#include <memory>
#include <string>
#include <vector>
Component input_list = Container::Vertical({});
std::vector<std::string> items(100, "");
for (size_t i = 0; i < items.size(); ++i) {
input_list->Add(Input(&(items[i]), "placeholder " + std::to_string(i)));
}
auto renderer = Renderer(input_list, [&] {
return input_list->Render() | vscroll_indicator | frame | border |
size(HEIGHT, LESS_THAN, 10);
});
auto screen = ScreenInteractive::TerminalOutput();
}
input_style
Demo
#include <functional>
#include <string>
#include <utility>
state.element |= borderEmpty;
if (state.is_placeholder) {
state.element |= dim;
}
if (state.focused) {
state.element |= borderDouble;
state.element |=
bgcolor(Color::White);
state.element |=
color(Color::Black);
} else if (state.hovered) {
state.element |= borderRounded;
state.element |=
color(Color::White);
} else {
state.element |= border;
state.element |=
color(Color::White);
}
return state.element;
};
state.element = hbox({
text(
"Theorem") | center | borderEmpty |
bgcolor(Color::Red),
separatorEmpty(),
separator() |
color(Color::White),
separatorEmpty(),
std::move(state.element),
});
state.element |= borderEmpty;
if (state.is_placeholder) {
state.element |= dim;
}
if (state.focused) {
state.element |=
bgcolor(Color::Black);
} else {
state.element |=
bgcolor(Color::Blue);
}
if (state.hovered) {
state.element |=
bgcolor(Color::GrayDark);
}
return vbox({state.element, separatorEmpty()});
};
auto first_name = new std::string();
auto middle_name = new std::string();
auto last_name = new std::string();
return Container::Vertical({
Input(first_name, "first name", style),
Input(middle_name, "middle name", style),
Input(last_name, "last name", style),
}) |
borderEmpty;
};
auto ui = Container::Horizontal({
generateUiFromStyle(style_1),
generateUiFromStyle(style_2),
generateUiFromStyle(style_3),
generateUiFromStyle(style_4),
});
auto screen = ScreenInteractive::TerminalOutput();
}
std::function< Element(InputState)> transform
Une classe représentant les paramètres de l'effet de couleur en dégradé linéaire.
linear_gradient_gallery
Demo
#include <memory>
#include <string>
auto screen = ScreenInteractive::Fullscreen();
float start = 0.f;
float end = 1.f;
std::string slider_angle_text;
std::string slider_start_text;
std::string slider_end_text;
auto slider_angle = Slider(&slider_angle_text, &
angle, 0, 360);
auto slider_start = Slider(&slider_start_text, &start, 0.f, 1.f, 0.05f);
auto slider_end = Slider(&slider_end_text, &end, 0.f, 1.f, 0.05f);
auto layout = Container::Vertical({
slider_angle,
slider_start,
slider_end,
});
auto renderer = Renderer(layout, [&] {
slider_angle_text =
"angle = " + std::to_string(
angle) +
"°";
slider_start_text = "start = " + std::to_string(int(start * 100)) + "%";
slider_end_text = "end = " + std::to_string(int(end * 100)) + "%";
auto background = text("Gradient") | center |
.Stop(Color::Blue, start)
.Stop(Color::Red, end));
return vbox({
background | flex,
layout->Render(),
}) |
flex;
});
}
maybe
Demo
#include <string>
#include <vector>
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int menu_1_selected = 0;
int menu_2_selected = 0;
bool menu_1_show = false;
bool menu_2_show = false;
auto layout = Container::Vertical({
Checkbox("Show menu_1", &menu_1_show),
Radiobox(&entries, &menu_1_selected) | border | Maybe(&menu_1_show),
Checkbox("Show menu_2", &menu_2_show),
Radiobox(&entries, &menu_2_selected) | border | Maybe(&menu_2_show),
Renderer([] {
return text(
"Vous avez trouvé la combinaison secrète!") |
color(Color::Red);
}) | Maybe([&] { return menu_1_selected == 1 && menu_2_selected == 2; }),
});
auto screen = ScreenInteractive::TerminalOutput();
}
menu
Demo
#include <functional>
#include <iostream>
#include <string>
#include <vector>
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
auto menu = Menu(&entries, &selected, option);
std::cout << "Selected element = " << selected << std::endl;
}
std::function< void()> on_enter
menu2
Demo
#include <functional>
#include <memory>
#include <string>
#include <vector>
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> left_menu_entries = {
"0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%",
};
std::vector<std::string> right_menu_entries = {
"0%", "1%", "2%", "3%", "4%", "5%", "6%", "7%", "8%", "9%", "10%",
};
menu_option.on_enter =
screen.ExitLoopClosure();
int left_menu_selected = 0;
int right_menu_selected = 0;
Menu(&left_menu_entries, &left_menu_selected, menu_option);
Menu(&right_menu_entries, &right_menu_selected, menu_option);
Component container = Container::Horizontal({
left_menu_,
right_menu_,
});
auto renderer = Renderer(container, [&] {
int sum = left_menu_selected * 10 + right_menu_selected;
return vbox({
hbox({
vbox({
hcenter(bold(text("Pourcentage par 10%"))),
separator(),
left_menu_->Render(),
}),
separator(),
vbox({
hcenter(bold(text("Pourcentage par 1%"))),
separator(),
right_menu_->Render(),
}),
separator(),
}),
separator(),
vbox({
hbox({
text(" jauge : "),
gauge(sum / 100.0),
}),
hbox({
text(" texte : "),
text(std::to_string(sum) + " %"),
}),
}),
}) |
border;
});
}
menu_entries
Demo
#include <functional>
#include <iostream>
#include <memory>
#include <string>
state.label = (state.active ? "> " : " ") + state.label;
if (state.focused) {
e = e | inverted;
}
if (state.active) {
e = e | bold;
}
return e;
};
return option;
}
auto screen = ScreenInteractive::TerminalOutput();
int selected = 0;
auto menu = Container::Vertical(
{
MenuEntry(" 1. improve"),
MenuEntry(" 2. tolerant"),
MenuEntry(" 3. career"),
MenuEntry(" 4. cast"),
MenuEntry(" 5. question"),
Renderer([] { return separator(); }),
MenuEntry(
" 6. rear",
Colored(Color::Red)),
MenuEntry(
" 7. drown",
Colored(Color::Yellow)),
MenuEntry(
" 8. nail",
Colored(Color::Green)),
MenuEntry(
" 9. quit",
Colored(Color::Cyan)),
MenuEntry(
"10. decorative",
Colored(Color::Blue)),
Renderer([] { return separator(); }),
MenuEntry("11. costume"),
MenuEntry("12. pick"),
MenuEntry("13. oral"),
MenuEntry("14. minister"),
MenuEntry("15. football"),
MenuEntry("16. welcome"),
MenuEntry("17. copper"),
MenuEntry("18. inhabitant"),
MenuEntry("19. fortune"),
},
&selected);
auto renderer = Renderer(menu, [&] {
return vbox({
hbox(text("selected = "), text(std::to_string(selected))),
separator(),
menu->Render() | frame | size(HEIGHT, LESS_THAN, 10),
}) |
border;
});
std::cout << "Selected element = " << selected << std::endl;
}
std::function< Element(const EntryState &state)> transform
menu_entries_animated
Demo
#include <iostream>
#include <memory>
#include <string>
return option;
}
auto screen = ScreenInteractive::TerminalOutput();
int selected = 0;
auto menu = Container::Vertical(
{
MenuEntry(
" 1. rear",
Colored(Color::Red)),
MenuEntry(
" 2. drown",
Colored(Color::Yellow)),
MenuEntry(
" 3. nail",
Colored(Color::Green)),
MenuEntry(
" 4. quit",
Colored(Color::Cyan)),
MenuEntry(
" 5. decorative",
Colored(Color::Blue)),
MenuEntry(" 7. costume"),
MenuEntry(" 8. pick"),
MenuEntry(" 9. oral"),
MenuEntry("11. minister"),
MenuEntry("12. football"),
MenuEntry("13. welcome"),
MenuEntry("14. copper"),
MenuEntry("15. inhabitant"),
},
&selected);
auto renderer = Renderer(menu, [&] {
return vbox({
hbox(text("selected = "), text(std::to_string(selected))),
separator(),
menu->Render() | frame,
}) |
});
std::cout << "Selected element = " << selected << std::endl;
}
AnimatedColorsOption animated_colors
AnimatedColorOption foreground
AnimatedColorOption background
menu_in_frame
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> entries;
int selected = 0;
for (int i = 0; i < 30; ++i) {
entries.push_back("Entry " + std::to_string(i));
}
auto radiobox = Menu(&entries, &selected);
auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
menu_in_frame_horizontal
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> entries;
int selected = 0;
for (int i = 0; i < 100; ++i) {
entries.push_back(std::to_string(i));
}
auto radiobox = Menu(&entries, &selected, MenuOption::Horizontal());
auto renderer = Renderer(
radiobox, [&] { return radiobox->Render() | hscroll_indicator | frame; });
auto screen = ScreenInteractive::FitComponent();
return 0;
}
menu_multiple
Demo
#include <stdlib.h>
#include <memory>
#include <string>
#include <vector>
return Renderer(component, [component, title] {
return window(text(title), component->Render()) | flex;
});
}
int menu_selected[] = {0, 0, 0};
std::vector<std::vector<std::string>> menu_entries = {
{
"Ananas",
"Raspberry",
"Citrus",
},
{
"Potatoes",
"Weat",
"Rise",
},
{
"Carrot",
"Lettuce",
"Tomato",
},
};
int menu_selected_global = 0;
auto menu_global = Container::Vertical(
{
Window(
"Menu 1", Menu(&menu_entries[0], &menu_selected[0])),
Window(
"Menu 2", Menu(&menu_entries[1], &menu_selected[1])),
Window(
"Menu 3", Menu(&menu_entries[2], &menu_selected[2])),
},
&menu_selected_global);
auto info = Renderer([&] {
int g = menu_selected_global;
std::string value = menu_entries[g][menu_selected[g]];
return window(text("Content"),
vbox({
text("menu_selected_global = " + std::to_string(g)),
text("menu_selected[0] = " +
std::to_string(menu_selected[0])),
text("menu_selected[1] = " +
std::to_string(menu_selected[1])),
text("menu_selected[2] = " +
std::to_string(menu_selected[2])),
text("Value = " + value),
})) |
flex;
});
auto global = Container::Horizontal({
menu_global,
info,
});
auto screen = ScreenInteractive::TerminalOutput();
return EXIT_SUCCESS;
}
menu_style
Demo
#include <array>
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <vector>
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> entries{
"Monkey", "Dog", "Cat", "Bird", "Elephant", "Cat",
};
std::array<int, 12> selected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
auto vmenu_1_ =
VMenu1(&entries, &selected[0]);
auto vmenu_2_ =
VMenu2(&entries, &selected[1]);
auto vmenu_3_ =
VMenu3(&entries, &selected[2]);
auto vmenu_4_ =
VMenu4(&entries, &selected[3]);
auto vmenu_5_ =
VMenu5(&entries, &selected[4]);
auto vmenu_6_ =
VMenu6(&entries, &selected[5]);
auto vmenu_7_ =
VMenu7(&entries, &selected[6]);
auto vmenu_8_ =
VMenu8(&entries, &selected[7]);
auto hmenu_1_ =
HMenu1(&entries, &selected[8]);
auto hmenu_2_ =
HMenu2(&entries, &selected[9]);
auto hmenu_3_ =
HMenu3(&entries, &selected[10]);
auto hmenu_4_ =
HMenu4(&entries, &selected[11]);
auto hmenu_5_ =
HMenu5(&entries, &selected[12]);
auto container = Container::Vertical({
Container::Horizontal({
vmenu_1_,
vmenu_2_,
vmenu_3_,
vmenu_4_,
vmenu_5_,
vmenu_6_,
vmenu_7_,
vmenu_8_,
}),
hmenu_1_,
hmenu_2_,
hmenu_3_,
hmenu_4_,
hmenu_5_,
});
auto renderer = Renderer(container, [&] {
return
hbox({
vbox({
hbox({
vmenu_1_->Render(),
separator(),
vmenu_2_->Render(),
separator(),
vmenu_3_->Render(),
separator(),
vmenu_4_->Render(),
separator(),
vmenu_5_->Render(),
vmenu_6_->Render(),
separator(),
vmenu_7_->Render(),
separator(),
vmenu_8_->Render(),
}),
separator(),
hmenu_1_->Render(),
separator(),
hmenu_2_->Render(),
separator(),
hmenu_3_->Render(),
separator(),
hmenu_4_->Render(),
hmenu_5_->Render(),
}) | border,
filler(),
});
});
}
auto option = MenuOption::Vertical();
state.label = (state.active ? "> " : " ") + state.label;
if (state.focused) {
}
if (state.active) {
e = e | bold;
}
return e;
};
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
state.label += (state.active ? " <" : " ");
Element e = hbox(filler(), text(state.label));
if (state.focused) {
}
if (state.active) {
e = e | bold;
}
return e;
};
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
Element e = state.active ? text(
"[" + state.label +
"]")
: text(" " + state.label + " ");
if (state.focused) {
e = e | bold;
}
if (state.focused) {
e = e | color(Color::Blue);
}
if (state.active) {
e = e | bold;
}
return e;
};
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
if (state.active && state.focused) {
return text(state.label) |
color(Color::Yellow) |
bgcolor(Color::Black) |
bold;
}
if (state.active) {
return text(state.label) |
color(Color::Yellow) |
bgcolor(Color::Black);
}
if (state.focused) {
return text(state.label) |
color(Color::Black) |
bgcolor(Color::Yellow) |
bold;
}
return text(state.label) |
color(Color::Black) |
bgcolor(Color::Yellow);
};
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
auto element = text(state.label);
if (state.active && state.focused) {
return element | borderDouble;
}
if (state.active) {
return element | border;
}
if (state.focused) {
return element | bold;
}
return element;
};
return Menu(entries, selected, option);
}
auto option = MenuOption::VerticalAnimated();
option.underline.color_inactive = Color::Default;
option.underline.color_active = Color::Red;
option.underline.SetAnimationFunction(animation::easing::Linear);
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
Color::Red, Color::White, std::chrono::milliseconds(500));
return Menu(entries, selected, option);
}
return Menu(entries, selected, MenuOption::Horizontal());
}
return Menu(entries, selected, MenuOption::Toggle());
}
auto option = MenuOption::Toggle();
option.elements_infix = [] { return text(" 🮣🮠 "); };
return Menu(entries, selected, option);
}
return Menu(entries, selected, MenuOption::HorizontalAnimated());
}
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimation(std::chrono::milliseconds(1500),
animation::easing::ElasticOut);
Element e = text(state.label) | hcenter | flex;
if (state.active && state.focused) {
e = e | bold;
}
if (!state.focused && !state.active) {
e = e | dim;
}
return e;
};
option.underline.color_inactive = Color::Default;
option.underline.color_active = Color::Red;
return Menu(entries, selected, option);
}
void Set(Color inactive, Color active, animation::Duration duration=std::chrono::milliseconds(250), animation::easing::Function function=animation::easing::QuadraticInOut)
Une option de couleur qui peut être animée. @params _inactive La couleur lorsque le composant est ina...
menu_underline_animated_gallery
Demo
#include <chrono>
#include <memory>
#include <string>
#include <vector>
return Renderer([id](bool focused) {
auto t = text("component " + std::to_string(id));
if (focused) {
t = t | inverted;
}
return t;
});
}
return Renderer([t] { return text(t) | borderEmpty; });
}
using namespace std::literals;
std::vector<std::string> tab_values{
"Tab 1", "Tab 2", "Tab 3", "A very very long tab", "탭",
};
int tab_selected = 0;
auto container = Container::Vertical({});
int frame_count = 0;
container->Add(Renderer(
[&] { return text("Frame count: " + std::to_string(frame_count++)); }));
{
auto option = MenuOption::HorizontalAnimated();
container->Add(
Text(
"Ceci démontre le composant Menu"));
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Définir la couleur du soulignement en bleu"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_inactive = Color::Blue;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Définir la couleur active du soulignement en rouge"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_active = Color::Red;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Définir la durée de l'animation à 0ms"));
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimationDuration(0ms);
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Définir la fonction d'assouplissement de l'animation sur 'back-out'"));
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimationFunction(animation::easing::BackOut);
option.underline.SetAnimationDuration(350ms);
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Ajouter un délai pour désynchroniser l'animation"));
auto option = MenuOption::HorizontalAnimated();
option.underline.follower_delay = 250ms;
container->Add(Menu(&tab_values, &tab_selected, option));
}
container->SetActiveChild(container->ChildAt(2));
auto screen = ScreenInteractive::TerminalOutput();
}
modal_dialog
Demo
#include <functional>
#include <memory>
std::function<void()> exit) {
auto component = Container::Vertical({
});
component |= Renderer([&](
Element inner) {
return vbox({
text("Main component"),
separator(),
inner,
})
| size(WIDTH, GREATER_THAN, 15)
| size(HEIGHT, GREATER_THAN, 15)
| border
| center;
});
return component;
}
std::function<void()> hide_modal) {
auto component = Container::Vertical({
});
component |= Renderer([&](
Element inner) {
return vbox({
text("Modal component "),
separator(),
inner,
})
| size(WIDTH, GREATER_THAN, 30)
| border;
});
return component;
}
int main(
int argc,
const char* argv[]) {
auto screen = ScreenInteractive::TerminalOutput();
bool modal_shown = false;
auto show_modal = [&] { modal_shown = true; };
auto hide_modal = [&] { modal_shown = false; };
auto exit =
screen.ExitLoopClosure();
auto do_nothing = [&] {};
return 0;
}
Component ModalComponent(std::function< void()> do_nothing, std::function< void()> hide_modal)
Component MainComponent(std::function< void()> show_modal, std::function< void()> exit)
modal_dialog_custom
Demo
#include <memory>
#include <string>
#include <vector>
auto screen = ScreenInteractive::TerminalOutput();
int depth = 0;
std::string rating = "3/5 stars";
auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; });
auto button_quit = Button(
"Quit",
screen.ExitLoopClosure());
auto depth_0_container = Container::Horizontal({
button_rate_ftxui,
button_quit,
});
auto depth_0_renderer = Renderer(depth_0_container, [&] {
return vbox({
text("Modal dialog example"),
separator(),
text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold,
filler(),
hbox({
button_rate_ftxui->Render(),
filler(),
button_quit->Render(),
}),
}) |
border | size(HEIGHT, GREATER_THAN, 18) | center;
});
std::vector<std::string> rating_labels = {
"1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars",
};
auto on_rating = [&](std::string new_rating) {
rating = new_rating;
depth = 0;
};
auto depth_1_container = Container::Horizontal({
Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }),
Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }),
Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }),
Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }),
Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }),
});
auto depth_1_renderer = Renderer(depth_1_container, [&] {
return vbox({
text("Do you like FTXUI?"),
separator(),
hbox(depth_1_container->Render()),
}) |
border;
});
auto main_container = Container::Tab(
{
depth_0_renderer,
depth_1_renderer,
},
&depth);
auto main_renderer = Renderer(main_container, [&] {
Element document = depth_0_renderer->Render();
if (depth == 1) {
document = dbox({
document,
depth_1_renderer->Render() | clear_under | center,
});
}
return document;
});
return 0;
}
nested_screen
Demo
#include <memory>
#include <string>
void Nested(std::string path) {
auto screen = ScreenInteractive::FitComponent();
auto back_button = Button(
"Retour",
screen.ExitLoopClosure());
auto goto_1 = Button(
"Aller à /1", [path] {
Nested(path +
"/1"); });
auto goto_2 = Button(
"Aller à /2", [path] {
Nested(path +
"/2"); });
auto goto_3 = Button(
"Aller à /3", [path] {
Nested(path +
"/3"); });
auto layout = Container::Vertical({
back_button,
goto_1,
goto_2,
goto_3,
});
auto renderer = Renderer(layout, [&] {
return vbox({
text("chemin: " + path),
separator(),
back_button->Render(),
goto_1->Render(),
goto_2->Render(),
goto_3->Render(),
}) |
border;
});
}
auto screen = ScreenInteractive::FitComponent();
auto button_quit = Button(
"Quitter",
screen.ExitLoopClosure());
auto button_nested = Button(
"Imbriqué", [] {
Nested(
""); });
screen.Loop(Container::Vertical({
button_quit,
button_nested,
}));
return 0;
}
void Nested(std::string path)
print_key_press
Demo
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>
std::string codes;
for (
auto& it : event.
input()) {
codes += " " + std::to_string((unsigned int)it);
}
return codes;
}
auto screen = ScreenInteractive::TerminalOutput();
std::vector<Event> keys;
auto left_column = Renderer([&] {
text("Codes"),
separator(),
};
for (size_t i = std::max(0, (int)keys.size() - 20); i < keys.size(); ++i) {
children.push_back(text(
Code(keys[i])));
}
return vbox(children);
});
auto right_column = Renderer([&] {
text("Event"),
separator(),
};
for (size_t i = std::max(0, (int)keys.size() - 20); i < keys.size(); ++i) {
children.push_back(text(keys[i].DebugString()));
}
return vbox(children);
});
int split_size = 40;
auto component = ResizableSplitLeft(left_column, right_column, &split_size);
component |= border;
component |= CatchEvent([&](
Event event) {
keys.push_back(event);
return false;
});
}
const std::string & input() const
std::string Code(Event event)
radiobox
Demo
#include <string>
#include <vector>
std::vector<std::string> radiobox_list = {
"Use gcc",
"Use clang",
"Use emscripten",
"Use tcc",
};
int selected = 0;
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(Radiobox(&radiobox_list, &selected));
return 0;
}
radiobox_in_frame
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> entries;
int selected = 0;
for (int i = 0; i < 30; ++i) {
entries.push_back("RadioBox " + std::to_string(i));
}
auto radiobox = Radiobox(&entries, &selected);
auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
renderer
Demo
#include <memory>
auto screen = ScreenInteractive::FitComponent();
auto renderer_focusable = Renderer([](bool focused) {
if (focused) {
return text("RENDU FOCUSABLE()") | center | bold | border;
} else {
return text(" Rendu focusable() ") | center | border;
}
});
auto renderer_non_focusable = Renderer([&] {
return text("~~~~~ Rendu non focusable() ~~~~~");
});
auto button = Button(
"Bouton quitter enveloppé",
screen.ExitLoopClosure());
auto renderer_wrap = Renderer(button, [&] {
if (button->Focused()) {
return button->Render() | bold |
color(Color::Red);
} else {
return button->Render();
}
});
screen.Loop(Container::Vertical({
renderer_focusable,
renderer_non_focusable,
renderer_wrap,
}));
}
resizable_split
Demo
#include <memory>
auto screen = ScreenInteractive::Fullscreen();
int left_size = 20;
int right_size = 20;
int top_size = 10;
int bottom_size = 10;
auto RendererInfo = [](const std::string& name, int* size) {
return Renderer([name, size] {
return text(name + ": " + std::to_string(*size)) | center;
});
};
auto middle = Renderer([] { return text("Middle") | center; });
auto left = RendererInfo("Left", &left_size);
auto right = RendererInfo("Right", &right_size);
auto top = RendererInfo("Top", &top_size);
auto bottom = RendererInfo("Bottom", &bottom_size);
auto container = middle;
container = ResizableSplitLeft(left, container, &left_size);
container = ResizableSplitRight(right, container, &right_size);
container = ResizableSplitTop(top, container, &top_size);
container = ResizableSplitBottom(bottom, container, &bottom_size);
auto renderer =
Renderer(container, [&] { return container->Render() | border; });
}
resizable_split_clamp
Demo
#include <memory>
auto screen = ScreenInteractive::Fullscreen();
int size = 40;
int size_min = 10;
int size_max = 80;
auto split = ResizableSplit({
.main = Renderer([] { return text("Left") | center; }),
.back = Renderer([] { return text("Right") | center; }),
.direction = Direction::Left,
.main_size = &size,
.min = &size_min,
.max = &size_max,
});
auto renderer = Renderer(split, [&] {
return window(text("Faites glisser le séparateur avec la souris"),
vbox({
text("Min: " + std::to_string(size_min)),
text("Max: " + std::to_string(size_max)),
text("Size: " + std::to_string(size)),
separator(),
split->Render() | flex,
}));
});
}
scrollbar
Demo
#include <string>
private:
float scroll_x = 0.1;
float scroll_y = 0.1;
public:
Impl() {
auto content = Renderer([=] {
const std::string lorem =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
"do eiusmod tempor incididunt ut labore et dolore magna "
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
"ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis "
"aute irure dolor in reprehenderit in voluptate velit esse "
"cillum dolore eu fugiat nulla pariatur. Excepteur sint "
"occaecat cupidatat non proident, sunt in culpa qui officia "
"deserunt mollit anim id est laborum.";
return vbox({
text(lorem.substr(0, -1)), text(lorem.substr(5, -1)), text(""),
text(lorem.substr(10, -1)), text(lorem.substr(15, -1)), text(""),
text(lorem.substr(20, -1)), text(lorem.substr(25, -1)), text(""),
text(lorem.substr(30, -1)), text(lorem.substr(35, -1)), text(""),
text(lorem.substr(40, -1)), text(lorem.substr(45, -1)), text(""),
text(lorem.substr(50, -1)), text(lorem.substr(55, -1)), text(""),
text(lorem.substr(60, -1)), text(lorem.substr(65, -1)), text(""),
text(lorem.substr(70, -1)), text(lorem.substr(75, -1)), text(""),
text(lorem.substr(80, -1)), text(lorem.substr(85, -1)), text(""),
text(lorem.substr(90, -1)), text(lorem.substr(95, -1)), text(""),
text(lorem.substr(100, -1)), text(lorem.substr(105, -1)), text(""),
text(lorem.substr(110, -1)), text(lorem.substr(115, -1)), text(""),
text(lorem.substr(120, -1)), text(lorem.substr(125, -1)), text(""),
text(lorem.substr(130, -1)), text(lorem.substr(135, -1)), text(""),
text(lorem.substr(140, -1)),
});
});
auto scrollable_content = Renderer(content, [&, content] {
return content->Render() | focusPositionRelative(scroll_x, scroll_y) |
frame | flex;
});
option_x.
value = &scroll_x;
option_x.min = 0.f;
option_x.max = 1.f;
option_x.increment = 0.1f;
option_x.direction = Direction::Right;
option_x.color_active = Color::Blue;
option_x.color_inactive = Color::BlueLight;
auto scrollbar_x = Slider(option_x);
option_y.
value = &scroll_y;
auto scrollbar_y = Slider(option_y);
Add(Container::Vertical({
Container::Horizontal({
scrollable_content,
scrollbar_y,
}) | flex,
Container::Horizontal({
scrollbar_x,
Renderer([] { return text(L"x"); }),
}),
}));
}
};
return Make<Impl>();
}
.title = "Première fenêtre",
.width = 80,
.height = 30,
});
.title = "Ma fenêtre",
.left = 40,
.top = 20,
.width = 80,
.height = 30,
});
auto window_container = Container::Stacked({
window_1,
window_2,
});
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(window_container);
return EXIT_SUCCESS;
}
Il implémente son propre rendu en tant que ftxui::Element. Il implémente la navigation au clavier en ...
selection
Demo
#include <string>
return vbox({
text("FTXUI : Une bibliothèque puissante pour construire des interfaces utilisateur."),
text("Profitez d'un riche ensemble de composants et d'un style déclaratif."),
text("Créez des interfaces utilisateur belles et réactives avec un minimum d'effort."),
text("Rejoignez la communauté et découvrez la puissance de FTXUI."),
});
}
auto screen = ScreenInteractive::TerminalOutput();
auto quit =
Button(
"Quitter",
screen.ExitLoopClosure(), ButtonOption::Animated());
int selection_change_counter = 0;
std::string selection_content = "";
selection_change_counter++;
selection_content =
screen.GetSelection();
});
auto renderer = Renderer(quit, [&] {
return vbox({
text("Sélection changée : " + std::to_string(selection_change_counter) +
" fois"),
text("Actuellement sélectionné : "),
paragraph(selection_content) | vscroll_indicator | frame | border |
size(HEIGHT, EQUAL, 10),
window(text("Séparation horizontale"), hbox({
separator(),
separator(),
})),
window(text("Séparation verticale"), vbox({
separator(),
separator(),
})),
window(text("Séparation en grille avec un style différent"),
vbox({
hbox({
separator(),
| selectionBackgroundColor(Color::Yellow)
| selectionColor(Color::Black)
| selectionStyleReset,
separator(),
}),
separator(),
hbox({
separator(),
}),
separator(),
}),
})),
quit->Render(),
});
});
}
slider
Demo
auto screen = ScreenInteractive::TerminalOutput();
int value = 50;
auto slider = Slider("Value:", &value, 0, 100, 1);
}
slider_direction
Demo
#include <array>
#include <cmath>
#include <memory>
auto screen = ScreenInteractive::TerminalOutput();
std::array<int, 30> values;
for (size_t i = 0; i < values.size(); ++i) {
values[i] = 50 + 20 * std::sin(i * 0.3);
}
auto layout_horizontal = Container::Horizontal({});
for (auto& value : values) {
layout_horizontal->Add(Slider<int>(option));
}
layout_horizontal |= size(HEIGHT, GREATER_THAN, 20);
screen.Loop(layout_horizontal);
}
slider_rgb
Demo
#include <memory>
#include <string>
return text("") | size(WIDTH, GREATER_THAN, 14) |
size(HEIGHT, GREATER_THAN, 7) |
bgcolor(Color::RGB(red, green, blue));
}
return text("RGB = (" +
std::to_string(red) + "," +
std::to_string(green) + "," +
std::to_string(blue) + ")"
);
}
int red = 128;
int green = 25;
int blue = 100;
auto slider_red = Slider("Red :", &red, 0, 255, 1);
auto slider_green = Slider("Green:", &green, 0, 255, 1);
auto slider_blue = Slider("Blue :", &blue, 0, 255, 1);
auto container = Container::Vertical({
slider_red,
slider_green,
slider_blue,
});
auto renderer = Renderer(container, [&] {
return hbox({
separator(),
vbox({
slider_red->Render(),
separator(),
slider_green->Render(),
separator(),
slider_blue->Render(),
separator(),
}) | xflex,
}) |
border | size(WIDTH, LESS_THAN, 80);
});
auto screen = ScreenInteractive::TerminalOutput();
}
Element ColorTile(int red, int green, int blue)
Element ColorString(int red, int green, int blue)
tab_horizontal
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> tab_values{
"tab_1",
"tab_2",
"tab_3",
};
int tab_selected = 0;
auto tab_toggle = Toggle(&tab_values, &tab_selected);
std::vector<std::string> tab_1_entries{
"Forest",
"Water",
"I don't know",
};
int tab_1_selected = 0;
std::vector<std::string> tab_2_entries{
"Hello",
"Hi",
"Hay",
};
int tab_2_selected = 0;
std::vector<std::string> tab_3_entries{
"Table",
"Nothing",
"Is",
"Empty",
};
int tab_3_selected = 0;
auto tab_container = Container::Tab(
{
Radiobox(&tab_1_entries, &tab_1_selected),
Radiobox(&tab_2_entries, &tab_2_selected),
Radiobox(&tab_3_entries, &tab_3_selected),
},
&tab_selected);
auto container = Container::Vertical({
tab_toggle,
tab_container,
});
auto renderer = Renderer(container, [&] {
return vbox({
tab_toggle->Render(),
separator(),
tab_container->Render(),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
}
tab_vertical
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> tab_values{
"tab_1",
"tab_2",
"tab_3",
};
int tab_selected = 0;
auto tab_menu = Menu(&tab_values, &tab_selected);
std::vector<std::string> tab_1_entries{
"Forest",
"Water",
"I don't know",
};
int tab_1_selected = 0;
std::vector<std::string> tab_2_entries{
"Hello",
"Hi",
"Hay",
};
int tab_2_selected = 0;
std::vector<std::string> tab_3_entries{
"Table",
"Nothing",
"Is",
"Empty",
};
int tab_3_selected = 0;
auto tab_container = Container::Tab(
{
Radiobox(&tab_1_entries, &tab_1_selected),
Radiobox(&tab_2_entries, &tab_2_selected),
Radiobox(&tab_3_entries, &tab_3_selected),
},
&tab_selected);
auto container = Container::Horizontal({
tab_menu,
tab_container,
});
auto renderer = Renderer(container, [&] {
return hbox({
tab_menu->Render(),
separator(),
tab_container->Render(),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
}
textarea
Demo
#include <memory>
#include <string>
std::string content_1;
std::string content_2;
auto textarea_1 = Input(&content_1);
auto textarea_2 = Input(&content_2);
int size = 50;
auto layout = ResizableSplitLeft(textarea_1, textarea_2, &size);
auto component = Renderer(layout, [&] {
return vbox({
text("Input:"),
separator(),
layout->Render() | flex,
}) |
border;
});
auto screen = ScreenInteractive::Fullscreen();
}
toggle
Demo
#include <memory>
#include <string>
#include <vector>
std::vector<std::string> toggle_1_entries = {
"On",
"Off",
};
std::vector<std::string> toggle_2_entries = {
"Enabled",
"Disabled",
};
std::vector<std::string> toggle_3_entries = {
"10€",
"0€",
};
std::vector<std::string> toggle_4_entries = {
"Nothing",
"One element",
"Several elements",
};
int toggle_1_selected = 0;
int toggle_2_selected = 0;
int toggle_3_selected = 0;
int toggle_4_selected = 0;
Component toggle_1 = Toggle(&toggle_1_entries, &toggle_1_selected);
Component toggle_2 = Toggle(&toggle_2_entries, &toggle_2_selected);
Component toggle_3 = Toggle(&toggle_3_entries, &toggle_3_selected);
Component toggle_4 = Toggle(&toggle_4_entries, &toggle_4_selected);
auto container = Container::Vertical({
toggle_1,
toggle_2,
toggle_3,
toggle_4,
});
auto renderer = Renderer(container, [&] {
return vbox({
text("Choose your options:"),
text(""),
hbox(text(" * Poweroff on startup : "), toggle_1->Render()),
hbox(text(" * Out of process : "), toggle_2->Render()),
hbox(text(" * Price of the information : "), toggle_3->Render()),
hbox(text(" * Number of elements : "), toggle_4->Render()),
});
});
auto screen = ScreenInteractive::TerminalOutput();
}
window
Demo
#include <string>
private:
bool checked[3] = {false, false, false};
float slider = 50;
public:
Impl() {
Add(Container::Vertical({
Checkbox("Cochez-moi", &checked[0]),
Checkbox("Cochez-moi", &checked[1]),
Checkbox("Cochez-moi", &checked[2]),
Slider("Curseur", &slider, 0.f, 100.f),
}));
}
};
return Make<Impl>();
}
int window_1_left = 20;
int window_1_top = 10;
int window_1_width = 40;
int window_1_height = 20;
.title = "Première fenêtre",
.left = &window_1_left,
.top = &window_1_top,
.width = &window_1_width,
.height = &window_1_height,
});
.title = "Ma fenêtre",
.left = 40,
.top = 20,
});
.title = "Ma fenêtre",
.left = 60,
.top = 30,
});
});
auto window_container = Container::Stacked({
window_1,
window_2,
window_3,
window_4,
window_5,
});
auto display_win_1 = Renderer([&] {
return text("window_1: " +
std::to_string(window_1_width) + "x" +
std::to_string(window_1_height) + " + " +
std::to_string(window_1_left) + "," +
std::to_string(window_1_top));
});
auto layout = Container::Vertical({
display_win_1,
window_container,
});
auto screen = ScreenInteractive::Fullscreen();
return EXIT_SUCCESS;
}
with_restored_io
Demo
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
auto screen = ScreenInteractive::Fullscreen();
auto btn_run = Button(
"Execute with restored IO",
screen.WithRestoredIO([] {
std::cout << "This is a child program using stdin/stdout." << std::endl;
for (int i = 0; i < 10; ++i) {
std::cout << "Please enter 10 strings (" << i << "/10)" << std::flush;
std::string input;
std::getline(std::cin, input);
}
}));
auto btn_quit = Button(
"Quit",
screen.ExitLoopClosure());
auto layout = Container::Horizontal({
btn_run,
btn_quit,
});
auto renderer = Renderer(layout, [&] {
auto explanation = paragraph(
"Après avoir cliqué sur ce bouton, le ScreenInteractive sera "
"suspendu et l'accès à stdin/stdout sera temporairement "
"restauré pour l'exécution d'une fonction.");
auto element = vbox({
explanation | borderEmpty,
hbox({
btn_run->Render(),
filler(),
btn_quit->Render(),
}),
});
element = element | borderEmpty | border | size(WIDTH, LESS_THAN, 80) |
size(HEIGHT, LESS_THAN, 20) | center;
return element;
});
return EXIT_SUCCESS;
}