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{"│", "─"}, // LIGHT
27 SeparatorCharset{"╏", "╍"}, // DASHED
28 SeparatorCharset{"┃", "━"}, // HEAVY
29 SeparatorCharset{"║", "═"}, // DOUBLE
30 SeparatorCharset{"│", "─"}, // ROUNDED
31 SeparatorCharset{" ", " "}, // EMPTY
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 Dessine une séparation verticale ou horizontale entre deux autres
104/// éléments.
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/// Ajoute une séparation visuelle entre deux éléments.
117///
118/// ### Example
119///
120/// ```cpp
121/// // Utilisation de 'border' comme fonction...
122/// Element document = vbox({
123/// text("up"),
124/// separator(),
125/// text("down"),
126/// });
127/// ```
128///
129/// ### Output
130///
131/// ```bash
132/// up
133/// ────
134/// down
135/// ```
137 return std::make_shared<SeparatorAuto>(LIGHT);
138}
139
140/// @brief Dessine une séparation verticale ou horizontale entre deux autres
141/// éléments.
142/// @param style le style du séparateur.
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/// Ajoute une séparation visuelle entre deux éléments.
155///
156/// ### Exemple
157///
158/// ```cpp
159/// // Utilisation de 'border' comme fonction...
160/// Element document = vbox({
161/// text("up"),
162/// separatorStyled(DOUBLE),
163/// text("down"),
164/// });
165/// ```
166///
167/// ### Output
168///
169/// ```bash
170/// up
171/// ════
172/// down
173/// ```
175 return std::make_shared<SeparatorAuto>(style);
176}
177
178/// @brief Dessine une séparation verticale ou horizontale entre deux autres
179/// éléments, en utilisant le style LIGHT.
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/// Ajoute une séparation visuelle entre deux éléments.
192///
193/// ### Exemple
194///
195/// ```cpp
196/// // Utilisation de 'border' comme fonction...
197/// Element document = vbox({
198/// text("up"),
199/// separatorLight(),
200/// text("down"),
201/// });
202/// ```
203///
204/// ### Output
205///
206/// ```bash
207/// up
208/// ────
209/// down
210/// ```
212 return std::make_shared<SeparatorAuto>(LIGHT);
213}
214
215/// @brief Dessine une séparation verticale ou horizontale entre deux autres
216/// éléments, en utilisant le style DASHED.
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/// Ajoute une séparation visuelle entre deux éléments.
229///
230/// ### Exemple
231///
232/// ```cpp
233/// // Utilisation de 'border' comme fonction...
234/// Element document = vbox({
235/// text("up"),
236/// separatorLight(),
237/// text("down"),
238/// });
239/// ```
240///
241/// ### Output
242///
243/// ```bash
244/// up
245/// ╍╍╍╍
246/// down
247/// ```
249 return std::make_shared<SeparatorAuto>(DASHED);
250}
251
252/// @brief Dessine une séparation verticale ou horizontale entre deux autres
253/// éléments, en utilisant le style HEAVY.
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/// Ajoute une séparation visuelle entre deux éléments.
266///
267/// ### Exemple
268///
269/// ```cpp
270/// // Utilisation de 'border' comme fonction...
271/// Element document = vbox({
272/// text("up"),
273/// separatorHeavy(),
274/// text("down"),
275/// });
276/// ```
277///
278/// ### Output
279///
280/// ```bash
281/// up
282/// ━━━━
283/// down
284/// ```
286 return std::make_shared<SeparatorAuto>(HEAVY);
287}
288
289/// @brief Dessine une séparation verticale ou horizontale entre deux autres
290/// éléments, en utilisant le style DOUBLE.
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/// Ajoute une séparation visuelle entre deux éléments.
303///
304/// ### Exemple
305///
306/// ```cpp
307/// // Utilisation de 'border' comme fonction...
308/// Element document = vbox({
309/// text("up"),
310/// separatorDouble(),
311/// text("down"),
312/// });
313/// ```
314///
315/// ### Output
316///
317/// ```bash
318/// up
319/// ════
320/// down
321/// ```
323 return std::make_shared<SeparatorAuto>(DOUBLE);
324}
325
326/// @brief Dessine une séparation verticale ou horizontale entre deux autres
327/// éléments, en utilisant le style EMPTY.
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/// Ajoute une séparation visuelle entre deux éléments.
340///
341/// ### Exemple
342///
343/// ```cpp
344/// // Utilisation de 'border' comme fonction...
345/// Element document = vbox({
346/// text("up"),
347/// separator(),
348/// text("down"),
349/// });
350/// ```
351///
352/// ### Output
353///
354/// ```bash
355/// up
356///
357/// down
358/// ```
360 return std::make_shared<SeparatorAuto>(EMPTY);
361}
362
363/// @brief Dessine une séparation verticale ou horizontale entre deux autres
364/// éléments.
365/// @param value le caractère pour remplir la zone du séparateur.
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/// Ajoute une séparation visuelle entre deux éléments.
378///
379/// ### Exemple
380///
381/// ```cpp
382/// // Utilisation de 'border' comme fonction...
383/// Element document = vbox({
384/// text("up"),
385/// separator(),
386/// text("down"),
387/// });
388/// ```
389///
390/// ### Output
391///
392/// ```bash
393/// up
394/// ────
395/// down
396/// ```
398 return std::make_shared<Separator>(std::string(value));
399}
400
401/// @brief Dessine un séparateur entre deux éléments remplis avec un pixel donné.
402/// @ingroup dom
403/// @see separator
404/// @see separatorLight
405/// @see separatorDashed
406/// @see separatorHeavy
407/// @see separatorDouble
408/// @see separatorStyled
409///
410/// ### Exemple
411///
412/// ```cpp
413/// Cell empty;
414/// Element document = vbox({
415/// text("Up"),
416/// separator(empty),
417/// text("Down"),
418/// })
419/// ```
420///
421/// ### Sortie
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 Dessine une barre horizontale, avec la zone entre la gauche et la droite colorée
433/// différemment.
434/// @param left la limite gauche de la zone active.
435/// @param right la limite droite de la zone active.
436/// @param selected_color la couleur de la zone sélectionnée.
437/// @param unselected_color la couleur de la zone non sélectionnée.
438///
439/// ### Exemple
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 // Ce sont les deux emplacements avec une demi-cellule vide.
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 Dessine une barre verticale, avec la zone entre le haut et le bas colorée
503/// différemment.
504/// @param up la limite supérieure de la zone active.
505/// @param down la limite inférieure de la zone active.
506/// @param selected_color la couleur de la zone sélectionnée.
507/// @param unselected_color la couleur de la zone non sélectionnée.
508///
509/// ### Exemple
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 // Ce sont les deux emplacements avec une demi-cellule vide.
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)
Dessine une séparation verticale ou horizontale entre deux autres éléments.
Element separatorEmpty()
Dessine une séparation verticale ou horizontale entre deux autres éléments, en utilisant le style EMP...
Element separatorLight()
Dessine une séparation verticale ou horizontale entre deux autres éléments, en utilisant le style LIG...
BorderStyle
BorderStyle est une énumération qui représente les différents styles de bordures pouvant être appliqu...
Definition elements.hpp:38
Element separatorDashed()
Dessine une séparation verticale ou horizontale entre deux autres éléments, en utilisant le style DAS...
Element separator()
Dessine une séparation verticale ou horizontale entre deux autres éléments.
Element separatorCharacter(std::string_view value)
Dessine une séparation verticale ou horizontale entre deux autres éléments.
Element separatorDouble()
Dessine une séparation verticale ou horizontale entre deux autres éléments, en utilisant le style DOU...
Element separatorHeavy()
Dessine une séparation verticale ou horizontale entre deux autres éléments, en utilisant le style HEA...
@ 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
L'espace de noms FTXUI ftxui::
Definition animation.hpp:11
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
Dessine une barre verticale, avec la zone entre le haut et le bas colorée différemment.
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)
Dessine une barre horizontale, avec la zone entre la gauche et la droite colorée différemment.
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_