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, [&] {
text("value = " + std::to_string(value)),
separator(),
buttons->Render() | flex,
}) |
flex | border;
});
auto screen = ScreenInteractive::FitComponent();
return 0;
}
Element vbox(Elements children)
Un contenedor que muestra elementos verticalmente uno por uno.
El espacio de nombres ftxui:: de FTXUI.
Argumentos para la transformación de |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, [&] {
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, [&] {
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;
}
return dimx size(HEIGHT, EQUAL, dimy)
return hbox({ text(std::to_string(int(progress *100))+"% ")|size(WIDTH, EQUAL, 5), gauge(progress), })
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, "Varias líneas (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);
});
auto renderer_line_block = Renderer([&] {
c.DrawText(0, 0, "Varias líneas (bloque)");
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);
});
auto renderer_circle_braille = Renderer([&] {
c.DrawText(0, 0, "Un círculo (braille)");
c.DrawPointCircle(mouse_x, mouse_y, 30);
});
auto renderer_circle_block = Renderer([&] {
c.DrawText(0, 0, "Un círculo (bloque)");
c.DrawBlockCircle(mouse_x, mouse_y, 30);
});
auto renderer_circle_filled_braille = Renderer([&] {
c.DrawText(0, 0, "Un círculo relleno (braille)");
c.DrawPointCircleFilled(mouse_x, mouse_y, 30);
});
auto renderer_circle_filled_block = Renderer([&] {
c.DrawText(0, 0, "Un círculo relleno (bloque)");
c.DrawBlockCircleFilled(mouse_x, mouse_y, 30);
});
auto renderer_ellipse_braille = Renderer([&] {
c.DrawText(0, 0, "Una elipse (braille)");
c.DrawPointEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
});
auto renderer_ellipse_block = Renderer([&] {
c.DrawText(0, 0, "Una elipse (bloque)");
c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
});
auto renderer_ellipse_filled_braille = Renderer([&] {
c.DrawText(0, 0, "Una elipse rellena (braille)");
c.DrawPointEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
mouse_y / 2);
});
auto renderer_ellipse_filled_block = Renderer([&] {
c.DrawText(0, 0, "Una elipse rellena (bloque)");
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);
});
auto renderer_text = Renderer([&] {
c.DrawText(0, 0, "Un trozo de texto");
c.DrawText(mouse_x, mouse_y, "Esto es un trozo de texto con efectos",
});
});
auto renderer_plot_1 = Renderer([&] {
c.DrawText(0, 0, "Un gráfico");
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]);
}
});
auto renderer_plot_2 = Renderer([&] {
c.DrawText(0, 0, "Un gráfico simétrico relleno");
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);
}
});
auto renderer_plot_3 = Renderer([&] {
c.DrawText(0, 0, "Un gráfico gaussiano 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]);
}
}
}
});
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 = {
"línea (braille)",
"línea (bloque)",
"círculo (braille)",
"círculo (bloque)",
"círculo relleno (braille)",
"círculo relleno (bloque)",
"elipse (braille)",
"elipse (bloque)",
"elipse rellena (braille)",
"elipse rellena (bloque)",
"trazado_1 simple",
"trazado_2 relleno",
"trazado_3 3D",
"texto",
};
auto tab_toggle = Menu(&tab_titles, &selected_tab);
auto component = Container::Horizontal({
tab_with_mouse,
tab_toggle,
});
auto component_renderer = Renderer(component, [&] {
tab_with_mouse->Render(),
separator(),
tab_toggle->Render(),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(component_renderer);
return 0;
}
Representa un evento. Puede ser un evento de pulsación de tecla, un redimensionamiento de terminal,...
Canvas es un búfer dibujable asociado con operaciones de dibujo.
Un carácter Unicode y su estilo asociado.
Element canvas(ConstRef< Canvas > canvas)
Produce un elemento a partir de un Canvas, o una referencia a un Canvas.
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("Casilla de verificación" + 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] {
text(" "),
vlist->Render(),
});
});
}
return std::make_shared<ComponentBase>();
}
auto component =
Collapsible("Collapsible 1",
Collapsible("Collapsible 1.1",
Collapsible(
"Collapsible 1.1.1",
Empty()),
Collapsible(
"Collapsible 1.1.2",
Empty()),
Collapsible(
"Collapsible 1.1.3",
Empty()),
})),
Collapsible("Collapsible 1.2",
Collapsible(
"Collapsible 1.2.1",
Empty()),
Collapsible(
"Collapsible 1.2.2",
Empty()),
Collapsible(
"Collapsible 1.2.3",
Empty()),
})),
Collapsible("Collapsible 1.3",
Collapsible(
"Collapsible 1.3.1",
Empty()),
Collapsible(
"Collapsible 1.3.2",
Empty()),
Collapsible(
"Collapsible 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++; }),
});
text("Este es el control izquierdo"),
separator(),
text("Left button count: " + std::to_string(left_count)),
left_buttons->Render(),
}) |
border;
});
auto rightpane = Renderer(right_buttons, [&] {
text("Este es el control derecho"),
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++;
text("Esto demuestra el uso de un ftxui::Loop personalizado. Se "),
text("ejecuta a 100 iteraciones por segundo. Los eventos de FTXUI "),
text("se procesan una vez por iteración y se renderiza un nuevo frame "),
text("según sea necesario"),
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 es una clase que gestiona el bucle de eventos de un componente.
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) {
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10),
filler(),
});
}
checkbox,
filler(),
});
},
});
auto dropdown_2 = Dropdown({
.radiobox = {.entries = &entries},
.transform =
if (open) {
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | bgcolor(Color::Blue),
filler(),
});
}
checkbox | bgcolor(Color::Blue),
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) {
checkbox | inverted,
radiobox | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 20) | bgcolor(Color::Red),
filler(),
});
}
checkbox | bgcolor(Color::Red),
filler(),
});
},
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(Container::Horizontal({
dropdown_1,
dropdown_2,
dropdown_3,
}));
}
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);
text(std::to_string(index)) | hcenter | dim) |
bgcolor(Color::HSV(index * 25, 255, 255)) |
color(Color::Black);
if (element_xflex_grow) {
element = element | xflex_grow;
}
if (element_yflex_grow) {
element = element | yflex_grow;
}
return element;
};
auto content_renderer = Renderer([&] {
{
},
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);
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,
});
window(text(
"FlexboxConfig::Direction"),
radiobox_direction->Render()),
window(text(
"FlexboxConfig::Wrap"), radiobox_wrap->Render()),
checkbox_element_xflex_grow->Render(),
checkbox_element_yflex_grow->Render(),
checkbox_group_xflex_grow->Render(),
checkbox_group_yflex_grow->Render(),
})),
}),
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)
Establece la dirección del flexbox.
FlexboxConfig es una estructura de configuración que define las propiedades de diseño para un contene...
return window(text(title)|hcenter|bold, text("contenido")|hcenter|dim)|size(WIDTH
return flexbox({ basic_color_display, palette_256_color_display, true_color_display, }, FlexboxConfig().SetGap(1, 1))
focus
Demo
#include <memory>
#include <string>
#include <vector>
std::string
title =
"(" + std::to_string(x) +
", " + std::to_string(y) +
")";
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) + ")";
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) {
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] {
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 = {
"Toggle_1",
"Toggle_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("checkbox1", &checkbox_1_selected),
Checkbox("checkbox2", &checkbox_2_selected),
Checkbox("checkbox3", &checkbox_3_selected),
Checkbox("checkbox4", &checkbox_4_selected),
});
checkboxes =
Wrap(
"Checkbox", checkboxes);
int radiobox_selected = 0;
std::vector<std::string> radiobox_entries = {
"Radiobox 1",
"Radiobox 2",
"Radiobox 3",
"Radiobox 4",
};
auto radiobox = Radiobox(&radiobox_entries, &radiobox_selected);
radiobox =
Wrap(
"Radiobox", radiobox);
std::string input_label;
auto input = Input(&input_label, "placeholder");
input =
Wrap(
"Input", input);
std::string button_label = "Quit";
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([] {
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, [&] {
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();
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([&] {
text("Frequency [Mhz]") | hcenter,
text("2400 "),
filler(),
text("1200 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | flex,
}) | flex,
});
auto utilization =
vbox({
text("Utilization [%]") | hcenter,
text("100 "),
filler(),
text("50 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | color(Color::RedLight),
}) | flex,
});
text("Ram [Mo]") | hcenter,
text("8192"),
filler(),
text("4096 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | color(Color::BlueLight),
}) | flex,
});
frequency | flex,
separator(),
utilization | flex,
}) | flex,
separator(),
ram | flex,
}) |
flex;
});
const std::vector<std::string> compiler_entries = {
"gcc",
"clang",
"emcc",
"game_maker",
"Compiladores de Ada",
"Compiladores de ALGOL 60",
"Compiladores de ALGOL 68",
"Ensambladores (Intel *86)",
"Ensambladores (Motorola 68*)",
"Ensambladores (Zilog Z80)",
"Ensambladores (otros)",
"Compiladores BASIC",
"Intérpretes BASIC",
"Compiladores por lotes",
"Compiladores C",
"Compiladores de fuente a fuente",
"Compiladores C++",
"Compiladores C#",
"Compiladores COBOL",
"Compiladores Common Lisp",
"Compiladores D",
"Compiladores DIBOL/DBL",
"Intérpretes ECMAScript",
"Compiladores Eiffel",
"Compiladores Fortran",
"Compiladores Go",
"Compiladores Haskell",
"Compiladores Java",
"Compiladores Pascal",
"Intérpretes Perl",
"Compiladores PHP",
"Compiladores PL/I",
"Compiladores Python",
"Compiladores e intérpretes Scheme",
"Compiladores Smalltalk",
"Intérpretes Tcl",
"Intérpretes VMS",
"Intérpretes Rexx",
"Compiladores 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,
"archivos de entrada", input_option);
std::string executable_content_ = "";
Component executable_ = Input(&executable_content_,
"ejecutable");
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(
"Compilador"),
compiler->Render() | vscroll_indicator | frame);
auto flags_win =
window(text(
"Banderas"), flags->Render() | vscroll_indicator | frame);
auto executable_win =
window(text(
"Ejecutable:"), executable_->Render());
auto input_win =
text("Añadir: "),
input_add->Render(),
filler(),
}),
separator(),
input->Render() | vscroll_indicator | frame |
}));
compiler_win,
flags_win,
}),
filler(),
}) |
size(HEIGHT, LESS_THAN, 8),
hflow(render_command()) | flex_grow,
}) |
flex_grow;
});
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));
});
text("Paleta de 16 colores:"),
separator(),
color(Color::Default, text("Predeterminado")),
color(Color::Black, text("Negro")),
color(Color::GrayDark, text("GrisOscuro")),
color(Color::GrayLight, text("GrisClaro")),
color(Color::White, text("Blanco")),
color(Color::Blue, text("Azul")),
color(Color::BlueLight, text("AzulClaro")),
color(Color::Cyan, text("Cian")),
color(Color::CyanLight, text("CianClaro")),
color(Color::Green, text("Verde")),
color(Color::GreenLight, text("VerdeClaro")),
color(Color::Magenta, text("Magenta")),
color(Color::MagentaLight, text("MagentaClaro")),
color(Color::Red, text("Rojo")),
color(Color::RedLight, text("RojoClaro")),
color(Color::Yellow, text("Amarillo")),
color(Color::YellowLight, text("AmarilloClaro")),
}),
bgcolor(Color::Default, text("Predeterminado")),
bgcolor(Color::Black, text("Negro")),
bgcolor(Color::GrayDark, text("GrisOscuro")),
bgcolor(Color::GrayLight, text("GrisClaro")),
bgcolor(Color::White, text("Blanco")),
bgcolor(Color::Blue, text("Azul")),
bgcolor(Color::BlueLight, text("AzulClaro")),
bgcolor(Color::Cyan, text("Cian")),
bgcolor(Color::CyanLight, text("CianClaro")),
bgcolor(Color::Green, text("Verde")),
bgcolor(Color::GreenLight, text("VerdeClaro")),
bgcolor(Color::Magenta, text("Magenta")),
bgcolor(Color::MagentaLight, text("MagentaClaro")),
bgcolor(Color::Red, text("Rojo")),
bgcolor(Color::RedLight, text("RojoClaro")),
bgcolor(Color::Yellow, text("Amarillo")),
bgcolor(Color::YellowLight, text("AmarilloClaro")),
}),
}),
}) |
border;
{
for (auto& column : info_columns) {
for (auto& it : column) {
column_elements.push_back(
}
}
separator(),
}) |
border;
}
{
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)));
}
}
separator(),
}) |
border;
}
{
},
});
float progress = (shift + delta) % 500 / 500.f;
text(std::to_string(
int(
progress * 100)) +
"% ") |
});
};
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),
});
});
std::string
title = std::to_string(dimx) +
"x" + std::to_string(dimy);
text("contenido") | hcenter | dim) |
};
std::string str =
"Lorem Ipsum es simplemente un texto ficticio de la industria de la "
"impresión y la tipografía.\nLorem Ipsum ha sido el texto ficticio "
"estándar de la industria desde el siglo XVI, cuando una impresora "
"desconocida tomó una galera de tipos y la mezcló para hacer un libro "
"de muestras de tipos.";
window(text(
"Alinear izquierda:"), paragraphAlignLeft(str)),
window(text(
"Alinear centro:"), paragraphAlignCenter(str)),
window(text(
"Alinear derecha:"), paragraphAlignRight(str)),
window(text(
"Alinear justificar:"), paragraphAlignJustify(str)),
paragraph(str),
separator(),
paragraph(str),
})),
window(text(
"Elementos con diferente tamaño:"),
})),
}) |
vscroll_indicator | yframe | flex;
});
return paragraph("<--- Esta barra vertical es redimensionable usando el ratón") |
center;
});
"htop", "color", "spinner", "gauge", "compiler", "paragraph",
};
{
htop,
color_tab_renderer,
spinner_tab_renderer,
compiler_renderer,
},
Button(
"Salir", [&] {
screen.Exit(); }, ButtonOption::Animated());
Container::Horizontal({
}),
});
text("Demostración de FTXUI") | bold | hcenter,
}),
});
});
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)
Establece el espacio (gap) del flexbox.
Color es una clase que representa un color en la interfaz de usuario de la terminal.
std::vector< std::string > tab_entries
int paragraph_renderer_split_position
auto palette_256_color_display
auto paragraph_renderer_group_renderer
auto paragraph_renderer_right
auto paragraph_renderer_left
auto paragraph_renderer_group
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);
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, [&] {
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
Oscurece el contenido del input usando '*'.
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 |= bgcolor(
LinearGradient(90, Color::Blue, Color::Red));
state.element |= color(Color::White);
} else {
state.element |= border;
state.element |= color(Color::White);
}
return state.element;
};
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
Una clase que representa la configuración para el efecto de color de gradiente lineal.
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));
background | flex,
layout->Render(),
}) |
flex;
});
}
maybe
Demo
#include <string>
#include <vector>
std::vector<std::string> entries = {
"entrada 1",
"entrada 2",
"entrada 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("Mostrar menu_1", &menu_1_show),
Radiobox(&entries, &menu_1_selected) | border | Maybe(&menu_1_show),
Checkbox("Mostrar menu_2", &menu_2_show),
Radiobox(&entries, &menu_2_selected) | border | Maybe(&menu_2_show),
Renderer([] {
return text("¡Encontraste la combinación secreta!") | 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;
hcenter(bold(text("Porcentaje por 10%"))),
separator(),
left_menu_->Render(),
}),
separator(),
hcenter(bold(text("Porcentaje por 1%"))),
separator(),
right_menu_->Render(),
}),
separator(),
}),
separator(),
text(" medidor : "),
gauge(sum / 100.0),
}),
text(" texto : "),
text(std::to_string(sum) + " %"),
}),
}),
}) |
border;
});
}
menu_entries
Demo
#include <functional>
#include <iostream>
#include <memory>
#include <string>
state.label = (state.active ? "> " : " ") + state.label;
Element e = text(state.label) | color(c);
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, [&] {
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, [&] {
hbox(text(
"selected = "), text(std::to_string(selected))),
separator(),
menu->Render() | frame,
}) |
border | bgcolor(Color::Black);
});
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 = {
{
"Piña",
"Frambuesa",
"Cítricos",
},
{
"Patatas",
"Trigo",
"Arroz",
},
{
"Zanahoria",
"Lechuga",
"Tomate",
},
};
int menu_selected_global = 0;
auto menu_global = Container::Vertical(
{
Window(
"Menú 1", Menu(&menu_entries[0], &menu_selected[0])),
Window(
"Menú 2", Menu(&menu_entries[1], &menu_selected[1])),
Window(
"Menú 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(
"Contenido"),
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("Valor = " + 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
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) {
e = e | bgcolor(Color::Blue);
}
if (state.active) {
e = e | bold;
}
return e;
};
return Menu(entries, selected, option);
}
auto option = MenuOption::Vertical();
state.label += (state.active ? " <" : " ");
if (state.focused) {
e = e | bgcolor(Color::Red);
}
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;
}
e = e | color(Color::Blue);
}
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)
Una opción de color que puede ser animada.
if(IsFullWidth(codepoint))
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(
"Esto demuestra el componente Menu"));
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Establecer color de subrayado en azul"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_inactive = Color::Blue;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Establecer color activo de subrayado en rojo"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_active = Color::Red;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Establecer duración de la animación en 0ms"));
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimationDuration(0ms);
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(
Text(
"Establecer función de aceleración de animación a 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(
"Añadir retraso para desincronizar la animación"));
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) {
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) {
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 = [&] {};
main_component |= Modal(modal_component, &modal_shown);
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 estrellas";
auto button_rate_ftxui = Button("Calificar FTXUI", [&] { depth = 1; });
auto button_quit = Button(
"Salir",
screen.ExitLoopClosure());
auto depth_0_container = Container::Horizontal({
button_rate_ftxui,
button_quit,
});
auto depth_0_renderer = Renderer(depth_0_container, [&] {
text("Ejemplo de diálogo modal"),
separator(),
text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold,
filler(),
button_rate_ftxui->Render(),
filler(),
button_quit->Render(),
}),
}) |
border |
size(HEIGHT, GREATER_THAN, 18) | center;
});
std::vector<std::string> rating_labels = {
"1/5 estrellas", "2/5 estrellas", "3/5 estrellas", "4/5 estrellas", "5/5 estrellas",
};
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, [&] {
text("¿Te gusta FTXUI?"),
separator(),
hbox(depth_1_container->Render()),
}) |
border;
});
{
depth_0_renderer,
depth_1_renderer,
},
&depth);
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(
"Back",
screen.ExitLoopClosure());
auto goto_1 = Button(
"Goto /1", [path] {
Nested(path +
"/1"); });
auto goto_2 = Button(
"Goto /2", [path] {
Nested(path +
"/2"); });
auto goto_3 = Button(
"Goto /3", [path] {
Nested(path +
"/3"); });
auto layout = Container::Vertical({
back_button,
goto_1,
goto_2,
goto_3,
});
auto renderer = Renderer(layout, [&] {
text("path: " + path),
separator(),
back_button->Render(),
goto_1->Render(),
goto_2->Render(),
goto_3->Render(),
}) |
border;
});
}
auto screen = ScreenInteractive::FitComponent();
auto button_quit = Button(
"Quit",
screen.ExitLoopClosure());
auto button_nested = Button(
"Nested", [] {
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])));
}
});
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()));
}
});
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("FOCUSABLE RENDERER()") | center | bold | border;
} else {
return text(" Focusable renderer() ") | center | border;
}
});
auto renderer_non_focusable = Renderer([&] {
return text("~~~~~ Non Focusable renderer() ~~~~~");
});
auto button = Button(
"Wrapped quit button",
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(
"Arrastra el separador con el ratón"),
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.";
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 = "First window",
.width = 80,
.height = 30,
});
.title = "My window",
.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;
}
Implementa el renderizado de sí mismo como ftxui::Element. Implementa la navegación por teclado respo...
selection
Demo
#include <string>
text("FTXUI: Una potente biblioteca para construir interfaces de usuario."),
text("Disfruta de un rico conjunto de componentes y un estilo declarativo."),
text("Crea UIs hermosas y responsivas con un mínimo esfuerzo."),
text("Únete a la comunidad y experimenta el poder de FTXUI."),
});
}
auto screen = ScreenInteractive::TerminalOutput();
auto quit =
Button(
"Quit",
screen.ExitLoopClosure(), ButtonOption::Animated());
int selection_change_counter = 0;
std::string selection_content = "";
selection_change_counter++;
selection_content =
screen.GetSelection();
});
auto renderer = Renderer(quit, [&] {
text("Selección cambiada: " + std::to_string(selection_change_counter) +
" veces"),
text("Actualmente seleccionado: "),
paragraph(selection_content) | vscroll_indicator | frame | border |
separator(),
separator(),
})),
separator(),
separator(),
})),
window(text(
"División en cuadrícula con estilo diferente"),
separator(),
| selectionBackgroundColor(Color::Yellow)
| selectionColor(Color::Black)
| selectionStyleReset,
separator(),
}),
separator(),
separator(),
}),
separator(),
}),
})),
quit->Render(),
});
});
}
slider
Demo
auto screen = ScreenInteractive::TerminalOutput();
int value = 50;
auto slider = Slider("Valor:", &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("Rojo :", &red, 0, 255, 1);
auto slider_green = Slider("Verde:", &green, 0, 255, 1);
auto slider_blue = Slider("Azul :", &blue, 0, 255, 1);
auto container = Container::Vertical({
slider_red,
slider_green,
slider_blue,
});
auto renderer = Renderer(container, [&] {
separator(),
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, [&] {
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, [&] {
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, [&] {
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, [&] {
text("Elige tus opciones:"),
text(""),
hbox(text(
" * Apagar al inicio : "), toggle_1->Render()),
hbox(text(
" * Fuera de proceso : "), toggle_2->Render()),
hbox(text(
" * Precio de la información : "), toggle_3->Render()),
hbox(text(
" * Número de elementos : "), 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("Check me", &checked[0]),
Checkbox("Check me", &checked[1]),
Checkbox("Check me", &checked[2]),
Slider("Slider", &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 = "First window",
.left = &window_1_left,
.top = &window_1_top,
.width = &window_1_width,
.height = &window_1_height,
});
.title = "My window",
.left = 40,
.top = 20,
});
.title = "My window",
.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(
"Ejecutar con E/S restaurada",
screen.WithRestoredIO([] {
std::cout << "Este es un programa hijo usando stdin/stdout." << std::endl;
for (int i = 0; i < 10; ++i) {
std::cout << "Por favor, introduce 10 cadenas (" << i << "/10)" << std::flush;
std::string input;
std::getline(std::cin, input);
}
}));
auto btn_quit = Button(
"Salir",
screen.ExitLoopClosure());
auto layout = Container::Horizontal({
btn_run,
btn_quit,
});
auto renderer = Renderer(layout, [&] {
auto explanation = paragraph(
"Después de hacer clic en este botón, ScreenInteractive se "
"suspenderá y el acceso a stdin/stdout se restaurará temporalmente "
"para ejecutar una función.");
explanation | borderEmpty,
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;
}