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