FTXUI 6.1.9
C++ functional terminal UI.
Chargement...
Recherche...
Aucune correspondance
homescreen.cpp
Aller à la documentation de ce fichier.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// L'utilisation de ce code source est régie par la licence MIT qui peut être trouvée dans
3// le fichier 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 // ---------------------------------------------------------------------------
35 // HTOP
36 // ---------------------------------------------------------------------------
37 int shift = 0;
38
39 auto my_graph = [&shift](int width, int height) {
40 std::vector<int> output(width);
41 for (int i = 0; i < width; ++i) {
42 float v = 0.5f;
43 v += 0.1f * sin((i + shift) * 0.1f);
44 v += 0.2f * sin((i + shift + 10) * 0.15f);
45 v += 0.1f * sin((i + shift) * 0.03f);
46 v *= height;
47 output[i] = (int)v;
48 }
49 return output;
50 };
51
52 auto htop = Renderer([&] {
53 auto frequency = vbox({
54 text("Fréquence [Mhz]") | hcenter,
55 hbox({
56 vbox({
57 text("2400 "),
58 filler(),
59 text("1200 "),
60 filler(),
61 text("0 "),
62 }),
63 graph(std::ref(my_graph)) | flex,
64 }) | flex,
65 });
66
67 auto utilization = vbox({
68 text("Utilisation [%]") | hcenter,
69 hbox({
70 vbox({
71 text("100 "),
72 filler(),
73 text("50 "),
74 filler(),
75 text("0 "),
76 }),
77 graph(std::ref(my_graph)) | color(Color::RedLight),
78 }) | flex,
79 });
80
81 auto ram = vbox({
82 text("Ram [Mo]") | hcenter,
83 hbox({
84 vbox({
85 text("8192"),
86 filler(),
87 text("4096 "),
88 filler(),
89 text("0 "),
90 }),
91 graph(std::ref(my_graph)) | color(Color::BlueLight),
92 }) | flex,
93 });
94
95 return hbox({
96 vbox({
97 frequency | flex,
98 separator(),
99 utilization | flex,
100 }) | flex,
101 separator(),
102 ram | flex,
103 }) |
104 flex;
105 });
106
107 // ---------------------------------------------------------------------------
108 // Compilateur
109 // ---------------------------------------------------------------------------
110
111 const std::vector<std::string> compiler_entries = {
112 "gcc",
113 "clang",
114 "emcc",
115 "game_maker",
116 "Compilateurs Ada",
117 "Compilateurs ALGOL 60",
118 "Compilateurs ALGOL 68",
119 "Assembleurs (Intel *86)",
120 "Assembleurs (Motorola 68*)",
121 "Assembleurs (Zilog Z80)",
122 "Assembleurs (autres)",
123 "Compilateurs BASIC",
124 "Interprètes BASIC",
125 "Compilateurs Batch",
126 "Compilateurs C",
127 "Compilateurs source à source",
128 "Compilateurs C++",
129 "Compilateurs C#",
130 "Compilateurs COBOL",
131 "Compilateurs Common Lisp",
132 "Compilateurs D",
133 "Compilateurs DIBOL/DBL",
134 "Interprètes ECMAScript",
135 "Compilateurs Eiffel",
136 "Compilateurs Fortran",
137 "Compilateurs Go",
138 "Compilateurs Haskell",
139 "Compilateurs Java",
140 "Compilateurs Pascal",
141 "Interprètes Perl",
142 "Compilateurs PHP",
143 "Compilateurs PL/I",
144 "Compilateurs Python",
145 "Compilateurs et interprètes Scheme",
146 "Compilateurs Smalltalk",
147 "Interprètes Tcl",
148 "Interprètes VMS",
149 "Interprètes Rexx",
150 "Compilateurs CLI",
151 };
152
153 int compiler_selected = 0;
154 Component compiler = Radiobox(&compiler_entries, &compiler_selected);
155
156 std::array<std::string, 8> options_label = {
157 "-Wall",
158 "-Werror",
159 "-lpthread",
160 "-O3",
161 "-Wabi-tag",
162 "-Wno-class-conversion",
163 "-Wcomma-subscript",
164 "-Wno-conversion-null",
165 };
166 std::array<bool, 8> options_state = {
167 false, false, false, false, false, false, false, false,
168 };
169
170 std::vector<std::string> input_entries;
171 int input_selected = 0;
172 Component input = Menu(&input_entries, &input_selected);
173
174 auto input_option = InputOption();
175 std::string input_add_content;
176 input_option.on_enter = [&] {
177 input_entries.push_back(input_add_content);
178 input_add_content = "";
179 };
180 Component input_add = Input(&input_add_content, "fichiers d'entrée", input_option);
181
182 std::string executable_content_ = "";
183 Component executable_ = Input(&executable_content_, "exécutable");
184
185 Component flags = Container::Vertical({
186 Checkbox(&options_label[0], &options_state[0]),
187 Checkbox(&options_label[1], &options_state[1]),
188 Checkbox(&options_label[2], &options_state[2]),
189 Checkbox(&options_label[3], &options_state[3]),
190 Checkbox(&options_label[4], &options_state[4]),
191 Checkbox(&options_label[5], &options_state[5]),
192 Checkbox(&options_label[6], &options_state[6]),
193 Checkbox(&options_label[7], &options_state[7]),
194 });
195
196 auto compiler_component = Container::Horizontal({
197 compiler,
198 flags,
199 Container::Vertical({
200 executable_,
201 Container::Horizontal({
202 input_add,
203 input,
204 }),
205 }),
206 });
207
208 auto render_command = [&] {
209 Elements line;
210 // Compilateur
211 line.push_back(text(compiler_entries[compiler_selected]) | bold);
212 // drapeaux
213 for (int i = 0; i < 8; ++i) {
214 if (options_state[i]) {
215 line.push_back(text(" "));
216 line.push_back(text(options_label[i]) | dim);
217 }
218 }
219 // Exécutable
220 if (!executable_content_.empty()) {
221 line.push_back(text(" -o ") | bold);
222 line.push_back(text(executable_content_) | color(Color::BlueLight) |
223 bold);
224 }
225 // Entrée
226 for (auto& it : input_entries) {
227 line.push_back(text(" " + it) | color(Color::RedLight));
228 }
229 return line;
230 };
231
232 auto compiler_renderer = Renderer(compiler_component, [&] {
233 auto compiler_win = window(text("Compilateur"),
234 compiler->Render() | vscroll_indicator | frame);
235 auto flags_win =
236 window(text("Drapeaux"), flags->Render() | vscroll_indicator | frame);
237 auto executable_win = window(text("Exécutable:"), executable_->Render());
238 auto input_win =
239 window(text("Entrée"), hbox({
240 vbox({
241 hbox({
242 text("Ajouter: "),
243 input_add->Render(),
244 }) | size(WIDTH, EQUAL, 20) |
245 size(HEIGHT, EQUAL, 1),
246 filler(),
247 }),
248 separator(),
249 input->Render() | vscroll_indicator | frame |
250 size(HEIGHT, EQUAL, 3) | flex,
251 }));
252 return vbox({
253 hbox({
254 compiler_win,
255 flags_win,
256 vbox({
257 executable_win | size(WIDTH, EQUAL, 20),
258 input_win | size(WIDTH, EQUAL, 60),
259 }),
260 filler(),
261 }) | size(HEIGHT, LESS_THAN, 8),
262 hflow(render_command()) | flex_grow,
263 }) |
264 flex_grow;
265 });
266
267 // ---------------------------------------------------------------------------
268 // Spinner
269 // ---------------------------------------------------------------------------
270 auto spinner_tab_renderer = Renderer([&] {
271 Elements entries;
272 for (int i = 0; i < 22; ++i) {
273 entries.push_back(spinner(i, shift / 5) | bold |
274 size(WIDTH, GREATER_THAN, 2) | border);
275 }
276 return hflow(std::move(entries));
277 });
278
279 // ---------------------------------------------------------------------------
280 // Couleurs
281 // ---------------------------------------------------------------------------
282 auto color_tab_renderer = Renderer([] {
283 auto basic_color_display =
284 vbox({
285 text("Palette de 16 couleurs:"),
286 separator(),
287 hbox({
288 vbox({
289 color(Color::Default, text("Défaut")),
290 color(Color::Black, text("Noir")),
291 color(Color::GrayDark, text("GrisFoncé")),
292 color(Color::GrayLight, text("GrisClair")),
293 color(Color::White, text("Blanc")),
294 color(Color::Blue, text("Bleu")),
295 color(Color::BlueLight, text("BleuClair")),
296 color(Color::Cyan, text("Cyan")),
297 color(Color::CyanLight, text("CyanClair")),
298 color(Color::Green, text("Vert")),
299 color(Color::GreenLight, text("VertClair")),
300 color(Color::Magenta, text("Magenta")),
301 color(Color::MagentaLight, text("MagentaClair")),
302 color(Color::Red, text("Rouge")),
303 color(Color::RedLight, text("RougeClair")),
304 color(Color::Yellow, text("Jaune")),
305 color(Color::YellowLight, text("JauneClair")),
306 }),
307 vbox({
308 bgcolor(Color::Default, text("Défaut")),
309 bgcolor(Color::Black, text("Noir")),
310 bgcolor(Color::GrayDark, text("GrisFoncé")),
311 bgcolor(Color::GrayLight, text("GrisClair")),
312 bgcolor(Color::White, text("Blanc")),
313 bgcolor(Color::Blue, text("Bleu")),
314 bgcolor(Color::BlueLight, text("BleuClair")),
315 bgcolor(Color::Cyan, text("Cyan")),
316 bgcolor(Color::CyanLight, text("CyanClair")),
317 bgcolor(Color::Green, text("Vert")),
318 bgcolor(Color::GreenLight, text("VertClair")),
319 bgcolor(Color::Magenta, text("Magenta")),
320 bgcolor(Color::MagentaLight, text("MagentaClair")),
321 bgcolor(Color::Red, text("Rouge")),
322 bgcolor(Color::RedLight, text("RougeClair")),
323 bgcolor(Color::Yellow, text("Jaune")),
324 bgcolor(Color::YellowLight, text("JauneClair")),
325 }),
326 }),
327 }) |
328 border;
329
330 auto palette_256_color_display = text("Palette de 256 couleurs:");
331 {
332 std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
333 Elements columns;
334 for (auto& column : info_columns) {
335 Elements column_elements;
336 for (auto& it : column) {
337 column_elements.push_back(
338 text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
339 }
340 columns.push_back(hbox(std::move(column_elements)));
341 }
342 palette_256_color_display = vbox({
343 palette_256_color_display,
344 separator(),
345 vbox(columns),
346 }) |
347 border;
348 }
349
350 // Affichage des couleurs réelles.
351 auto true_color_display = text("TrueColors: 24bits:");
352 {
353 int saturation = 255;
354 Elements array;
355 for (int value = 0; value < 255; value += 16) {
356 Elements line;
357 for (int hue = 0; hue < 255; hue += 6) {
358 line.push_back(text("▀") //
359 | color(Color::HSV(hue, saturation, value)) //
360 | bgcolor(Color::HSV(hue, saturation, value + 8)));
361 }
362 array.push_back(hbox(std::move(line)));
363 }
364 true_color_display = vbox({
365 true_color_display,
366 separator(),
367 vbox(std::move(array)),
368 }) |
369 border;
370 }
371
372 return flexbox(
373 {
374 basic_color_display,
375 palette_256_color_display,
376 true_color_display,
377 },
378 FlexboxConfig().SetGap(1, 1));
379 });
380
381 // ---------------------------------------------------------------------------
382 // Jauges
383 // ---------------------------------------------------------------------------
384 auto render_gauge = [&shift](int delta) {
385 float progress = (shift + delta) % 500 / 500.f;
386 return hbox({
387 text(std::to_string(int(progress * 100)) + "% ") |
388 size(WIDTH, EQUAL, 5),
389 gauge(progress),
390 });
391 };
392
393 auto gauge_component = Renderer([render_gauge] {
394 return vbox({
395 render_gauge(0) | color(Color::Black),
396 render_gauge(100) | color(Color::GrayDark),
397 render_gauge(50) | color(Color::GrayLight),
398 render_gauge(6894) | color(Color::White),
399 separator(),
400 render_gauge(6841) | color(Color::Blue),
401 render_gauge(9813) | color(Color::BlueLight),
402 render_gauge(98765) | color(Color::Cyan),
403 render_gauge(98) | color(Color::CyanLight),
404 render_gauge(9846) | color(Color::Green),
405 render_gauge(1122) | color(Color::GreenLight),
406 render_gauge(84) | color(Color::Magenta),
407 render_gauge(645) | color(Color::MagentaLight),
408 render_gauge(568) | color(Color::Red),
409 render_gauge(2222) | color(Color::RedLight),
410 render_gauge(220) | color(Color::Yellow),
411 render_gauge(348) | color(Color::YellowLight),
412 });
413 });
414
415 // ---------------------------------------------------------------------------
416 // Paragraphe
417 // ---------------------------------------------------------------------------
418 auto make_box = [](size_t dimx, size_t dimy) {
419 std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
420 return window(text(title) | hcenter | bold,
421 text("contenu") | hcenter | dim) |
422 size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
423 };
424
425 auto paragraph_renderer_left = Renderer([&] {
426 std::string str =
427 "Lorem Ipsum est simplement un faux texte de l'industrie de "
428 "l'impression et de la composition.\nLorem Ipsum a été le texte "
429 "factice standard de l'industrie depuis les années 1500, quand un "
430 "imprimeur inconnu a pris une galère de caractères et l'a brouillée "
431 "pour en faire un livre spécimen.";
432 return vbox({
433 window(text("Aligner à gauche:"), paragraphAlignLeft(str)),
434 window(text("Aligner au centre:"), paragraphAlignCenter(str)),
435 window(text("Aligner à droite:"), paragraphAlignRight(str)),
436 window(text("Justifier:"), paragraphAlignJustify(str)),
437 window(text("Côte à côte"), hbox({
438 paragraph(str),
439 separator(),
440 paragraph(str),
441 })),
442 window(text("Éléments de tailles différentes:"),
443 flexbox({
444 make_box(10, 5),
445 make_box(9, 4),
446 make_box(8, 4),
447 make_box(6, 3),
448 make_box(10, 5),
449 make_box(9, 4),
450 make_box(8, 4),
451 make_box(6, 3),
452 make_box(10, 5),
453 make_box(9, 4),
454 make_box(8, 4),
455 make_box(6, 3),
456 })),
457 }) |
458 vscroll_indicator | yframe | flex;
459 });
460
461 auto paragraph_renderer_right = Renderer([] {
462 return paragraph("<--- Cette barre verticale est redimensionnable avec la souris") |
463 center;
464 });
465
466 int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
467 auto paragraph_renderer_group =
468 ResizableSplitLeft(paragraph_renderer_left, paragraph_renderer_right,
469 &paragraph_renderer_split_position);
470 auto paragraph_renderer_group_renderer =
471 Renderer(paragraph_renderer_group,
472 [&] { return paragraph_renderer_group->Render(); });
473
474 // ---------------------------------------------------------------------------
475 // Onglets
476 // ---------------------------------------------------------------------------
477
478 int tab_index = 0;
479 std::vector<std::string> tab_entries = {
480 "htop", "couleur", "spinner", "jauge", "compilateur", "paragraphe",
481 };
482 auto tab_selection =
483 Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
484 auto tab_content = Container::Tab(
485 {
486 htop,
487 color_tab_renderer,
488 spinner_tab_renderer,
489 gauge_component,
490 compiler_renderer,
491 paragraph_renderer_group_renderer,
492 },
493 &tab_index);
494
495 auto exit_button =
496 Button("Quitter", [&] { screen.Exit(); }, ButtonOption::Animated());
497
498 auto main_container = Container::Vertical({
499 Container::Horizontal({
500 tab_selection,
501 exit_button,
502 }),
503 tab_content,
504 });
505
506 auto main_renderer = Renderer(main_container, [&] {
507 return vbox({
508 text("Démo FTXUI") | bold | hcenter,
509 hbox({
510 tab_selection->Render() | flex,
511 exit_button->Render(),
512 }),
513 tab_content->Render() | flex,
514 });
515 });
516
517 Loop loop(&screen, main_renderer);
518 while (!loop.HasQuitted()) {
519 // Mettre à jour l'état de l'application.
520 shift++;
521
522 // Demander un nouveau cadre à dessiner.
523 screen.RequestAnimationFrame();
524
525 // Exécuter les événements et dessiner le cadre suivant.
526 loop.RunOnce();
527
528 // Dormir pendant une courte durée pour contrôler la fréquence d'images (60 FPS).
529 std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 60));
530 }
531
532 return 0;
533}
std::vector< std::vector< ftxui::ColorInfo > > ColorInfoSorted2D()
auto screen
Element make_box(int x, int y)
static ButtonOption Animated()
Crée une ButtonOption, utilisant des couleurs animées.
Element Render()
Dessine le composant. Construit un ftxui::Element à dessiner sur l'écran ftxui::Screen représentant c...
static ScreenInteractive Fullscreen()
static MenuOption HorizontalAnimated()
Options standard pour un menu horizontal animé. Cela peut être utile pour implémenter une barre d'ong...
Loop est une classe qui gère la boucle d'événements pour un composant.
Definition loop.hpp:56
Component Menu(MenuOption options)
Une liste de texte. L'élément sélectionné est mis en évidence.
Component Radiobox(RadioboxOption options)
Une liste d'éléments, où un seul peut être sélectionné.
Component Button(ButtonOption options)
Dessine un bouton. Exécute une fonction lors d'un clic.
Component Renderer(Component child, std::function< Element()>)
Renvoie un nouveau composant, similaire à |child|, mais utilisant |render| comme événement Component:...
Component Input(InputOption options={})
Une zone de saisie pour éditer du texte.
Component Checkbox(CheckboxOption options)
Dessine un élément à cocher.
Component ResizableSplitLeft(Component main, Component back, int *main_size)
Une séparation horizontale entre deux composants, configurable à l'aide de la souris.
Option pour le composant Input.
virtual void Render(Screen &screen)
FlexboxConfig & SetGap(int gap_x, int gap_y)
Définit la direction de flex (flex direction) de la flexbox.
Decorator bgcolor(Color)
Décore en utilisant une couleur d'arrière-plan.
Element window(Element title, Element content, BorderStyle border=ROUNDED)
Dessine une fenêtre avec un titre et une bordure autour de l'élément.
Decorator size(WidthOrHeight, Constraint, int value)
Applique une contrainte sur la taille d'un élément.
Element flex(Element)
Permet à un élément enfant de s'étendre proportionnellement à l'espace restant dans un conteneur.
Definition flex.cpp:123
Element paragraphAlignRight(const std::string &text)
Renvoie un élément affichant le paragraphe sur plusieurs lignes, aligné à droite.
Element spinner(int charset_index, size_t image_index)
Utile pour représenter l'effet du temps et/ou des événements. Cela affiche une "vidéo" en art ASCII.
Element center(Element)
Centre un élément horizontalement et verticalement.
Element paragraphAlignCenter(const std::string &text)
Renvoie un élément affichant le paragraphe sur plusieurs lignes, aligné au centre.
Element text(std::wstring text)
Affiche un morceau de texte unicode.
Definition text.cpp:160
Element flex_grow(Element)
S'étend si possible.
Definition flex.cpp:141
Element paragraphAlignLeft(const std::string &text)
Renvoie un élément affichant le paragraphe sur plusieurs lignes, aligné à gauche.
Element separator()
Dessine une séparation verticale ou horizontale entre deux autres éléments.
Element filler()
Un élément qui occupera proportionnellement l'espace disponible dans un conteneur.
Definition flex.cpp:98
Element paragraphAlignJustify(const std::string &text)
Renvoie un élément affichant le paragraphe sur plusieurs lignes, aligné en utilisant un alignement ju...
Decorator color(Color)
Décore en utilisant une couleur de premier plan.
Element hcenter(Element)
Centre un élément horizontalement.
Element vbox(Elements)
Un conteneur affichant les éléments verticalement un par un.
Definition vbox.cpp:96
FlexboxConfig est une structure de configuration qui définit les propriétés de mise en page pour un c...
static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value)
Construit une couleur à partir de sa représentation HSV. https://en.wikipedia.org/wiki/HSL_and_HSV.
Color est une classe qui représente une couleur dans l'interface utilisateur du terminal.
Definition color.hpp:21
Dimensions Size()
Obtenir la taille du terminal.
Definition terminal.cpp:92
int main()
L'espace de noms FTXUI ftxui::
Definition animation.hpp:10
Element flexbox(Elements, FlexboxConfig config=FlexboxConfig())
Un conteneur affichant des éléments sur des lignes/colonnes et capable de passer à la colonne/ligne s...
Definition flexbox.cpp:251
Element hflow(Elements)
Un conteneur affichant des éléments en lignes de gauche à droite. Quand il est rempli,...
Definition flexbox.cpp:269
Element hbox(Elements)
Un conteneur affichant les éléments horizontalement un par un.
Definition hbox.cpp:94
std::vector< Element > Elements
Definition elements.hpp:23
Elements paragraph(std::wstring text)
@ LESS_THAN
Definition elements.hpp:161
@ GREATER_THAN
Definition elements.hpp:161
Element gauge(float progress)
Element graph(GraphFunction)
Dessine un graphique en utilisant une GraphFunction.
std::shared_ptr< ComponentBase > Component