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 
18 namespace ftxui {
19 
20 namespace {
21 Decorator 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
50 Elements 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 /// ```
72 Element 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