FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/dom/separator.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 <array> // for array, array<>::value_type
5#include <memory> // for make_shared, allocator
6#include <string> // for basic_string, string
7#include <utility> // for move
8
9#include "ftxui/dom/elements.hpp" // for Element, BorderStyle, LIGHT, separator, DOUBLE, EMPTY, HEAVY, separatorCharacter, separatorDouble, separatorEmpty, separatorHSelector, separatorHeavy, separatorLight, separatorStyled, separatorVSelector
10#include "ftxui/dom/node.hpp" // for Node
11#include "ftxui/dom/requirement.hpp" // for Requirement
12#include "ftxui/screen/box.hpp" // for Box
13#include "ftxui/screen/color.hpp" // for Color
14#include "ftxui/screen/pixel.hpp" // for Pixel
15#include "ftxui/screen/screen.hpp" // for Pixel, Screen
16
17namespace ftxui {
18
19namespace {
20using Charset = std::array<std::string, 2>; // NOLINT
21using Charsets = std::array<Charset, 6>; // NOLINT
22// NOLINTNEXTLINE
23const Charsets charsets = {
24 Charset{"│", "─"}, // LIGERO
25 Charset{"╏", "╍"}, // DISCONTINUO
26 Charset{"┃", "━"}, // GRUESO
27 Charset{"║", "═"}, // DOBLE
28 Charset{"│", "─"}, // REDONDEADO
29 Charset{" ", " "}, // VACÍO
30};
31
32class Separator : public Node {
33 public:
34 explicit Separator(std::string value) : value_(std::move(value)) {}
35
36 void ComputeRequirement() override {
37 requirement_.min_x = 1;
38 requirement_.min_y = 1;
39 }
40
41 void Render(Screen& screen) override {
42 for (int y = box_.y_min; y <= box_.y_max; ++y) {
43 for (int x = box_.x_min; x <= box_.x_max; ++x) {
44 Pixel& pixel = screen.PixelAt(x, y);
45 pixel.character = value_;
46 pixel.automerge = true;
47 }
48 }
49 }
50
51 std::string value_;
52};
53
54class SeparatorAuto : public Node {
55 public:
56 explicit SeparatorAuto(BorderStyle style) : style_(style) {}
57
58 void ComputeRequirement() override {
59 requirement_.min_x = 1;
60 requirement_.min_y = 1;
61 }
62
63 void Render(Screen& screen) override {
64 const bool is_column = (box_.x_max == box_.x_min);
65 const bool is_line = (box_.y_min == box_.y_max);
66
67 const std::string c =
68 charsets[style_][int(is_line && !is_column)]; // NOLINT
69
70 for (int y = box_.y_min; y <= box_.y_max; ++y) {
71 for (int x = box_.x_min; x <= box_.x_max; ++x) {
72 Pixel& pixel = screen.PixelAt(x, y);
73 pixel.character = c;
74 pixel.automerge = true;
75 }
76 }
77 }
78
80};
81
82class SeparatorWithPixel : public SeparatorAuto {
83 public:
84 explicit SeparatorWithPixel(Pixel pixel)
85 : SeparatorAuto(LIGHT), pixel_(std::move(pixel)) {
86 pixel_.automerge = true;
87 }
88 void Render(Screen& screen) override {
89 for (int y = box_.y_min; y <= box_.y_max; ++y) {
90 for (int x = box_.x_min; x <= box_.x_max; ++x) {
91 screen.PixelAt(x, y) = pixel_;
92 }
93 }
94 }
95
96 private:
97 Pixel pixel_;
98};
99} // namespace
100
101/// @brief Dibuja una separación vertical u horizontal entre otros dos
102/// elementos.
103/// @ingroup dom
104/// @see separator
105/// @see separatorLight
106/// @see separatorDashed
107/// @see separatorDouble
108/// @see separatorHeavy
109/// @see separatorEmpty
110/// @see separatorRounded
111/// @see separatorStyled
112/// @see separatorCharacter
113///
114/// Añade una separación visual entre dos elementos.
115///
116/// ### Ejemplo
117///
118/// ```cpp
119/// // Use 'border' as a function...
120/// Element document = vbox({
121/// text("up"),
122/// separator(),
123/// text("down"),
124/// });
125/// ```
126///
127/// ### Salida
128///
129/// ```bash
130/// up
131/// ────
132/// down
133/// ```
135 return std::make_shared<SeparatorAuto>(LIGHT);
136}
137
138/// @brief Dibuja una separación vertical u horizontal entre otros dos
139/// elementos.
140/// @param style el estilo del separador.
141/// @ingroup dom
142/// @see separator
143/// @see separatorLight
144/// @see separatorDashed
145/// @see separatorDouble
146/// @see separatorHeavy
147/// @see separatorEmpty
148/// @see separatorRounded
149/// @see separatorStyled
150/// @see separatorCharacter
151///
152/// Añade una separación visual entre dos elementos.
153///
154/// ### Ejemplo
155///
156/// ```cpp
157/// // Use 'border' as a function...
158/// Element document = vbox({
159/// text("up"),
160/// separatorStyled(DOUBLE),
161/// text("down"),
162/// });
163/// ```
164///
165/// ### Salida
166///
167/// ```bash
168/// up
169/// ════
170/// down
171/// ```
173 return std::make_shared<SeparatorAuto>(style);
174}
175
176/// @brief Dibuja una separación vertical u horizontal entre otros dos
177/// elementos, usando el estilo LIGERO.
178/// @ingroup dom
179/// @see separator
180/// @see separatorLight
181/// @see separatorDashed
182/// @see separatorDouble
183/// @see separatorHeavy
184/// @see separatorEmpty
185/// @see separatorRounded
186/// @see separatorStyled
187/// @see separatorCharacter
188///
189/// Añade una separación visual entre dos elementos.
190///
191/// ### Ejemplo
192///
193/// ```cpp
194/// // Use 'border' as a function...
195/// Element document = vbox({
196/// text("up"),
197/// separatorLight(),
198/// text("down"),
199/// });
200/// ```
201///
202/// ### Salida
203///
204/// ```bash
205/// up
206/// ────
207/// down
208/// ```
210 return std::make_shared<SeparatorAuto>(LIGHT);
211}
212
213/// @brief Dibuja una separación vertical u horizontal entre otros dos
214/// elementos, usando el estilo DISCONTINUO.
215/// @ingroup dom
216/// @see separator
217/// @see separatorLight
218/// @see separatorDashed
219/// @see separatorDouble
220/// @see separatorHeavy
221/// @see separatorEmpty
222/// @see separatorRounded
223/// @see separatorStyled
224/// @see separatorCharacter
225///
226/// Añade una separación visual entre dos elementos.
227///
228/// ### Ejemplo
229///
230/// ```cpp
231/// // Use 'border' as a function...
232/// Element document = vbox({
233/// text("up"),
234/// separatorLight(),
235/// text("down"),
236/// });
237/// ```
238///
239/// ### Salida
240///
241/// ```bash
242/// up
243/// ╍╍╍╍
244/// down
245/// ```
247 return std::make_shared<SeparatorAuto>(DASHED);
248}
249
250/// @brief Dibuja una separación vertical u horizontal entre otros dos
251/// elementos, usando el estilo GRUESO.
252/// @ingroup dom
253/// @see separator
254/// @see separatorLight
255/// @see separatorDashed
256/// @see separatorDouble
257/// @see separatorHeavy
258/// @see separatorEmpty
259/// @see separatorRounded
260/// @see separatorStyled
261/// @see separatorCharacter
262///
263/// Añade una separación visual entre dos elementos.
264///
265/// ### Ejemplo
266///
267/// ```cpp
268/// // Use 'border' as a function...
269/// Element document = vbox({
270/// text("up"),
271/// separatorHeavy(),
272/// text("down"),
273/// });
274/// ```
275///
276/// ### Salida
277///
278/// ```bash
279/// up
280/// ━━━━
281/// down
282/// ```
284 return std::make_shared<SeparatorAuto>(HEAVY);
285}
286
287/// @brief Dibuja una separación vertical u horizontal entre otros dos
288/// elementos, usando el estilo DOBLE.
289/// @ingroup dom
290/// @see separator
291/// @see separatorLight
292/// @see separatorDashed
293/// @see separatorDouble
294/// @see separatorHeavy
295/// @see separatorEmpty
296/// @see separatorRounded
297/// @see separatorStyled
298/// @see separatorCharacter
299///
300/// Añade una separación visual entre dos elementos.
301///
302/// ### Ejemplo
303///
304/// ```cpp
305/// // Use 'border' as a function...
306/// Element document = vbox({
307/// text("up"),
308/// separatorDouble(),
309/// text("down"),
310/// });
311/// ```
312///
313/// ### Salida
314///
315/// ```bash
316/// up
317/// ════
318/// down
319/// ```
321 return std::make_shared<SeparatorAuto>(DOUBLE);
322}
323
324/// @brief Dibuja una separación vertical u horizontal entre otros dos
325/// elementos, usando el estilo VACÍO.
326/// @ingroup dom
327/// @see separator
328/// @see separatorLight
329/// @see separatorDashed
330/// @see separatorDouble
331/// @see separatorHeavy
332/// @see separatorEmpty
333/// @see separatorRounded
334/// @see separatorStyled
335/// @see separatorCharacter
336///
337/// Añade una separación visual entre dos elementos.
338///
339/// ### Ejemplo
340///
341/// ```cpp
342/// // Use 'border' as a function...
343/// Element document = vbox({
344/// text("up"),
345/// separator(),
346/// text("down"),
347/// });
348/// ```
349///
350/// ### Salida
351///
352/// ```bash
353/// up
354///
355/// down
356/// ```
358 return std::make_shared<SeparatorAuto>(EMPTY);
359}
360
361/// @brief Dibuja una separación vertical u horizontal entre otros dos
362/// elementos.
363/// @param value el carácter para rellenar el área del separador.
364/// @ingroup dom
365/// @see separator
366/// @see separatorLight
367/// @see separatorDashed
368/// @see separatorDouble
369/// @see separatorHeavy
370/// @see separatorEmpty
371/// @see separatorRounded
372/// @see separatorStyled
373/// @see separatorCharacter
374///
375/// Añade una separación visual entre dos elementos.
376///
377/// ### Ejemplo
378///
379/// ```cpp
380/// // Use 'border' as a function...
381/// Element document = vbox({
382/// text("up"),
383/// separator(),
384/// text("down"),
385/// });
386/// ```
387///
388/// ### Salida
389///
390/// ```bash
391/// up
392/// ────
393/// down
394/// ```
395Element separatorCharacter(std::string value) {
396 return std::make_shared<Separator>(std::move(value));
397}
398
399/// @brief Dibuja un separador entre dos elementos, rellenado con un píxel dado.
400/// @ingroup dom
401/// @see separator
402/// @see separatorLight
403/// @see separatorDashed
404/// @see separatorHeavy
405/// @see separatorDouble
406/// @see separatorStyled
407///
408/// ### Ejemplo
409///
410/// ```cpp
411/// Pixel empty;
412/// Element document = vbox({
413/// text("Up"),
414/// separator(empty),
415/// text("Down"),
416/// })
417/// ```
418///
419/// ### Salida
420///
421/// ```bash
422/// Up
423///
424/// Down
425/// ```
427 return std::make_shared<SeparatorWithPixel>(std::move(pixel));
428}
429
430/// @brief Dibuja una barra horizontal, con el área entre izquierda/derecha coloreada
431/// de forma diferente.
432/// @param left el límite izquierdo del área activa.
433/// @param right el límite derecho del área activa.
434/// @param selected_color el color del área seleccionada.
435/// @param unselected_color el color del área no seleccionada.
436///
437/// ### Ejemplo
438///
439/// ```cpp
440/// Element document = separatorHSelector(2,5, Color::White, Color::Blue);
441/// ```
443 float right,
444 Color unselected_color,
445 Color selected_color) {
446 class Impl : public Node {
447 public:
448 Impl(float left, float right, Color selected_color, Color unselected_color)
449 : left_(left),
450 right_(right),
451 unselected_color_(unselected_color),
452 selected_color_(selected_color) {}
453 void ComputeRequirement() override {
454 requirement_.min_x = 1;
455 requirement_.min_y = 1;
456 }
457
458 void Render(Screen& screen) override {
459 if (box_.y_max < box_.y_min) {
460 return;
461 }
462
463 // This are the two location with an empty demi-cell.
464 int demi_cell_left = int(left_ * 2.F - 1.F); // NOLINT
465 int demi_cell_right = int(right_ * 2.F + 2.F); // NOLINT
466
467 const int y = box_.y_min;
468 for (int x = box_.x_min; x <= box_.x_max; ++x) {
469 Pixel& pixel = screen.PixelAt(x, y);
470
471 const int a = (x - box_.x_min) * 2;
472 const int b = a + 1;
473 const bool a_empty = demi_cell_left == a || demi_cell_right == a;
474 const bool b_empty = demi_cell_left == b || demi_cell_right == b;
475
476 if (!a_empty && !b_empty) {
477 pixel.character = "─";
478 pixel.automerge = true;
479 } else {
480 pixel.character = a_empty ? "╶" : "╴"; // NOLINT
481 pixel.automerge = false;
482 }
483
484 if (demi_cell_left <= a && b <= demi_cell_right) {
485 pixel.foreground_color = selected_color_;
486 } else {
487 pixel.foreground_color = unselected_color_;
488 }
489 }
490 }
491
492 float left_;
493 float right_;
494 Color unselected_color_;
495 Color selected_color_;
496 };
497 return std::make_shared<Impl>(left, right, unselected_color, selected_color);
498}
499
500/// @brief Dibuja una barra vertical, con el área entre arriba/abajo coloreada
501/// de forma diferente.
502/// @param up el límite superior del área activa.
503/// @param down el límite inferior del área activa.
504/// @param selected_color el color del área seleccionada.
505/// @param unselected_color el color del área no seleccionada.
506///
507/// ### Ejemplo
508///
509/// ```cpp
510/// Element document = separatorHSelector(2,5, Color::White, Color::Blue);
511/// ```
513 float down,
514 Color unselected_color,
515 Color selected_color) {
516 class Impl : public Node {
517 public:
518 Impl(float up, float down, Color unselected_color, Color selected_color)
519 : up_(up),
520 down_(down),
521 unselected_color_(unselected_color),
522 selected_color_(selected_color) {}
523 void ComputeRequirement() override {
524 requirement_.min_x = 1;
525 requirement_.min_y = 1;
526 }
527
528 void Render(Screen& screen) override {
529 if (box_.x_max < box_.x_min) {
530 return;
531 }
532
533 // This are the two location with an empty demi-cell.
534 const int demi_cell_up = int(up_ * 2 - 1);
535 const int demi_cell_down = int(down_ * 2 + 2);
536
537 const int x = box_.x_min;
538 for (int y = box_.y_min; y <= box_.y_max; ++y) {
539 Pixel& pixel = screen.PixelAt(x, y);
540
541 const int a = (y - box_.y_min) * 2;
542 const int b = a + 1;
543 const bool a_empty = demi_cell_up == a || demi_cell_down == a;
544 const bool b_empty = demi_cell_up == b || demi_cell_down == b;
545
546 if (!a_empty && !b_empty) {
547 pixel.character = "│";
548 pixel.automerge = true;
549 } else {
550 pixel.character = a_empty ? "╷" : "╵"; // NOLINT
551 pixel.automerge = false;
552 }
553
554 if (demi_cell_up <= a && b <= demi_cell_down) {
555 pixel.foreground_color = selected_color_;
556 } else {
557 pixel.foreground_color = unselected_color_;
558 }
559 }
560 }
561
562 float up_;
563 float down_;
564 Color unselected_color_;
565 Color selected_color_;
566 };
567 return std::make_shared<Impl>(up, down, unselected_color, selected_color);
568}
569
570} // namespace ftxui
auto screen
Node es la clase base para todos los elementos en el árbol DOM.
Definition node.hpp:37
Element separatorStyled(BorderStyle)
Dibuja una separación vertical u horizontal entre otros dos elementos.
Element separatorEmpty()
Dibuja una separación vertical u horizontal entre otros dos elementos, usando el estilo VACÍO.
Element separatorLight()
Dibuja una separación vertical u horizontal entre otros dos elementos, usando el estilo LIGERO.
Element separatorDashed()
Dibuja una separación vertical u horizontal entre otros dos elementos, usando el estilo DISCONTINUO.
Element separatorCharacter(std::string)
Dibuja una separación vertical u horizontal entre otros dos elementos.
Element separator()
Dibuja una separación vertical u horizontal entre otros dos elementos.
void Render(Screen &screen, const Element &element)
Muestra un elemento en un ftxui::Screen.
Definition node.cpp:84
Element separatorDouble()
Dibuja una separación vertical u horizontal entre otros dos elementos, usando el estilo DOBLE.
Element separatorHeavy()
Dibuja una separación vertical u horizontal entre otros dos elementos, usando el estilo GRUESO.
BorderStyle
BorderStyle es una enumeración que representa los diferentes estilos de bordes que se pueden aplicar ...
Definition elements.hpp:35
@ EMPTY
Definition elements.hpp:41
@ DOUBLE
Definition elements.hpp:39
@ HEAVY
Definition elements.hpp:38
@ DASHED
Definition elements.hpp:37
@ LIGHT
Definition elements.hpp:36
Color foreground_color
Definition pixel.hpp:49
std::string character
Definition pixel.hpp:45
bool automerge
Definition pixel.hpp:36
Color es una clase que representa un color en la interfaz de usuario de la terminal.
Definition color.hpp:21
Una cuadrícula rectangular de píxeles.
Definition screen.hpp:26
Un carácter Unicode y su estilo asociado.
Definition pixel.hpp:15
El espacio de nombres ftxui:: de FTXUI.
Definition animation.hpp:10
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
Dibuja una barra vertical, con el área entre arriba/abajo coloreada de forma diferente.
std::shared_ptr< Node > Element
Definition elements.hpp:22
Element separatorHSelector(float left, float right, Color unselected_color, Color selected_color)
Dibuja una barra horizontal, con el área entre izquierda/derecha coloreada de forma diferente.
std::uint8_t left
Definition screen.cpp:130
std::uint8_t down
Definition screen.cpp:133
std::uint8_t right
Definition screen.cpp:132
std::function< void(Pixel &)> style_
std::string value_