FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
homescreen.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. Todos los derechos reservados.
2// El uso de este código fuente se rige por la licencia MIT que se puede encontrar en
3// el archivo LICENSE.
4#include <stddef.h> // for size_t
5#include <array> // for array
6#include <atomic> // for atomic
7#include <chrono> // for operator""s, chrono_literals
8#include <cmath> // for sin
10#include <functional> // for ref, reference_wrapper, function
11#include <memory> // for allocator, shared_ptr, __shared_ptr_access
12#include <string> // for string, basic_string, char_traits, operator+, to_string
13#include <thread> // for sleep_for, thread
14#include <utility> // for move
15#include <vector> // for vector
16
17#include "../dom/color_info_sorted_2d.ipp" // for ColorInfoSorted2D
18#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab
19#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
20#include "ftxui/component/component_options.hpp" // for MenuOption, InputOption
21#include "ftxui/component/event.hpp" // for Event, Event::Custom
22#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
23#include "ftxui/dom/elements.hpp" // for text, color, operator|, bgcolor, filler, Element, vbox, size, hbox, separator, flex, window, graph, EQUAL, paragraph, WIDTH, hcenter, Elements, bold, vscroll_indicator, HEIGHT, flexbox, hflow, border, frame, flex_grow, gauge, paragraphAlignCenter, paragraphAlignJustify, paragraphAlignLeft, paragraphAlignRight, dim, spinner, LESS_THAN, center, yframe, GREATER_THAN
24#include "ftxui/dom/flexbox_config.hpp" // for FlexboxConfig
25#include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::Black, Color::Blue, Color::Cyan, Color::CyanLight, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::White, Color::Yellow, Color::YellowLight, Color::Default, Color::Palette256, ftxui
26#include "ftxui/screen/color_info.hpp" // for ColorInfo
27#include "ftxui/screen/terminal.hpp" // for Size, Dimensions
28
29using namespace ftxui;
30
31int main() {
33
34 // ---------------------------------------------------------------------------\n // HTOP
35 // ---------------------------------------------------------------------------\n int shift = 0;
36
37 auto my_graph = [&shift](int width, int height) {
38 std::vector<int> output(width);
39 for (int i = 0; i < width; ++i) {
40 float v = 0.5f;
41 v += 0.1f * sin((i + shift) * 0.1f);
42 v += 0.2f * sin((i + shift + 10) * 0.15f);
43 v += 0.1f * sin((i + shift) * 0.03f);
44 v *= height;
45 output[i] = (int)v;
46 }
47 return output;
48 };
49
50 auto htop = Renderer([&] {
51 auto frequency = vbox({
52 text("Frequency [Mhz]") | hcenter,
53 hbox({
54 vbox({
55 text("2400 "),
56 filler(),
57 text("1200 "),
58 filler(),
59 text("0 "),
60 }),
61 graph(std::ref(my_graph)) | flex,
62 }) | flex,
63 });
64
65 auto utilization = vbox({
66 text("Utilization [%]") | hcenter,
67 hbox({
68 vbox({
69 text("100 "),
70 filler(),
71 text("50 "),
72 filler(),
73 text("0 "),
74 }),
75 graph(std::ref(my_graph)) | color(Color::RedLight),
76 }) | flex,
77 });
78
79 auto ram = vbox({
80 text("Ram [Mo]") | hcenter,
81 hbox({
82 vbox({
83 text("8192"),
84 filler(),
85 text("4096 "),
86 filler(),
87 text("0 "),
88 }),
89 graph(std::ref(my_graph)) | color(Color::BlueLight),
90 }) | flex,
91 });
92
93 return hbox({
94 vbox({
95 frequency | flex,
96 separator(),
97 utilization | flex,
98 }) | flex,
99 separator(),
100 ram | flex,
101 }) |
102 flex;
103 });
104
105 // ---------------------------------------------------------------------------\n // Compilador
106 // ---------------------------------------------------------------------------\n
107 const std::vector<std::string> compiler_entries = {
108 "gcc",
109 "clang",
110 "emcc",
111 "game_maker",
112 "Compiladores de Ada",
113 "Compiladores de ALGOL 60",
114 "Compiladores de ALGOL 68",
115 "Ensambladores (Intel *86)",
116 "Ensambladores (Motorola 68*)",
117 "Ensambladores (Zilog Z80)",
118 "Ensambladores (otros)",
119 "Compiladores BASIC",
120 "Intérpretes BASIC",
121 "Compiladores por lotes",
122 "Compiladores C",
123 "Compiladores de fuente a fuente",
124 "Compiladores C++",
125 "Compiladores C#",
126 "Compiladores COBOL",
127 "Compiladores Common Lisp",
128 "Compiladores D",
129 "Compiladores DIBOL/DBL",
130 "Intérpretes ECMAScript",
131 "Compiladores Eiffel",
132 "Compiladores Fortran",
133 "Compiladores Go",
134 "Compiladores Haskell",
135 "Compiladores Java",
136 "Compiladores Pascal",
137 "Intérpretes Perl",
138 "Compiladores PHP",
139 "Compiladores PL/I",
140 "Compiladores Python",
141 "Compiladores e intérpretes Scheme",
142 "Compiladores Smalltalk",
143 "Intérpretes Tcl",
144 "Intérpretes VMS",
145 "Intérpretes Rexx",
146 "Compiladores CLI",
147 };
148
149 int compiler_selected = 0;
150 Component compiler = Radiobox(&compiler_entries, &compiler_selected);
151
152 std::array<std::string, 8> options_label = {
153 "-Wall",
154 "-Werror",
155 "-lpthread",
156 "-O3",
157 "-Wabi-tag",
158 "-Wno-class-conversion",
159 "-Wcomma-subscript",
160 "-Wno-conversion-null",
161 };
162 std::array<bool, 8> options_state = {
163 false, false, false, false, false, false, false, false,
164 };
165
166 std::vector<std::string> input_entries;
167 int input_selected = 0;
168 Component input = Menu(&input_entries, &input_selected);
169
170 auto input_option = InputOption();
171 std::string input_add_content;
172 input_option.on_enter = [&] {
173 input_entries.push_back(input_add_content);
174 input_add_content = "";
175 };
176 Component input_add = Input(&input_add_content, "archivos de entrada", input_option);
177
178 std::string executable_content_ = "";
179 Component executable_ = Input(&executable_content_, "ejecutable");
180
181 Component flags = Container::Vertical({
182 Checkbox(&options_label[0], &options_state[0]),
183 Checkbox(&options_label[1], &options_state[1]),
184 Checkbox(&options_label[2], &options_state[2]),
185 Checkbox(&options_label[3], &options_state[3]),
186 Checkbox(&options_label[4], &options_state[4]),
187 Checkbox(&options_label[5], &options_state[5]),
188 Checkbox(&options_label[6], &options_state[6]),
189 Checkbox(&options_label[7], &options_state[7]),
190 });
191
192 auto compiler_component = Container::Horizontal({
193 compiler,
194 flags,
195 Container::Vertical({
196 executable_,
197 Container::Horizontal({
198 input_add,
199 input,
200 }),
201 }),
202 });
203
204 auto render_command = [&] {
205 Elements line;
206 // Compilador
207 line.push_back(text(compiler_entries[compiler_selected]) | bold);
208 // flags
209 for (int i = 0; i < 8; ++i) {
210 if (options_state[i]) {
211 line.push_back(text(" "));
212 line.push_back(text(options_label[i]) | dim);
213 }
214 }
215 // Ejecutable
216 if (!executable_content_.empty()) {
217 line.push_back(text(" -o ") | bold);
218 line.push_back(text(executable_content_) | color(Color::BlueLight) |
219 bold);
220 }
221 // Entrada
222 for (auto& it : input_entries) {
223 line.push_back(text(" " + it) | color(Color::RedLight));
224 }
225 return line;
226 };
227
228 auto compiler_renderer = Renderer(compiler_component, [&] {
229 auto compiler_win = window(text("Compilador"),
230 compiler->Render() | vscroll_indicator | frame);
231 auto flags_win =
232 window(text("Banderas"), flags->Render() | vscroll_indicator | frame);
233 auto executable_win = window(text("Ejecutable:"), executable_->Render());
234 auto input_win =
235 window(text("Entrada"), hbox({
236 vbox({
237 hbox({
238 text("Añadir: "),
239 input_add->Render(),
240 }) | size(WIDTH, EQUAL, 20) |
241 size(HEIGHT, EQUAL, 1),
242 filler(),
243 }),
244 separator(),
245 input->Render() | vscroll_indicator | frame |
246 size(HEIGHT, EQUAL, 3) | flex,
247 }));
248 return vbox({
249 hbox({
250 compiler_win,
251 flags_win,
252 vbox({
253 executable_win | size(WIDTH, EQUAL, 20),
254 input_win | size(WIDTH, EQUAL, 60),
255 }),
256 filler(),
257 }) | size(HEIGHT, LESS_THAN, 8),
258 hflow(render_command()) | flex_grow,
259 }) |
260 flex_grow;
261 });
262
263 // ---------------------------------------------------------------------------\n // Spinner
264 // ---------------------------------------------------------------------------\n auto spinner_tab_renderer = Renderer([&] {
265 Elements entries;
266 for (int i = 0; i < 22; ++i) {
267 entries.push_back(spinner(i, shift / 5) | bold |
268 size(WIDTH, GREATER_THAN, 2) | border);
269 }
270 return hflow(std::move(entries));
271 });
272
273 // ---------------------------------------------------------------------------\n // Colores
274 // ---------------------------------------------------------------------------\n auto color_tab_renderer = Renderer([] {
276 vbox({
277 text("Paleta de 16 colores:"),
278 separator(),
279 hbox({
280 vbox({
281 color(Color::Default, text("Predeterminado")),
282 color(Color::Black, text("Negro")),
283 color(Color::GrayDark, text("GrisOscuro")),
284 color(Color::GrayLight, text("GrisClaro")),
285 color(Color::White, text("Blanco")),
286 color(Color::Blue, text("Azul")),
287 color(Color::BlueLight, text("AzulClaro")),
288 color(Color::Cyan, text("Cian")),
289 color(Color::CyanLight, text("CianClaro")),
290 color(Color::Green, text("Verde")),
291 color(Color::GreenLight, text("VerdeClaro")),
292 color(Color::Magenta, text("Magenta")),
293 color(Color::MagentaLight, text("MagentaClaro")),
294 color(Color::Red, text("Rojo")),
295 color(Color::RedLight, text("RojoClaro")),
296 color(Color::Yellow, text("Amarillo")),
297 color(Color::YellowLight, text("AmarilloClaro")),
298 }),
299 vbox({
300 bgcolor(Color::Default, text("Predeterminado")),
301 bgcolor(Color::Black, text("Negro")),
302 bgcolor(Color::GrayDark, text("GrisOscuro")),
303 bgcolor(Color::GrayLight, text("GrisClaro")),
304 bgcolor(Color::White, text("Blanco")),
305 bgcolor(Color::Blue, text("Azul")),
306 bgcolor(Color::BlueLight, text("AzulClaro")),
307 bgcolor(Color::Cyan, text("Cian")),
308 bgcolor(Color::CyanLight, text("CianClaro")),
309 bgcolor(Color::Green, text("Verde")),
310 bgcolor(Color::GreenLight, text("VerdeClaro")),
311 bgcolor(Color::Magenta, text("Magenta")),
312 bgcolor(Color::MagentaLight, text("MagentaClaro")),
313 bgcolor(Color::Red, text("Rojo")),
314 bgcolor(Color::RedLight, text("RojoClaro")),
315 bgcolor(Color::Yellow, text("Amarillo")),
316 bgcolor(Color::YellowLight, text("AmarilloClaro")),
317 }),
318 }),
319 }) |
320 border;
321
322 auto palette_256_color_display = text("Paleta de 256 colores:");
323 {
324 std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
326 for (auto& column : info_columns) {
327 Elements column_elements;
328 for (auto& it : column) {
329 column_elements.push_back(
330 text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
331 }
332 columns.push_back(hbox(std::move(column_elements)));
333 }
336 separator(),
337 vbox(columns),
338 }) |
339 border;
340 }
341
342 // Visualización de color verdadero.
343 auto true_color_display = text("Colores verdaderos: 24bits:");
344 {
345 int saturation = 255;
347 for (int value = 0; value < 255; value += 16) {
348 Elements line;
349 for (int hue = 0; hue < 255; hue += 6) {
350 line.push_back(text("▀") //
351 | color(Color::HSV(hue, saturation, value)) //
352 | bgcolor(Color::HSV(hue, saturation, value + 8)));
353 }
354 array.push_back(hbox(std::move(line)));
355 }
358 separator(),
359 vbox(std::move(array)),
360 }) |
361 border;
362 }
363
364 return flexbox(
365 {
369 },
370 FlexboxConfig().SetGap(1, 1));
371 });
372
373 // ---------------------------------------------------------------------------\n // Medidores
374 // ---------------------------------------------------------------------------\n auto render_gauge = [&shift](int delta) {
375 float progress = (shift + delta) % 500 / 500.f;
376 return hbox({
377 text(std::to_string(int(progress * 100)) + "% ") |
378 size(WIDTH, EQUAL, 5),
380 });
381 };
382
383 auto gauge_component = Renderer([render_gauge] {
384 return vbox({
385 render_gauge(0) | color(Color::Black),
386 render_gauge(100) | color(Color::GrayDark),
387 render_gauge(50) | color(Color::GrayLight),
388 render_gauge(6894) | color(Color::White),
389 separator(),
390 render_gauge(6841) | color(Color::Blue),
391 render_gauge(9813) | color(Color::BlueLight),
392 render_gauge(98765) | color(Color::Cyan),
393 render_gauge(98) | color(Color::CyanLight),
394 render_gauge(9846) | color(Color::Green),
395 render_gauge(1122) | color(Color::GreenLight),
396 render_gauge(84) | color(Color::Magenta),
397 render_gauge(645) | color(Color::MagentaLight),
398 render_gauge(568) | color(Color::Red),
399 render_gauge(2222) | color(Color::RedLight),
400 render_gauge(220) | color(Color::Yellow),
401 render_gauge(348) | color(Color::YellowLight),
402 });
403 });
404
405 // ---------------------------------------------------------------------------\n // Párrafo
406 // ---------------------------------------------------------------------------\n auto make_box = [](size_t dimx, size_t dimy) {
407 std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
408 return window(text(title) | hcenter | bold,
409 text("contenido") | hcenter | dim) |
410 size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
411 };
412
414 std::string str =
415 "Lorem Ipsum es simplemente un texto ficticio de la industria de la "
416 "impresión y la tipografía.\nLorem Ipsum ha sido el texto ficticio "
417 "estándar de la industria desde el siglo XVI, cuando una impresora "
418 "desconocida tomó una galera de tipos y la mezcló para hacer un libro "
419 "de muestras de tipos.";
420 return vbox({
421 window(text("Alinear izquierda:"), paragraphAlignLeft(str)),
422 window(text("Alinear centro:"), paragraphAlignCenter(str)),
423 window(text("Alinear derecha:"), paragraphAlignRight(str)),
424 window(text("Alinear justificar:"), paragraphAlignJustify(str)),
425 window(text("Lado a lado"), hbox({
426 paragraph(str),
427 separator(),
428 paragraph(str),
429 })),
430 window(text("Elementos con diferente tamaño:"),
431 flexbox({
432 make_box(10, 5),
433 make_box(9, 4),
434 make_box(8, 4),
435 make_box(6, 3),
436 make_box(10, 5),
437 make_box(9, 4),
438 make_box(8, 4),
439 make_box(6, 3),
440 make_box(10, 5),
441 make_box(9, 4),
442 make_box(8, 4),
443 make_box(6, 3),
444 })),
445 }) |
446 vscroll_indicator | yframe | flex;
447 });
448
450 return paragraph("<--- Esta barra vertical es redimensionable usando el ratón") |
451 center;
452 });
453
454 int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
460 [&] { return paragraph_renderer_group->Render(); });
461
462 // ---------------------------------------------------------------------------\n // Pestañas
463 // ---------------------------------------------------------------------------\n
464 int tab_index = 0;
465 std::vector<std::string> tab_entries = {
466 "htop", "color", "spinner", "gauge", "compiler", "paragraph",
467 };
470 auto tab_content = Container::Tab(
471 {
472 htop,
473 color_tab_renderer,
474 spinner_tab_renderer,
476 compiler_renderer,
478 },
479 &tab_index);
480
482 Button("Salir", [&] { screen.Exit(); }, ButtonOption::Animated());
483
484 auto main_container = Container::Vertical({
485 Container::Horizontal({
488 }),
490 });
491
493 return vbox({
494 text("Demostración de FTXUI") | bold | hcenter,
495 hbox({
496 tab_selection->Render() | flex,
498 }),
500 });
501 });
502
504 while (!loop.HasQuitted()) {
505 // Actualizar el estado de la aplicación.
506 shift++;
507
508 // Solicitar que se dibuje un nuevo fotograma.
509 screen.RequestAnimationFrame();
510
511 // Ejecutar eventos y dibujar el siguiente fotograma.
512 loop.RunOnce();
513
514 // Esperar una corta duración para controlar la velocidad de fotogramas (60 FPS).
515 std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 60));
516 }
517
518 return 0;
519}
std::vector< std::vector< ftxui::ColorInfo > > ColorInfoSorted2D()
Element make_box(int x, int y)
Element Render()
Dibuja el componente. Construye un ftxui::Element para ser dibujado en la ftxui::Screen representando...
static ScreenInteractive Fullscreen()
void RunOnce()
Ejecuta el bucle una vez. Hace que el component procese todas las tareas/eventos pendientes....
Definition loop.cpp:37
static MenuOption HorizontalAnimated()
Opciones estándar para un menú horizontal animado. Esto puede ser útil para implementar una barra de ...
static ButtonOption Animated()
Loop es una clase que gestiona el bucle de eventos de un componente.
Definition loop.hpp:56
Component Menu(MenuOption options)
Una lista de texto. El elemento enfocado es seleccionado.
Component Radiobox(RadioboxOption options)
Una lista de elementos, donde solo uno puede ser seleccionado.
Component Button(ButtonOption options)
Dibuja un botón. Ejecuta una función al hacer clic.
Component Renderer(Component child, std::function< Element()>)
Retorna un nuevo Componente, similar a |child|, pero usando |render| como el evento Component::Render...
Component Input(InputOption options={})
Un cuadro de entrada para editar texto.
Component Checkbox(CheckboxOption options)
Dibuja un elemento seleccionable.
Component ResizableSplitLeft(Component main, Component back, int *main_size)
Una división horizontal entre dos componentes, configurable usando el ratón.
Opción para el componente Input.
virtual void Render(Screen &screen)
Muestra un elemento en un ftxui::Screen.
Definition node.cpp:59
FlexboxConfig & SetGap(int gap_x, int gap_y)
Establece el espacio (gap) del flexbox.
Decorator bgcolor(Color)
Decora usando un color de fondo.
Element window(Element title, Element content, BorderStyle border=ROUNDED)
Draw window with a title and a border around the element.
Decorator size(WidthOrHeight, Constraint, int value)
Aplica una restricción al tamaño de un elemento.
Element flex(Element)
Hace que un elemento hijo se expanda proporcionalmente al espacio restante en un contenedor.
Definition flex.cpp:123
Element paragraphAlignRight(const std::string &text)
Devuelve un elemento que dibuja el párrafo en varias líneas, alineado a la derecha.
Element spinner(int charset_index, size_t image_index)
Útil para representar el efecto del tiempo y/o eventos. Esto muestra un "video" de arte ASCII.
Element center(Element)
Centra un elemento horizontal y verticalmente.
Element paragraphAlignCenter(const std::string &text)
Devuelve un elemento que dibuja el párrafo en varias líneas, alineado al centro.
Element text(std::wstring text)
Muestra un fragmento de texto Unicode.
Definition text.cpp:160
Element flex_grow(Element)
Expandir si es posible.
Definition flex.cpp:141
Element paragraphAlignLeft(const std::string &text)
Devuelve un elemento que dibuja el párrafo en varias líneas, alineado a la izquierda.
Element separator()
Dibuja una separación vertical u horizontal entre otros dos elementos.
Element filler()
Un elemento que se expandirá proporcionalmente al espacio restante en un contenedor.
Definition flex.cpp:98
Element gauge(float progress)
Dibuja una barra de progreso de alta definición.
Element paragraphAlignJustify(const std::string &text)
Devuelve un elemento que dibuja el párrafo en varias líneas, alineado utilizando una alineación justi...
Decorator color(Color)
Decora usando un color de primer plano.
Element hcenter(Element)
Centra un elemento horizontalmente.
FlexboxConfig es una estructura de configuración que define las propiedades de diseño para un contene...
static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value)
Construye un Color a partir de su representación HSV. https://en.wikipedia.org/wiki/HSL_and_HSV.
Color es una clase que representa un color en la interfaz de usuario de la terminal.
Definition color.hpp:21
std::vector< std::string > tab_entries
auto true_color_display
Elements array
auto main_renderer
int paragraph_renderer_split_position
auto main_container
auto palette_256_color_display
auto paragraph_renderer_group_renderer
auto paragraph_renderer_right
auto gauge_component
Elements columns
auto paragraph_renderer_left
auto basic_color_display
std::string title
int tab_index
float progress
auto exit_button
auto tab_content
int main()
auto paragraph_renderer_group
Loop loop & screen
auto tab_selection
El espacio de nombres ftxui:: de FTXUI.
Definition animation.hpp:10
Element flexbox(Elements, FlexboxConfig config=FlexboxConfig())
Un contenedor que muestra elementos en filas/columnas y es capaz de ajustarse a la siguiente columna/...
Definition flexbox.cpp:251
Element hflow(Elements)
Un contenedor que muestra elementos en filas de izquierda a derecha. Cuando está lleno,...
Definition flexbox.cpp:269
Element hbox(Elements)
Un contenedor que muestra elementos horizontalmente uno por uno.
Definition hbox.cpp:94
std::vector< Element > Elements
Definition elements.hpp:23
Element vbox(Elements)
Elements paragraph(std::wstring text)
@ LESS_THAN
Definition elements.hpp:162
@ GREATER_THAN
Definition elements.hpp:162
Element graph(GraphFunction)
Dibuja un gráfico usando una GraphFunction.
std::shared_ptr< ComponentBase > Component