FTXUI  0.11.1
C++ functional terminal UI.
util.cpp
Go to the documentation of this file.
1 #include <algorithm> // for min
2 #include <functional> // for function
3 #include <memory> // for __shared_ptr_access, make_unique
4 #include <utility> // for move
5 #include <vector> // for vector
6 
7 #include "ftxui/dom/elements.hpp" // for Element, Decorator, Elements, operator|, Fit, emptyElement, nothing
8 #include "ftxui/dom/node.hpp" // for Node, Node::Status
9 #include "ftxui/dom/requirement.hpp" // for Requirement
10 #include "ftxui/screen/box.hpp" // for Box
11 #include "ftxui/screen/screen.hpp" // for Full
12 #include "ftxui/screen/terminal.hpp" // for Dimensions
13 
14 namespace ftxui {
15 
16 namespace {
17 Decorator compose(Decorator a, Decorator b) {
18  return [a = std::move(a), b = std::move(b)](Element element) {
19  return b(a(std::move(element)));
20  };
21 }
22 } // namespace
23 
24 /// @brief A decoration doing absolutely nothing.
25 /// @ingroup dom
27  return element;
28 }
29 
30 /// @brief Compose two decorator into one.
31 /// @ingroup dom
32 ///
33 /// ### Example
34 ///
35 /// ```cpp
36 /// auto decorator = bold | blink;
37 /// ```
39  return compose(a, b);
40 }
41 
42 /// @brief From a set of element, apply a decorator to every elements.
43 /// @return the set of decorated element.
44 /// @ingroup dom
45 Elements operator|(Elements elements, Decorator decorator) {
46  Elements output;
47  for (auto& it : elements)
48  output.push_back(std::move(it) | decorator);
49  return output;
50 }
51 
52 /// @brief From an element, apply a decorator.
53 /// @return the decorated element.
54 /// @ingroup dom
55 ///
56 /// ### Example
57 ///
58 /// Both of these are equivalent:
59 /// ```cpp
60 /// bold(text("Hello"));
61 /// ```
62 /// ```cpp
63 /// text("Hello") | bold;
64 /// ```
65 Element operator|(Element element, Decorator decorator) {
66  return decorator(std::move(element));
67 }
68 
69 /// The minimal dimension that will fit the given element.
70 /// @see Fixed
71 /// @see Full
73  Dimensions fullsize = Dimension::Full();
74  Box box;
75  box.x_min = 0;
76  box.y_min = 0;
77  box.x_max = fullsize.dimx;
78  box.y_max = fullsize.dimy;
79 
80  Node::Status status;
81  e->Check(&status);
82  while (status.need_iteration && status.iteration < 20) {
83  e->ComputeRequirement();
84 
85  // Don't give the element more space than it needs:
86  box.x_max = std::min(box.x_max, e->requirement().min_x);
87  box.y_max = std::min(box.y_max, e->requirement().min_y);
88 
89  e->SetBox(box);
90  status.need_iteration = false;
91  status.iteration++;
92  e->Check(&status);
93 
94  if (!status.need_iteration)
95  break;
96  // Increase the size of the box until it fits, but not more than the with of
97  // the terminal emulator:
98  box.x_max = std::min(e->requirement().min_x, fullsize.dimx);
99  box.y_max = std::min(e->requirement().min_y, fullsize.dimy);
100  }
101 
102  return {
103  box.x_max,
104  box.y_max,
105  };
106 }
107 
108 /// An element of size 0x0 drawing nothing.
109 /// @ingroup dom
111  class Impl : public Node {
112  void ComputeRequirement() override {
113  requirement_.min_x = 0;
114  requirement_.min_x = 0;
115  }
116  };
117  return std::make_unique<Impl>();
118 }
119 
120 } // namespace ftxui
121 
122 // Copyright 2020 Arthur Sonzogni. All rights reserved.
123 // Use of this source code is governed by the MIT license that can be found in
124 // the LICENSE file.
bool need_iteration
Definition: node.hpp:43
Dimensions Fit(Element &)
Definition: util.cpp:72
Dimensions Full()
Definition: screen.cpp:332
std::function< Element(Element)> Decorator
Definition: elements.hpp:18
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition: util.cpp:26
std::shared_ptr< Node > Element
Definition: elements.hpp:16
Element emptyElement()
Definition: util.cpp:110
std::vector< Element > Elements
Definition: elements.hpp:17
Element operator|(Element, Decorator)
From an element, apply a decorator.
Definition: util.cpp:65
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