FTXUI 7.0.3
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/dom/gauge.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <ftxui/dom/direction.hpp> // for Direction, Direction::Down, Direction::Left, Direction::Right, Direction::Up
5#include <memory> // for allocator, make_shared
6#include <string> // for string
7
8#include "ftxui/dom/elements.hpp" // for Element, gauge, gaugeDirection, gaugeDown, gaugeLeft, gaugeRight, gaugeUp
9#include "ftxui/dom/node.hpp" // for Node
10#include "ftxui/dom/requirement.hpp" // for Requirement
11#include "ftxui/screen/box.hpp" // for Box
12#include "ftxui/screen/screen.hpp" // for Screen, Cell
13
14#include "ftxui/screen/terminal.hpp" // for Quirks, GetQuirks
15
16namespace ftxui {
17
18namespace {
19// NOLINTNEXTLINE
20static const std::string charset_horizontal[11] = {
21 " ", " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█",
22 // Un caractère supplémentaire au cas où le fuzzer parviendrait à avoir :
23 // int(9 * (limit - limit_int) = 9 "█"};
24 "█"};
25
26// NOLINTNEXTLINE
27static const std::string charset_horizontal_microsoft[11] = {
28 " ", " ", " ", " ", "▌", "▌", "▌", "█", "█", "█",
29 // Un caractère supplémentaire au cas où le fuzzer parviendrait à avoir :
30 // int(9 * (limit - limit_int) = 9 "█"};
31 "█"};
32
33// NOLINTNEXTLINE
34static const std::string charset_vertical[10] = {
35 "█",
36 "▇",
37 "▆",
38 "▅",
39 "▄",
40 "▃",
41 "▂",
42 "▁",
43 " ",
44 // Un caractère supplémentaire au cas où le fuzzer parviendrait à avoir :
45 // int(8 * (limit - limit_int) = 8 " ",
46 " ",
47};
48
49class Gauge : public Node {
50 public:
51 Gauge(float progress, Direction direction, std::vector<std::string> charset = {})
52 : progress_(progress),
53 direction_(direction),
54 charset_(std::move(charset)) {
55 // Ceci gère NAN correctement :
56 if (!(progress_ > 0.F)) {
57 progress_ = 0.F;
58 }
59 if (!(progress_ < 1.F)) {
60 progress_ = 1.F;
61 }
62 }
63
64 void ComputeRequirement() override {
65 switch (direction_) {
67 case Direction::Left:
68 requirement_.flex_grow_x = 1;
69 requirement_.flex_grow_y = 0;
70 requirement_.flex_shrink_x = 1;
71 requirement_.flex_shrink_y = 0;
72 break;
73 case Direction::Up:
74 case Direction::Down:
75 requirement_.flex_grow_x = 0;
76 requirement_.flex_grow_y = 1;
77 requirement_.flex_shrink_x = 0;
78 requirement_.flex_shrink_y = 1;
79 break;
80 }
81 requirement_.min_x = 1;
82 requirement_.min_y = 1;
83 }
84
85 void Render(Screen& screen) override {
86 switch (direction_) {
88 RenderHorizontal(screen, /*invert=*/false);
89 break;
90 case Direction::Up:
91 RenderVertical(screen, /*invert=*/false);
92 break;
93 case Direction::Left:
94 RenderHorizontal(screen, /*invert=*/true);
95 break;
96 case Direction::Down:
97 RenderVertical(screen, /*invert=*/true);
98 break;
99 }
100 }
101
102 void RenderHorizontal(Screen& screen, bool invert) {
103 if (box_.y_min > box_.y_max) {
104 return;
105 }
106
107 // `full` est l'index du glyphe "plein" dans `charset` ; la cellule
108 // limite choisit le glyphe d'index int(full * fractional_fill).
109 const std::string* charset;
110 int full;
111 if (charset_.empty()) {
112 charset = Terminal::GetQuirks().BlockCharacters() // NOLINT
113 ? charset_horizontal
114 : charset_horizontal_microsoft;
115 full = 9;
116 } else {
117 charset = charset_.data();
118 full = static_cast<int>(charset_.size()) - 1;
119 }
120
121 // Dessine la barre de progression horizontalement sur toute la hauteur allouée :
122 const float progress = invert ? 1.F - progress_ : progress_;
123 const auto limit =
124 float(box_.x_min) + progress * float(box_.x_max - box_.x_min + 1);
125 const int limit_int = static_cast<int>(limit);
126
127 for (int y = box_.y_min; y <= box_.y_max; y++) {
128 int x = box_.x_min;
129 while (x < limit_int) {
130 screen.at(x++, y) = charset[full];
131 }
132 if (x <= box_.x_max) {
133 screen.at(x++, y) = charset[int(full * (limit - limit_int))];
134 }
135 while (x <= box_.x_max) {
136 screen.at(x++, y) = charset[0];
137 }
138 }
139
140 if (invert) {
141 Invert(screen);
142 }
143 }
144
145 void RenderVertical(Screen& screen, bool invert) {
146 if (box_.x_min > box_.x_max) {
147 return;
148 }
149
150 const std::string* charset;
151 int full;
152 if (charset_.empty()) {
153 charset = charset_vertical;
154 full = 8;
155 } else {
156 charset = charset_.data();
157 full = static_cast<int>(charset_.size()) - 1;
158 }
159
160 // Dessine la barre de progression verticalement sur toute la largeur allouée :
161 const float progress = invert ? progress_ : 1.F - progress_;
162 const float limit =
163 float(box_.y_min) + progress * float(box_.y_max - box_.y_min + 1);
164 const int limit_int = static_cast<int>(limit);
165
166 for (int x = box_.x_min; x <= box_.x_max; x++) {
167 int y = box_.y_min;
168 while (y < limit_int) {
169 screen.at(x, y++) = charset[full];
170 }
171 if (y <= box_.y_max) {
172 screen.at(x, y++) = charset[int(full * (limit - limit_int))];
173 }
174 while (y <= box_.y_max) {
175 screen.at(x, y++) = charset[0];
176 }
177 }
178 if (invert) {
179 Invert(screen);
180 }
181 }
182
183 void Invert(Screen& screen) {
184 for (int y = box_.y_min; y <= box_.y_max; y++) {
185 for (int x = box_.x_min; x <= box_.x_max; x++) {
186 screen.CellAt(x, y).inverted ^= true;
187 }
188 }
189 }
190
191 private:
192 float progress_;
193 Direction direction_;
194 std::vector<std::string> charset_;
195};
196
197} // namespace
198
199/// @brief Dessine une barre de progression haute définition progressant dans la
200/// direction spécifiée.
201/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
202/// @param direction Direction of progress bars progression.
203/// @ingroup dom
205 return std::make_shared<Gauge>(progress, direction);
206}
207
208/// @brief Dessine une barre de progression en haute définition progressant de gauche à droite.
209/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
210/// @ingroup dom
211///
212/// ### Exemple
213///
214/// Une jauge. Elle peut être utilisée pour représenter une barre de progression.
215/// ~~~cpp
216/// border(gaugeRight(0.5))
217/// ~~~
218///
219/// #### Sortie
220///
221/// ~~~bash
222/// ┌──────────────────────────────────────────────────────────────────────────┐
223/// │█████████████████████████████████████ │
224/// └──────────────────────────────────────────────────────────────────────────┘
225/// ~~~
226Element gaugeRight(float progress) {
227 return gaugeDirection(progress, Direction::Right);
228}
229
230/// @brief Dessine une barre de progression en haute définition progressant de droite à gauche.
231/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
232/// @ingroup dom
233///
234/// ### Exemple
235///
236/// Une jauge. Elle peut être utilisée pour représenter une barre de progression.
237/// ~~~cpp
238/// border(gaugeLeft(0.5))
239/// ~~~
240///
241/// #### Sortie
242///
243/// ~~~bash
244/// ┌──────────────────────────────────────────────────────────────────────────┐
245/// │ █████████████████████████████████████│
246/// └──────────────────────────────────────────────────────────────────────────┘
247/// ~~~
248Element gaugeLeft(float progress) {
249 return gaugeDirection(progress, Direction::Left);
250}
251
252/// @brief Dessine une barre de progression en haute définition progressant de bas en haut.
253/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
254/// @ingroup dom
255///
256/// ### Exemple
257///
258/// Une jauge. Elle peut être utilisée pour représenter une barre de progression.
259/// ~~~cpp
260/// border(gaugeUp(0.5))
261/// ~~~
262///
263/// #### Sortie
264///
265/// ~~~bash
266/// ┌─┐
267/// │ │
268/// │ │
269/// │ │
270/// │ │
271/// │█│
272/// │█│
273/// │█│
274/// │█│
275/// └─┘
276/// ~~~
277Element gaugeUp(float progress) {
278 return gaugeDirection(progress, Direction::Up);
279}
280
281/// @brief Dessine une barre de progression haute définition progressant de
282/// haut en bas.
283/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
284/// @ingroup dom
285///
286/// ### Exemple
287///
288/// Une jauge. Elle peut être utilisée pour représenter une barre de progression.
289/// ~~~cpp
290/// border(gaugeDown(0.5))
291/// ~~~
292///
293/// #### Output
294///
295/// ~~~bash
296/// ┌─┐
297/// │█│
298/// │█│
299/// │█│
300/// │█│
301/// │ │
302/// │ │
303/// │ │
304/// │ │
305/// └─┘
306/// ~~~
307Element gaugeDown(float progress) {
308 return gaugeDirection(progress, Direction::Down);
309}
310
311/// @brief Dessine une barre de progression haute définition.
312/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
313/// @ingroup dom
314///
315/// ### Exemple
316///
317/// Une jauge. Elle peut être utilisée pour représenter une barre de progression.
318/// ~~~cpp
319/// border(gauge(0.5))
320/// ~~~
321///
322/// #### Output
323///
324/// ~~~bash
325/// ┌──────────────────────────────────────────────────────────────────────────┐
326/// │█████████████████████████████████████ │
327/// └──────────────────────────────────────────────────────────────────────────┘
328/// ~~~
329Element gauge(float progress) {
330 return gaugeRight(progress);
331}
332
333/// @brief Dessine une barre de progression haute définition en utilisant un jeu de caractères personnalisé.
334/// @param progress La proportion de la zone à remplir. Appartient à [0,1].
335/// @param charset Glyphes de "vide" (index 0) à "plein" (dernier index) ; un
336/// jeu de caractères à 2 entrées donne une barre unie non nuancée.
337/// @param direction Direction de progression des barres de progression. Par défaut
338/// Right.
339/// @ingroup dom
340///
341/// ### Exemple
342///
343/// Une jauge rendue avec un jeu de caractères personnalisé au lieu des
344/// caractères de bloc par défaut.
345/// ~~~cpp
346/// border(gaugeCharset(0.5, {".", "#"}))
347/// ~~~
348///
349/// #### Sortie
350///
351/// ~~~bash
352/// ┌──────────────────────────────────────────────────────────────────────────┐
353/// │#####################################.....................................│
354/// └──────────────────────────────────────────────────────────────────────────┘
355/// ~~~
356Element gaugeCharset(float progress,
357 std::vector<std::string> charset,
359 return std::make_shared<Gauge>(progress, direction, std::move(charset));
360}
361
362} // namespace ftxui
Element gaugeDirection(float progress, Direction direction)
Dessine une barre de progression haute définition progressant dans la direction spécifiée.
Element gaugeRight(float progress)
Dessine une barre de progression en haute définition progressant de gauche à droite.
Direction
Direction est une énumération qui représente les quatre directions cardinales.
Definition direction.hpp:15
Element gaugeUp(float progress)
Dessine une barre de progression en haute définition progressant de bas en haut.
Element gaugeCharset(float progress, std::vector< std::string > charset, Direction direction=Direction::Right)
Dessine une barre de progression haute définition en utilisant un jeu de caractères personnalisé.
Element gaugeLeft(float progress)
Dessine une barre de progression en haute définition progressant de droite à gauche.
Element gauge(float progress)
Dessine une barre de progression haute définition.
Element gaugeDown(float progress)
Dessine une barre de progression haute définition progressant de haut en bas.
Quirks GetQuirks()
Récupère les particularités du terminal.
Definition terminal.cpp:355
L'espace de noms FTXUI ftxui::
Definition animation.hpp:11
std::shared_ptr< Node > Element
Definition elements.hpp:25
Direction direction
Definition elements.hpp:83
int y
Definition elements.hpp:134
void Render(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:105
const Charset & charset_