FTXUI  5.0.0
C++ functional terminal UI.
flex.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 <memory> // for make_shared, __shared_ptr_access
5 #include <utility> // for move
6 #include <vector> // for __alloc_traits<>::value_type
7 
8 #include "ftxui/dom/elements.hpp" // for Element, unpack, filler, flex, flex_grow, flex_shrink, notflex, xflex, xflex_grow, xflex_shrink, yflex, yflex_grow, yflex_shrink
9 #include "ftxui/dom/node.hpp" // for Elements, Node
10 #include "ftxui/dom/requirement.hpp" // for Requirement
11 #include "ftxui/screen/box.hpp" // for Box
12 
13 namespace ftxui {
14 
15 namespace {
16 
17 using FlexFunction = void (*)(Requirement&);
18 
19 void function_flex_grow(Requirement& r) {
20  r.flex_grow_x = 1;
21  r.flex_grow_y = 1;
22 }
23 
24 void function_xflex_grow(Requirement& r) {
25  r.flex_grow_x = 1;
26 }
27 
28 void function_yflex_grow(Requirement& r) {
29  r.flex_grow_y = 1;
30 }
31 
32 void function_flex_shrink(Requirement& r) {
33  r.flex_shrink_x = 1;
34  r.flex_shrink_y = 1;
35 }
36 
37 void function_xflex_shrink(Requirement& r) {
38  r.flex_shrink_x = 1;
39 }
40 
41 void function_yflex_shrink(Requirement& r) {
42  r.flex_shrink_y = 1;
43 }
44 
45 void function_flex(Requirement& r) {
46  r.flex_grow_x = 1;
47  r.flex_grow_y = 1;
48  r.flex_shrink_x = 1;
49  r.flex_shrink_y = 1;
50 }
51 
52 void function_xflex(Requirement& r) {
53  r.flex_grow_x = 1;
54  r.flex_shrink_x = 1;
55 }
56 
57 void function_yflex(Requirement& r) {
58  r.flex_grow_y = 1;
59  r.flex_shrink_y = 1;
60 }
61 
62 void function_not_flex(Requirement& r) {
63  r.flex_grow_x = 0;
64  r.flex_grow_y = 0;
65  r.flex_shrink_x = 0;
66  r.flex_shrink_y = 0;
67 }
68 
69 class Flex : public Node {
70  public:
71  explicit Flex(FlexFunction f) : f_(f) {}
72  Flex(FlexFunction f, Element child) : Node(unpack(std::move(child))), f_(f) {}
73  void ComputeRequirement() override {
74  requirement_.min_x = 0;
75  requirement_.min_y = 0;
76  if (!children_.empty()) {
77  children_[0]->ComputeRequirement();
78  requirement_ = children_[0]->requirement();
79  }
80  f_(requirement_);
81  }
82 
83  void SetBox(Box box) override {
84  if (children_.empty()) {
85  return;
86  }
87  children_[0]->SetBox(box);
88  }
89 
90  FlexFunction f_;
91 };
92 
93 } // namespace
94 
95 /// @brief An element that will take expand proportionnally to the space left in
96 /// a container.
97 /// @ingroup dom
99  return std::make_shared<Flex>(function_flex);
100 }
101 
102 /// @brief Make a child element to expand proportionnally to the space left in a
103 /// container.
104 /// @ingroup dom
105 ///
106 /// #### Examples:
107 ///
108 /// ~~~cpp
109 /// hbox({
110 /// text("left") | border ,
111 /// text("middle") | border | flex,
112 /// text("right") | border,
113 /// });
114 /// ~~~
115 ///
116 /// #### Output:
117 ///
118 /// ~~~bash
119 /// ┌────┐┌─────────────────────────────────────────────────────────┐┌─────┐
120 /// │left││middle ││right│
121 /// └────┘└─────────────────────────────────────────────────────────┘└─────┘
122 /// ~~~
124  return std::make_shared<Flex>(function_flex, std::move(child));
125 }
126 
127 /// @brief Expand/Minimize if possible/needed on the X axis.
128 /// @ingroup dom
130  return std::make_shared<Flex>(function_xflex, std::move(child));
131 }
132 
133 /// @brief Expand/Minimize if possible/needed on the Y axis.
134 /// @ingroup dom
136  return std::make_shared<Flex>(function_yflex, std::move(child));
137 }
138 
139 /// @brief Expand if possible.
140 /// @ingroup dom
142  return std::make_shared<Flex>(function_flex_grow, std::move(child));
143 }
144 
145 /// @brief Expand if possible on the X axis.
146 /// @ingroup dom
148  return std::make_shared<Flex>(function_xflex_grow, std::move(child));
149 }
150 
151 /// @brief Expand if possible on the Y axis.
152 /// @ingroup dom
154  return std::make_shared<Flex>(function_yflex_grow, std::move(child));
155 }
156 
157 /// @brief Minimize if needed.
158 /// @ingroup dom
160  return std::make_shared<Flex>(function_flex_shrink, std::move(child));
161 }
162 
163 /// @brief Minimize if needed on the X axis.
164 /// @ingroup dom
166  return std::make_shared<Flex>(function_xflex_shrink, std::move(child));
167 }
168 
169 /// @brief Minimize if needed on the Y axis.
170 /// @ingroup dom
172  return std::make_shared<Flex>(function_yflex_shrink, std::move(child));
173 }
174 
175 /// @brief Make the element not flexible.
176 /// @ingroup dom
178  return std::make_shared<Flex>(function_not_flex, std::move(child));
179 }
180 
181 } // namespace ftxui
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
Definition: flex.cpp:129
Element xflex_grow(Element)
Expand if possible on the X axis.
Definition: flex.cpp:147
Element flex(Element)
Make a child element to expand proportionnally to the space left in a container.
Definition: flex.cpp:123
std::shared_ptr< Node > Element
Definition: elements.hpp:23
Element yflex(Element)
Expand/Minimize if possible/needed on the Y axis.
Definition: flex.cpp:135
Element flex_shrink(Element)
Minimize if needed.
Definition: flex.cpp:159
Element yflex_grow(Element)
Expand if possible on the Y axis.
Definition: flex.cpp:153
Element flex_grow(Element)
Expand if possible.
Definition: flex.cpp:141
Element notflex(Element)
Make the element not flexible.
Definition: flex.cpp:177
Element xflex_shrink(Element)
Minimize if needed on the X axis.
Definition: flex.cpp:165
Element filler()
An element that will take expand proportionnally to the space left in a container.
Definition: flex.cpp:98
Element yflex_shrink(Element)
Minimize if needed on the Y axis.
Definition: flex.cpp:171