FTXUI  0.9.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
border.cpp
Go to the documentation of this file.
1#include <algorithm> // for max
2#include <iterator> // for begin, end
3#include <memory> // for allocator, make_shared, __shared_ptr_access
4#include <string> // for basic_string, string
5#include <utility> // for move
6#include <vector> // for vector, __alloc_traits<>::value_type
7
8#include "ftxui/dom/elements.hpp" // for unpack, Element, Decorator, Elements, border, borderWith, window
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 Pixel, Screen
13
14namespace ftxui {
15
16static std::string simple_border_charset[6][6] = {
17 {"┌", "┐", "└", "┘", "─", "│"},
18 {"┏", "┓", "┗", "┛", "━", "┃"},
19 {"╔", "╗", "╚", "╝", "═", "║"},
20 {"╭", "╮", "╰", "╯", "─", "│"},
21};
22
23// For reference, here is the charset for normal border:
24// {"┌", "┐", "└", "┘", "─", "│", "┬", "┴", "┤", "├"};
25// TODO(arthursonzogni): Consider adding options to choose the kind of borders
26// to use.
27
28class Border : public Node {
29 public:
30 Border(Elements children, BorderStyle style)
31 : Node(std::move(children)),
32 charset(std::begin(simple_border_charset[style]),
33 std::end(simple_border_charset[style])) {}
34 Border(Elements children, Pixel pixel)
35 : Node(std::move(children)), charset_pixel(10, pixel) {}
36
37 std::vector<Pixel> charset_pixel;
38 std::vector<std::string> charset;
39
40 void ComputeRequirement() override {
42 requirement_ = children_[0]->requirement();
45 if (children_.size() == 2) {
47 std::max(requirement_.min_x, children_[1]->requirement().min_x + 2);
48 }
53 }
54
55 void SetBox(Box box) override {
56 Node::SetBox(box);
57 if (children_.size() == 2) {
58 Box title_box;
59 title_box.x_min = box.x_min + 1;
60 title_box.x_max = box.x_max - 1;
61 title_box.y_min = box.y_min;
62 title_box.y_max = box.y_min;
63 children_[1]->SetBox(title_box);
64 }
65 box.x_min++;
66 box.x_max--;
67 box.y_min++;
68 box.y_max--;
69 children_[0]->SetBox(box);
70 }
71
72 void Render(Screen& screen) override {
73 // Draw content.
74 children_[0]->Render(screen);
75
76 // Draw the border.
77 if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max)
78 return;
79
80 if (!charset.empty())
81 RenderPixel(screen);
82 else
83 RenderChar(screen);
84 }
85
86 void RenderPixel(Screen& screen) {
87 screen.at(box_.x_min, box_.y_min) = charset[0];
88 screen.at(box_.x_max, box_.y_min) = charset[1];
89 screen.at(box_.x_min, box_.y_max) = charset[2];
90 screen.at(box_.x_max, box_.y_max) = charset[3];
91 for (float x = box_.x_min + 1; x < box_.x_max; ++x) {
92 screen.at(x, box_.y_min) = charset[4];
93 screen.at(x, box_.y_max) = charset[4];
94 }
95 for (float y = box_.y_min + 1; y < box_.y_max; ++y) {
96 screen.at(box_.x_min, y) = charset[5];
97 screen.at(box_.x_max, y) = charset[5];
98 }
99
100 // Draw title.
101 if (children_.size() == 2)
102 children_[1]->Render(screen);
103 }
104
105 void RenderChar(Screen& screen) {
106 screen.PixelAt(box_.x_min, box_.y_min) = charset_pixel[0];
107 screen.PixelAt(box_.x_max, box_.y_min) = charset_pixel[1];
108 screen.PixelAt(box_.x_min, box_.y_max) = charset_pixel[2];
109 screen.PixelAt(box_.x_max, box_.y_max) = charset_pixel[3];
110 for (float x = box_.x_min + 1; x < box_.x_max; ++x) {
111 screen.PixelAt(x, box_.y_min) = charset_pixel[4];
112 screen.PixelAt(x, box_.y_max) = charset_pixel[4];
113 }
114 for (float y = box_.y_min + 1; y < box_.y_max; ++y) {
115 screen.PixelAt(box_.x_min, y) = charset_pixel[5];
116 screen.PixelAt(box_.x_max, y) = charset_pixel[5];
117 }
118 }
119};
120
121/// @brief Draw a border around the element.
122/// @ingroup dom
123/// @see border
124/// @see borderLight
125/// @see borderDouble
126/// @see borderHeavy
127/// @see borderRounded
128///
129/// Add a border around an element
130///
131/// ### Example
132///
133/// ```cpp
134/// // Use 'border' as a function...
135/// Element document = border(text("The element"));
136///
137/// // ...Or as a 'pipe'.
138/// Element document = text("The element") | border;
139/// ```
140///
141/// ### Output
142///
143/// ```bash
144/// ┌───────────┐
145/// │The element│
146/// └───────────┘
147/// ```
149 return std::make_shared<Border>(unpack(std::move(child)), ROUNDED);
150}
151
152/// @brief Same as border but with a constant Pixel around the element.
153/// @ingroup dom
154/// @see border
156 return [pixel](Element child) {
157 return std::make_shared<Border>(unpack(std::move(child)), pixel);
158 };
159}
160
161/// @brief Same as border but with different styles.
162/// @ingroup dom
163/// @see border
165 return [style](Element child) {
166 return std::make_shared<Border>(unpack(std::move(child)), style);
167 };
168}
169
170/// @brief Draw a light border around the element.
171/// @ingroup dom
172/// @see border
173/// @see borderLight
174/// @see borderDouble
175/// @see borderHeavy
176/// @see borderRounded
177/// @see borderStyled
178/// @see borderWith
179///
180/// Add a border around an element
181///
182/// ### Example
183///
184/// ```cpp
185/// // Use 'borderLight' as a function...
186/// Element document = borderLight(text("The element"));
187///
188/// // ...Or as a 'pipe'.
189/// Element document = text("The element") | borderLight;
190/// ```
191///
192/// ### Output
193///
194/// ```bash
195/// ┌──────────────┐
196/// │The element │
197/// └──────────────┘
198/// ```
200 return std::make_shared<Border>(unpack(std::move(child)), LIGHT);
201}
202
203/// @brief Draw a heavy border around the element.
204/// @ingroup dom
205/// @see border
206/// @see borderLight
207/// @see borderDouble
208/// @see borderHeavy
209/// @see borderRounded
210/// @see borderStyled
211/// @see borderWith
212///
213/// Add a border around an element
214///
215/// ### Example
216///
217/// ```cpp
218/// // Use 'borderHeavy' as a function...
219/// Element document = borderHeavy(text("The element"));
220///
221/// // ...Or as a 'pipe'.
222/// Element document = text("The element") | borderHeavy;
223/// ```
224///
225/// ### Output
226///
227/// ```bash
228/// ┏━━━━━━━━━━━━━━┓
229/// ┃The element ┃
230/// ┗━━━━━━━━━━━━━━┛
231/// ```
233 return std::make_shared<Border>(unpack(std::move(child)), HEAVY);
234}
235
236/// @brief Draw a double border around the element.
237/// @ingroup dom
238/// @see border
239/// @see borderLight
240/// @see borderDouble
241/// @see borderHeavy
242/// @see borderRounded
243/// @see borderStyled
244/// @see borderWith
245///
246/// Add a border around an element
247///
248/// ### Example
249///
250/// ```cpp
251/// // Use 'borderDouble' as a function...
252/// Element document = borderDouble(text("The element"));
253///
254/// // ...Or as a 'pipe'.
255/// Element document = text("The element") | borderDouble;
256/// ```
257///
258/// ### Output
259///
260/// ```bash
261/// ╔══════════════╗
262/// ║The element ║
263/// ╚══════════════╝
264/// ```
266 return std::make_shared<Border>(unpack(std::move(child)), DOUBLE);
267}
268
269/// @brief Draw a rounded border around the element.
270/// @ingroup dom
271/// @see border
272/// @see borderLight
273/// @see borderDouble
274/// @see borderHeavy
275/// @see borderRounded
276/// @see borderStyled
277/// @see borderWith
278///
279/// Add a border around an element
280///
281/// ### Example
282///
283/// ```cpp
284/// // Use 'borderRounded' as a function...
285/// Element document = borderRounded(text("The element"));
286///
287/// // ...Or as a 'pipe'.
288/// Element document = text("The element") | borderRounded;
289/// ```
290///
291/// ### Output
292///
293/// ```bash
294/// ╭──────────────╮
295/// │The element │
296/// ╰──────────────╯
297/// ```
299 return std::make_shared<Border>(unpack(std::move(child)), ROUNDED);
300}
301
302/// @brief Draw window with a title and a border around the element.
303/// @param title The title of the window.
304/// @param content The element to be wrapped.
305/// @ingroup dom
306/// @see border
307///
308/// ### Example
309///
310/// ```cpp
311/// Element document = window(text("Title"),
312/// text("content")
313/// );
314/// ```
315///
316/// ### Output
317///
318/// ```bash
319/// ┌Title──┐
320/// │content│
321/// └───────┘
322/// ```
323Element window(Element title, Element content) {
324 return std::make_shared<Border>(unpack(std::move(content), std::move(title)),
325 ROUNDED);
326}
327} // namespace ftxui
328
329// Copyright 2020 Arthur Sonzogni. All rights reserved.
330// Use of this source code is governed by the MIT license that can be found in
331// the LICENSE file.
Elements children_
Definition node.hpp:39
virtual void SetBox(Box box)
Assign a position and a dimension to an element for drawing.
Definition node.cpp:21
Requirement requirement_
Definition node.hpp:40
virtual void ComputeRequirement()
Compute how much space an elements needs.
Definition node.cpp:14
Box box_
Definition node.hpp:41
Element borderDouble(Element)
Draw a double border around the element.
Definition border.cpp:265
std::function< Element(Element)> Decorator
Definition elements.hpp:17
std::shared_ptr< Node > Element
Definition elements.hpp:15
Decorator borderWith(Pixel)
Same as border but with a constant Pixel around the element.
Definition border.cpp:155
Element borderRounded(Element)
Draw a rounded border around the element.
Definition border.cpp:298
Element window(Element title, Element content)
Draw window with a title and a border around the element.
Definition border.cpp:323
std::vector< Element > Elements
Definition elements.hpp:16
Element borderHeavy(Element)
Draw a heavy border around the element.
Definition border.cpp:232
Element borderLight(Element)
Draw a light border around the element.
Definition border.cpp:199
Decorator borderStyled(BorderStyle)
Same as border but with different styles.
Definition border.cpp:164
Element border(Element)
Draw a border around the element.
Definition border.cpp:148
BorderStyle
Definition elements.hpp:20
@ DOUBLE
Definition elements.hpp:20
@ HEAVY
Definition elements.hpp:20
@ ROUNDED
Definition elements.hpp:20
@ LIGHT
Definition elements.hpp:20
int x_max
Definition box.hpp:8
int y_min
Definition box.hpp:9
int y_max
Definition box.hpp:10
int x_min
Definition box.hpp:7
A unicode character and its associated style.
Definition screen.hpp:16