FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
node.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 <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 Calcula cuánto espacio necesita un elemento.
21 if (children_.empty()) {
22 return;
23 }
24 for (auto& child : children_) {
25 child->ComputeRequirement();
26 }
27
28 // Por defecto, el requisito es el del primer hijo.
29 requirement_ = children_[0]->requirement();
30
31 // Propagar el requisito de enfoque.
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 Asigna una posición y una dimensión a un elemento para dibujarlo.
41void Node::SetBox(Box box) {
42 box_ = box;
43}
44
45/// @brief Calcula la selección de un elemento.
46void Node::Select(Selection& selection) {
47 // Si el cuadro de este Nodo no se interseca con la selección, entonces no hay selección.
48 if (Box::Intersection(selection.GetBox(), box_).IsEmpty()) {
49 return;
50 }
51
52 // Por defecto, diferimos la selección a los hijos.
53 for (auto& child : children_) {
54 child->Select(selection);
55 }
56}
57
58/// @brief Muestra un elemento en un ftxui::Screen.
60 for (auto& child : children_) {
61 child->Render(screen);
62 }
63}
64
65void Node::Check(Status* status) {
66 for (auto& child : children_) {
67 child->Check(status);
68 }
69 status->need_iteration |= (status->iteration == 0);
70}
71
72std::string Node::GetSelectedContent(Selection& selection) {
73 std::string content;
74
75 for (auto& child : children_) {
76 content += child->GetSelectedContent(selection);
77 }
78
79 return content;
80}
81
82/// @brief Muestra un elemento en un ftxui::Screen.
83/// @ingroup dom
84void Render(Screen& screen, const Element& element) {
85 Selection selection;
86 Render(screen, element.get(), selection);
87}
88
89/// @brief Muestra un elemento en un ftxui::Screen.
90/// @ingroup dom
91void Render(Screen& screen, Node* node) {
92 Selection selection;
93 Render(screen, node, selection);
94}
95
96void Render(Screen& screen, Node* node, Selection& selection) {
97 Box box;
98 box.x_min = 0;
99 box.y_min = 0;
100 box.x_max = screen.dimx() - 1;
101 box.y_max = screen.dimy() - 1;
102
103 Node::Status status;
104 node->Check(&status);
105 const int max_iterations = 20;
106 while (status.need_iteration && status.iteration < max_iterations) {
107 // Paso 1: Encontrar qué dimensión quiere tener este elemento.
108 node->ComputeRequirement();
109
110 // Paso 2: Asignar una dimensión al elemento.
111 node->SetBox(box);
112
113 // Comprobar si el elemento necesita otra iteración del algoritmo de diseño.
114 status.need_iteration = false;
115 status.iteration++;
116 node->Check(&status);
117 }
118
119 // Paso 3: Selección
120 if (!selection.IsEmpty()) {
121 node->Select(selection);
122 }
123
124 if (node->requirement().focused.enabled
125#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
126 // Al colocar el cursor en la posición correcta, las personas que usan caracteres CJK (chino,
127 // japonés, coreano, ...) pueden ver su [editor de métodos de entrada]
128 // mostrado en la ubicación correcta. Ver [problema].
129 //
130 // [editor de métodos de entrada]:
131 // https://en.wikipedia.org/wiki/Input_method
132 //
133 // [problema]:
134 // https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
135 //
136 // Desafortunadamente, la terminal de Microsoft no maneja correctamente la ocultación del
137 // cursor. En su lugar, el carácter debajo del cursor se oculta, lo cual es un
138 // gran problema. Como resultado, no podemos habilitar la configuración del cursor en la
139 // ubicación correcta. Se mostrará en la esquina inferior derecha.
140 // Ver:
141 // https://github.com/microsoft/terminal/issues/1203
142 // https://github.com/microsoft/terminal/issues/3093
143 &&
145#endif
146 ) {
147 screen.SetCursor(Screen::Cursor{
151 });
152 } else {
153 screen.SetCursor(Screen::Cursor{
154 screen.dimx() - 1,
155 screen.dimy() - 1,
157 });
158 }
159
160 // Paso 4: Dibujar el elemento.
161 screen.stencil = box;
162 node->Render(screen);
163
164 // Paso 5: Aplicar sombreadores
165 screen.ApplyShader();
166}
167
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 // Paso 1: Encontrar qué dimensión quiere tener este elemento.
182 node->ComputeRequirement();
183
184 // Paso 2: Asignar una dimensión al elemento.
185 node->SetBox(box);
186
187 // Comprobar si el elemento necesita otra iteración del algoritmo de diseño.
188 status.need_iteration = false;
189 status.iteration++;
190 node->Check(&status);
191 }
192
193 // Paso 3: Selección
194 node->Select(selection);
195
196 // Paso 4: obtener el contenido seleccionado.
197 return node->GetSelectedContent(selection);
198}
199
200} // namespace ftxui
auto screen
const Box & GetBox() const
Obtiene el cuadro de la selección.
virtual void Select(Selection &selection)
Calcula la selección de un elemento.
Definition node.cpp:46
Elements children_
Definition node.hpp:79
virtual std::string GetSelectedContent(Selection &selection)
Definition node.cpp:72
virtual void SetBox(Box box)
Asigna una posición y una dimensión a un elemento para dibujarlo.
Definition node.cpp:41
Requirement requirement_
Definition node.hpp:80
Requirement requirement()
Definition node.hpp:52
virtual void ComputeRequirement()
Calcula cuánto espacio necesita un elemento.
Definition node.cpp:20
virtual void Check(Status *status)
Definition node.cpp:65
virtual ~Node()
virtual void Render(Screen &screen)
Muestra un elemento en un ftxui::Screen.
Definition node.cpp:59
bool IsEmpty() const
Definition selection.hpp:31
Box box_
Definition node.hpp:81
friend void Render(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:96
Node es la clase base para todos los elementos en el árbol DOM.
Definition node.hpp:37
Representa una selección en una interfaz de usuario de terminal.
Definition selection.hpp:22
void Render(Screen &screen, const Element &element)
Muestra un elemento en un ftxui::Screen.
Definition node.cpp:84
int x_max
Definition box.hpp:18
int y_min
Definition box.hpp:19
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:11
int y_max
Definition box.hpp:20
int x_min
Definition box.hpp:17
Una cuadrícula rectangular de píxeles.
Definition screen.hpp:26
Box es una estructura que representa un área rectangular en un espacio 2D.
Definition box.hpp:16
El espacio de nombres ftxui:: de FTXUI.
Definition animation.hpp:10
std::string GetNodeSelectedContent(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:168
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::vector< Element > Elements
Definition elements.hpp:23
Screen::Cursor::Shape cursor_shape