FTXUI 6.1.9
C++ functional terminal UI.
Chargement...
Recherche...
Aucune correspondance
node.cpp
Aller à la documentation de ce fichier.
1// Copyright 2020 Arthur Sonzogni. Tous droits réservés.
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 <ftxui/screen/box.hpp> // for Box
5#include <string>
6#include <utility> // for move
7
8#include <cstddef>
9#include "ftxui/dom/node.hpp"
10#include "ftxui/dom/selection.hpp" // for Selection
11#include "ftxui/screen/screen.hpp" // for Screen
12
13namespace ftxui {
14
15Node::Node() = default;
16Node::Node(Elements children) : children_(std::move(children)) {}
17Node::~Node() = default;
18
19/// @brief Calcule l'espace nécessaire à un élément.
21 if (children_.empty()) {
22 return;
23 }
24 for (auto& child : children_) {
25 child->ComputeRequirement();
26 }
27
28 // Par défaut, l'exigence est celle du premier enfant.
29 requirement_ = children_[0]->requirement();
30
31 // Propage l'exigence de focus.
32 for (size_t i = 1; i < children_.size(); ++i) {
34 children_[i]->requirement().focused.enabled) {
35 requirement_.focused = children_[i]->requirement().focused;
36 }
37 }
38}
39
40/// @brief Assigne une position et une dimension à un élément pour le dessin.
41void Node::SetBox(Box box) {
42 box_ = box;
43}
44
45/// @brief Calcule la sélection d'un élément.
46void Node::Select(Selection& selection) {
47 // Si la boîte de ce nœud n'intersecte pas la sélection, alors pas de sélection.
48 if (Box::Intersection(selection.GetBox(), box_).IsEmpty()) {
49 return;
50 }
51
52 // Par défaut, nous déléguons la sélection aux enfants.
53 for (auto& child : children_) {
54 child->Select(selection);
55 }
56}
57
58/// @brief Affiche un élément sur un ftxui::Screen.
59 for (auto& child : children_) {
60 child->Render(screen);
61 }
62}
63
64void Node::Check(Status* status) {
65 for (auto& child : children_) {
66 child->Check(status);
67 }
68 status->need_iteration |= (status->iteration == 0);
69}
70
71std::string Node::GetSelectedContent(Selection& selection) {
72 std::string content;
73
74 for (auto& child : children_) {
75 content += child->GetSelectedContent(selection);
76 }
77
78 return content;
79}
80
81/// @brief Affiche un élément sur un ftxui::Screen.
82/// @ingroup dom
83void Render(Screen& screen, const Element& element) {
84 Selection selection;
85 Render(screen, element.get(), selection);
86}
87
88/// @brief Affiche un élément sur un ftxui::Screen.
89/// @ingroup dom
90void Render(Screen& screen, Node* node) {
91 Selection selection;
92 Render(screen, node, selection);
93}
94
95void Render(Screen& screen, Node* node, Selection& selection) {
96 Box box;
97 box.x_min = 0;
98 box.y_min = 0;
99 box.x_max = screen.dimx() - 1;
100 box.y_max = screen.dimy() - 1;
101
102 Node::Status status;
103 node->Check(&status);
104 const int max_iterations = 20;
105 while (status.need_iteration && status.iteration < max_iterations) {
106 // Étape 1 : Détermine la dimension souhaitée par cet élément.
107 node->ComputeRequirement();
108
109 // Étape 2 : Assigne une dimension à l'élément.
110 node->SetBox(box);
111
112 // Vérifie si l'élément nécessite une autre itération de l'algorithme de mise en page.
113 status.need_iteration = false;
114 status.iteration++;
115 node->Check(&status);
116 }
117
118 // Étape 3 : Sélection
119 if (!selection.IsEmpty()) {
120 node->Select(selection);
121 }
122
123 if (node->requirement().focused.enabled
124#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
125 // Positionner le curseur au bon endroit permet aux personnes utilisant des
126 // caractères CJK (Chine, Japonais, Coréen, ...) de voir leur [éditeur de
127 // méthode d'entrée] affiché au bon endroit. Voir [problème].
128 //
129 // [éditeur de méthode d'entrée]:
130 // https://fr.wikipedia.org/wiki/M%C3%A9thode_de_saisie
131 //
132 // [problème]:
133 // https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
134 //
135 // Malheureusement, le terminal Microsoft ne gère pas correctement le
136 // masquage du curseur. Au lieu de cela, le caractère sous le curseur est
137 // masqué, ce qui est un gros problème. Par conséquent, nous ne pouvons pas
138 // activer le positionnement du curseur au bon endroit. Il sera affiché
139 // dans le coin inférieur droit.
140 // Voir:
141 // https://github.com/microsoft/terminal/issues/1203
142 // https://github.com/microsoft/terminal/issues/3093
143 &&
144 node->requirement().focused.cursor_shape != Screen::Cursor::Shape::Hidden
145#endif
146 ) {
147 screen.SetCursor(Screen::Cursor{
148 node->requirement().focused.node->box_.x_max,
149 node->requirement().focused.node->box_.y_max,
150 node->requirement().focused.cursor_shape,
151 });
152 } else {
153 screen.SetCursor(Screen::Cursor{
154 screen.dimx() - 1,
155 screen.dimy() - 1,
156 Screen::Cursor::Shape::Hidden,
157 });
158 }
159
160 // Étape 4 : Dessine l'élément.
161 screen.stencil = box;
162 node->Render(screen);
163
164 // Étape 5 : Applique les shaders.
165 screen.ApplyShader();
166}
167
168std::string GetNodeSelectedContent(Screen& screen,
169 Node* node,
170 Selection& selection) {
171 Box box;
172 box.x_min = 0;
173 box.y_min = 0;
174 box.x_max = screen.dimx() - 1;
175 box.y_max = screen.dimy() - 1;
176
177 Node::Status status;
178 node->Check(&status);
179 const int max_iterations = 20;
180 while (status.need_iteration && status.iteration < max_iterations) {
181 // Étape 1 : Détermine la dimension souhaitée par cet élément.
182 node->ComputeRequirement();
183
184 // Étape 2 : Assigne une dimension à l'élément.
185 node->SetBox(box);
186
187 // Vérifie si l'élément nécessite une autre itération de l'algorithme de mise en page.
188 status.need_iteration = false;
189 status.iteration++;
190 node->Check(&status);
191 }
192
193 // Étape 3 : Sélection
194 node->Select(selection);
195
196 // Étape 4 : Récupère le contenu sélectionné.
197 return node->GetSelectedContent(selection);
198}
199
200} // namespace ftxui
auto screen
const Box & GetBox() const
Récupère la boîte de sélection.
virtual void Select(Selection &selection)
Calcule la sélection d'un élément.
Definition node.cpp:46
Elements children_
Definition node.hpp:78
virtual void SetBox(Box box)
Assigne une position et une dimension à un élément pour le dessin.
Definition node.cpp:41
Requirement requirement_
Definition node.hpp:79
virtual void ComputeRequirement()
Calcule l'espace nécessaire à un élément.
Definition node.cpp:20
virtual ~Node()
Box box_
Definition node.hpp:80
Représente une sélection dans une interface utilisateur de terminal.
Definition selection.hpp:22
void Render(Screen &screen, const Element &element)
Affiche un élément sur un ftxui::Screen.
Definition node.cpp:83
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:11
Box est une structure qui représente une zone rectangulaire dans un espace 2D.
Definition box.hpp:16
L'espace de noms FTXUI ftxui::
Definition animation.hpp:10
std::vector< Element > Elements
Definition elements.hpp:23
std::string GetNodeSelectedContent(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:168