FTXUI 6.1.9 C++ functional terminal UI.

Loading...
Searching...
No Matches
dom/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
elements.hpp
ftxui::Node
Node is the base class for all elements in the DOM tree.
Definition node.hpp:37
ftxui::nothing
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition dom/util.cpp:28
ftxui::emptyElement
Element emptyElement()
Definition dom/util.cpp:140
ftxui::Dimension::Fit
Dimensions Fit(Element &, bool extend_beyond_screen=false)
ftxui::Dimension::Full
Dimensions Full()
ftxui
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
ftxui::Decorator
std::function< Element(Element)> Decorator
Definition elements.hpp:24
ftxui::Element
std::shared_ptr< Node > Element
Definition elements.hpp:22
ftxui::Elements
std::vector< Element > Elements
Definition elements.hpp:23
ftxui::operator|
Component operator|(Component component, ComponentDecorator decorator)
Definition component/util.cpp:12
ftxui::operator|=
Component & operator|=(Component &component, ComponentDecorator decorator)
Definition component/util.cpp:22
node.hpp
requirement.hpp
screen.hpp
terminal.hpp