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