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