FTXUI
6.1.9
C++ functional terminal UI.
Toggle main menu visibility
Loading...
Searching...
No Matches
util.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 <algorithm>
// for min
5
#include <functional>
// for function
6
#include <memory>
// for __shared_ptr_access, make_unique
7
#include <utility>
// for move
8
9
#include "
ftxui/dom/elements.hpp
"
// for Element, Decorator, Elements, operator|, Fit, emptyElement, nothing, operator|=
10
#include "
ftxui/dom/node.hpp
"
// for Node, Node::Status
11
#include "
ftxui/dom/requirement.hpp
"
// for Requirement
12
#include "
ftxui/screen/box.hpp
"
// for Box
13
#include "
ftxui/screen/screen.hpp
"
// for Full
14
#include "
ftxui/screen/terminal.hpp
"
// for Dimensions
15
16
namespace
ftxui
{
17
18
namespace
{
19
Decorator
compose(
Decorator
a,
Decorator
b) {
20
return
[a = std::move(a), b = std::move(b)](
Element
element) {
21
return
b(a(std::move(element)));
22
};
23
}
24
}
// namespace
25
26
/// @brief A decoration doing absolutely nothing.
27
/// @ingroup dom
28
Element
nothing
(
Element
element) {
29
return
element;
30
}
31
32
/// @brief Compose two decorator into one.
33
/// @ingroup dom
34
///
35
/// ### Example
36
///
37
/// ```cpp
38
/// auto decorator = bold | blink;
39
/// ```
40
Decorator
operator|
(
Decorator
a,
Decorator
b) {
41
return
compose(std::move(a),
//
42
std::move(b));
43
}
44
45
/// @brief From a set of element, apply a decorator to every elements.
46
/// @return the set of decorated element.
47
/// @ingroup dom
48
Elements
operator|
(
Elements
elements,
Decorator
decorator) {
// NOLINT
49
Elements
output;
50
output.reserve(elements.size());
51
for
(
auto
& it : elements) {
52
output.push_back(std::move(it) | decorator);
53
}
54
return
output;
55
}
56
57
/// @brief From an element, apply a decorator.
58
/// @return the decorated element.
59
/// @ingroup dom
60
///
61
/// ### Example
62
///
63
/// Both of these are equivalent:
64
/// ```cpp
65
/// bold(text("Hello"));
66
/// ```
67
/// ```cpp
68
/// text("Hello") | bold;
69
/// ```
70
Element
operator|
(
Element
element,
Decorator
decorator) {
// NOLINT
71
return
decorator(std::move(element));
72
}
73
74
/// @brief Apply a decorator to an element.
75
/// @return the decorated element.
76
/// @ingroup dom
77
///
78
/// ### Example
79
///
80
/// Both of these are equivalent:
81
/// ```cpp
82
/// auto element = text("Hello");
83
/// element |= bold;
84
/// ```
85
Element
&
operator|=
(
Element
& e,
Decorator
d) {
86
e = e | std::move(d);
87
return
e;
88
}
89
90
/// The minimal dimension that will fit the given element.
91
/// @see Fixed
92
/// @see Full
93
Dimensions
Dimension::Fit
(
Element
& e,
bool
extend_beyond_screen) {
94
const
Dimensions
fullsize =
Dimension::Full
();
95
Box
box;
96
box.
x_min
= 0;
97
box.
y_min
= 0;
98
box.
x_max
= fullsize.
dimx
;
99
box.
y_max
= fullsize.
dimy
;
100
101
Node::Status
status;
102
e->Check(&status);
103
const
int
max_iteration = 20;
104
while
(status.
need_iteration
&& status.
iteration
< max_iteration) {
105
e->ComputeRequirement();
106
107
// Don't give the element more space than it needs:
108
box.
x_max
= std::min(box.
x_max
, e->requirement().min_x);
109
box.
y_max
= e->requirement().min_y;
110
if
(!extend_beyond_screen) {
111
box.
y_max
= std::min(box.
y_max
, fullsize.
dimy
);
112
}
113
114
e->SetBox(box);
115
status.
need_iteration
=
false
;
116
status.
iteration
++;
117
e->Check(&status);
118
119
if
(!status.
need_iteration
) {
120
break
;
121
}
122
// Increase the size of the box until it fits...
123
box.
x_max
= std::min(e->requirement().min_x, fullsize.
dimx
);
124
box.
y_max
= e->requirement().min_y;
125
126
// ... but don't go beyond the screen size:
127
if
(!extend_beyond_screen) {
128
box.
y_max
= std::min(box.
y_max
, fullsize.
dimy
);
129
}
130
}
131
132
return
{
133
box.
x_max
,
134
box.
y_max
,
135
};
136
}
137
138
/// An element of size 0x0 drawing nothing.
139
/// @ingroup dom
140
Element
emptyElement
() {
141
class
Impl :
public
Node
{
142
void
ComputeRequirement()
override
{
143
requirement_.min_x = 0;
144
requirement_.min_y = 0;
145
}
146
};
147
return
std::make_unique<Impl>();
148
}
149
150
}
// namespace ftxui
box.hpp
ftxui::Node
Definition
node.hpp:23
ftxui::Node::Status::need_iteration
bool need_iteration
Definition
node.hpp:58
ftxui::Node::Status::iteration
int iteration
Definition
node.hpp:57
ftxui::Node::Status
Definition
node.hpp:56
elements.hpp
ftxui::Dimension::Fit
Dimensions Fit(Element &, bool extend_beyond_screen=false)
Definition
util.cpp:93
ftxui::Dimension::Full
Dimensions Full()
Definition
screen.cpp:382
ftxui
Definition
animation.hpp:10
ftxui::Decorator
std::function< Element(Element)> Decorator
Definition
elements.hpp:24
ftxui::nothing
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition
util.cpp:28
ftxui::Element
std::shared_ptr< Node > Element
Definition
elements.hpp:22
ftxui::Dimensions::dimy
int dimy
Definition
terminal.hpp:10
ftxui::emptyElement
Element emptyElement()
Definition
util.cpp:140
ftxui::Elements
std::vector< Element > Elements
Definition
elements.hpp:23
ftxui::operator|
Component operator|(Component component, ComponentDecorator decorator)
Definition
util.cpp:12
ftxui::Dimensions::dimx
int dimx
Definition
terminal.hpp:9
ftxui::operator|=
Component & operator|=(Component &component, ComponentDecorator decorator)
Definition
util.cpp:22
ftxui::Dimensions
Definition
terminal.hpp:8
node.hpp
requirement.hpp
screen.hpp
ftxui::Box
Definition
box.hpp:9
ftxui::Box::x_max
int x_max
Definition
box.hpp:11
ftxui::Box::y_min
int y_min
Definition
box.hpp:12
ftxui::Box::y_max
int y_max
Definition
box.hpp:13
ftxui::Box::x_min
int x_min
Definition
box.hpp:10
terminal.hpp