FTXUI  6.0.2
C++ functional terminal UI.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
node.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/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;
17Node::~Node() = default;
18
19/// @brief Compute how much space an elements needs.
20/// @ingroup dom
22 if (children_.empty()) {
23 return;
24 }
25 for (auto& child : children_) {
26 child->ComputeRequirement();
27 }
28
29 // By default, the requirement is the one of the first child.
30 requirement_ = children_[0]->requirement();
31
32 // Propagate the focused requirement.
33 for (size_t i = 1; i < children_.size(); ++i) {
35 children_[i]->requirement().focused.enabled) {
36 requirement_.focused = children_[i]->requirement().focused;
37 }
38 }
39}
40
41/// @brief Assign a position and a dimension to an element for drawing.
42/// @ingroup dom
43void Node::SetBox(Box box) {
44 box_ = box;
45}
46
47/// @brief Compute the selection of an element.
48/// @ingroup dom
50 // If this Node box_ doesn't intersect with the selection, then no selection.
51 if (Box::Intersection(selection.GetBox(), box_).IsEmpty()) {
52 return;
53 }
54
55 // By default we defer the selection to the children.
56 for (auto& child : children_) {
57 child->Select(selection);
58 }
59}
60
61/// @brief Display an element on a ftxui::Screen.
62/// @ingroup dom
64 for (auto& child : children_) {
65 child->Render(screen);
66 }
67}
68
70 for (auto& child : children_) {
71 child->Check(status);
72 }
73 status->need_iteration |= (status->iteration == 0);
74}
75
77 std::string content;
78
79 for (auto& child : children_) {
80 content += child->GetSelectedContent(selection);
81 }
82
83 return content;
84}
85
86/// @brief Display an element on a ftxui::Screen.
87/// @ingroup dom
88void Render(Screen& screen, const Element& element) {
90 Render(screen, element.get(), selection);
91}
92
93/// @brief Display an element on a ftxui::Screen.
94/// @ingroup dom
95void Render(Screen& screen, Node* node) {
97 Render(screen, node, selection);
98}
99
101 Box box;
102 box.x_min = 0;
103 box.y_min = 0;
104 box.x_max = screen.dimx() - 1;
105 box.y_max = screen.dimy() - 1;
106
108 node->Check(&status);
109 const int max_iterations = 20;
110 while (status.need_iteration && status.iteration < max_iterations) {
111 // Step 1: Find what dimension this elements wants to be.
112 node->ComputeRequirement();
113
114 // Step 2: Assign a dimension to the element.
115 node->SetBox(box);
116
117 // Check if the element needs another iteration of the layout algorithm.
118 status.need_iteration = false;
119 status.iteration++;
120 node->Check(&status);
121 }
122
123 // Step 3: Selection
124 if (!selection.IsEmpty()) {
125 node->Select(selection);
126 }
127
128 if (node->requirement().focused.enabled
130 // Setting the cursor to the right position allow folks using CJK (China,
131 // Japanese, Korean, ...) characters to see their [input method editor]
132 // displayed at the right location. See [issue].
133 //
134 // [input method editor]:
135 // https://en.wikipedia.org/wiki/Input_method
136 //
137 // [issue]:
138 // https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
139 //
140 // Unfortunately, Microsoft terminal do not handle properly hiding the
141 // cursor. Instead the character under the cursor is hidden, which is a
142 // big problem. As a result, we can't enable setting cursor to the right
143 // location. It will be displayed at the bottom right corner.
144 // See:
145 // https://github.com/microsoft/terminal/issues/1203
146 // https://github.com/microsoft/terminal/issues/3093
147 &&
149#endif
150 ) {
151 screen.SetCursor(Screen::Cursor{
152 node->requirement().focused.node->box_.x_max,
155 });
156 } else {
157 screen.SetCursor(Screen::Cursor{
158 screen.dimx() - 1,
159 screen.dimy() - 1,
161 });
162 }
163
164 // Step 4: Draw the element.
165 screen.stencil = box;
166 node->Render(screen);
167
168 // Step 5: Apply shaders
169 screen.ApplyShader();
170}
171
173 Node* node,
175 Box box;
176 box.x_min = 0;
177 box.y_min = 0;
178 box.x_max = screen.dimx() - 1;
179 box.y_max = screen.dimy() - 1;
180
182 node->Check(&status);
183 const int max_iterations = 20;
184 while (status.need_iteration && status.iteration < max_iterations) {
185 // Step 1: Find what dimension this elements wants to be.
186 node->ComputeRequirement();
187
188 // Step 2: Assign a dimension to the element.
189 node->SetBox(box);
190
191 // Check if the element needs another iteration of the layout algorithm.
192 status.need_iteration = false;
193 status.iteration++;
194 node->Check(&status);
195 }
196
197 // Step 3: Selection
198 node->Select(selection);
199
200 // Step 4: get the selected content.
201 return node->GetSelectedContent(selection);
202}
203
204} // namespace ftxui
virtual void Select(Selection &selection)
Compute the selection of an element.
Definition node.cpp:49
Elements children_
Definition node.hpp:65
virtual std::string GetSelectedContent(Selection &selection)
Definition node.cpp:76
virtual void SetBox(Box box)
Assign a position and a dimension to an element for drawing.
Definition node.cpp:43
Requirement requirement_
Definition node.hpp:66
Requirement requirement()
Definition node.hpp:38
virtual void ComputeRequirement()
Compute how much space an elements needs.
Definition node.cpp:21
virtual void Check(Status *status)
Definition node.cpp:69
virtual ~Node()
virtual void Render(Screen &screen)
Display an element on a ftxui::Screen.
Definition node.cpp:63
Box box_
Definition node.hpp:67
friend void Render(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:100
A rectangular grid of Pixel.
Definition screen.hpp:27
Represent a selection in the terminal.
Definition selection.hpp:17
std::string GetNodeSelectedContent(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:172
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
std::vector< Element > Elements
Definition elements.hpp:23
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition node.cpp:88
int x_max
Definition box.hpp:11
int y_min
Definition box.hpp:12
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:12
int y_max
Definition box.hpp:13
int x_min
Definition box.hpp:10
Screen::Cursor::Shape cursor_shape