FTXUI  6.0.2
C++ functional terminal UI.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
frame.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 max, min
5#include <memory> // for make_shared, __shared_ptr_access
6#include <utility> // for move
7
8#include "ftxui/dom/elements.hpp" // for Element, unpack, Elements, focus, frame, select, xframe, yframe
9#include "ftxui/dom/node.hpp" // for Node, Elements
10#include "ftxui/dom/requirement.hpp" // for Requirement
11#include "ftxui/screen/box.hpp" // for Box
12#include "ftxui/screen/screen.hpp" // for Screen, Screen::Cursor
13#include "ftxui/util/autoreset.hpp" // for AutoReset
14
15namespace ftxui {
16
17namespace {
18class Focus : public Node {
19 public:
20 explicit Focus(Elements children) : Node(std::move(children)) {}
21
22 void ComputeRequirement() override {
24 requirement_ = children_[0]->requirement();
25 requirement_.focused.enabled = true;
26 requirement_.focused.node = this;
27 requirement_.focused.box.x_min = 0;
28 requirement_.focused.box.y_min = 0;
29 requirement_.focused.box.x_max = requirement_.min_x - 1;
30 requirement_.focused.box.y_max = requirement_.min_y - 1;
31 }
32
33 void SetBox(Box box) override {
34 Node::SetBox(box);
35 children_[0]->SetBox(box);
36 }
37};
38
39class Frame : public Node {
40 public:
41 Frame(Elements children, bool x_frame, bool y_frame)
42 : Node(std::move(children)), x_frame_(x_frame), y_frame_(y_frame) {}
43
44 void SetBox(Box box) override {
45 Node::SetBox(box);
46 auto& focused_box = requirement_.focused.box;
47 Box children_box = box;
48
49 if (x_frame_) {
50 const int external_dimx = box.x_max - box.x_min;
51 const int internal_dimx = std::max(requirement_.min_x, external_dimx);
52 const int focused_dimx = focused_box.x_max - focused_box.x_min;
53 int dx = focused_box.x_min - external_dimx / 2 + focused_dimx / 2;
54 dx = std::max(0, std::min(internal_dimx - external_dimx - 1, dx));
55 children_box.x_min = box.x_min - dx;
56 children_box.x_max = box.x_min + internal_dimx - dx;
57 }
58
59 if (y_frame_) {
60 const int external_dimy = box.y_max - box.y_min;
61 const int internal_dimy = std::max(requirement_.min_y, external_dimy);
62 const int focused_dimy = focused_box.y_max - focused_box.y_min;
63 int dy = focused_box.y_min - external_dimy / 2 + focused_dimy / 2;
64 dy = std::max(0, std::min(internal_dimy - external_dimy - 1, dy));
65 children_box.y_min = box.y_min - dy;
66 children_box.y_max = box.y_min + internal_dimy - dy;
67 }
68
69 children_[0]->SetBox(children_box);
70 }
71
72 void Render(Screen& screen) override {
73 const AutoReset<Box> stencil(&screen.stencil,
74 Box::Intersection(box_, screen.stencil));
75 children_[0]->Render(screen);
76 }
77
78 private:
79 bool x_frame_;
80 bool y_frame_;
81};
82
83class FocusCursor : public Focus {
84 public:
85 FocusCursor(Elements children, Screen::Cursor::Shape shape)
86 : Focus(std::move(children)), shape_(shape) {}
87
88 private:
89 void ComputeRequirement() override {
90 Focus::ComputeRequirement(); // NOLINT
91 requirement_.focused.cursor_shape = shape_;
92 }
94};
95
96} // namespace
97
98/// @brief Set the `child` to be the one focused among its siblings.
99/// @param child The element to be focused.
100/// @ingroup dom
102 return std::make_shared<Focus>(unpack(std::move(child)));
103}
104
105/// This is deprecated. Use `focus` instead.
106/// @brief Set the `child` to be the one focused among its siblings.
107/// @param child The element to be focused.
109 return focus(std::move(child));
110}
111
112/// @brief Allow an element to be displayed inside a 'virtual' area. It size can
113/// be larger than its container. In this case only a smaller portion is
114/// displayed. The view is scrollable to make the focused element visible.
115/// @see frame
116/// @see xframe
117/// @see yframe
119 return std::make_shared<Frame>(unpack(std::move(child)), true, true);
120}
121
122/// @brief Same as `frame`, but only on the x-axis.
123/// @see frame
124/// @see xframe
125/// @see yframe
127 return std::make_shared<Frame>(unpack(std::move(child)), true, false);
128}
129
130/// @brief Same as `frame`, but only on the y-axis.
131/// @see frame
132/// @see xframe
133/// @see yframe
135 return std::make_shared<Frame>(unpack(std::move(child)), false, true);
136}
137
138/// @brief Same as `focus`, but set the cursor shape to be a still block.
139/// @see focus
140/// @see focusCursorBlock
141/// @see focusCursorBlockBlinking
142/// @see focusCursorBar
143/// @see focusCursorBarBlinking
144/// @see focusCursorUnderline
145/// @see focusCursorUnderlineBlinking
146/// @ingroup dom
148 return std::make_shared<FocusCursor>(unpack(std::move(child)),
150}
151
152/// @brief Same as `focus`, but set the cursor shape to be a blinking block.
153/// @see focus
154/// @see focusCursorBlock
155/// @see focusCursorBlockBlinking
156/// @see focusCursorBar
157/// @see focusCursorBarBlinking
158/// @see focusCursorUnderline
159/// @see focusCursorUnderlineBlinking
160/// @ingroup dom
162 return std::make_shared<FocusCursor>(unpack(std::move(child)),
164}
165
166/// @brief Same as `focus`, but set the cursor shape to be a still block.
167/// @see focus
168/// @see focusCursorBlock
169/// @see focusCursorBlockBlinking
170/// @see focusCursorBar
171/// @see focusCursorBarBlinking
172/// @see focusCursorUnderline
173/// @see focusCursorUnderlineBlinking
174/// @ingroup dom
176 return std::make_shared<FocusCursor>(unpack(std::move(child)),
178}
179
180/// @brief Same as `focus`, but set the cursor shape to be a blinking bar.
181/// @see focus
182/// @see focusCursorBlock
183/// @see focusCursorBlockBlinking
184/// @see focusCursorBar
185/// @see focusCursorBarBlinking
186/// @see focusCursorUnderline
187/// @see focusCursorUnderlineBlinking
188/// @ingroup dom
190 return std::make_shared<FocusCursor>(unpack(std::move(child)),
192}
193
194/// @brief Same as `focus`, but set the cursor shape to be a still underline.
195/// @see focus
196/// @see focusCursorBlock
197/// @see focusCursorBlockBlinking
198/// @see focusCursorBar
199/// @see focusCursorBarBlinking
200/// @see focusCursorUnderline
201/// @see focusCursorUnderlineBlinking
202/// @ingroup dom
204 return std::make_shared<FocusCursor>(unpack(std::move(child)),
206}
207
208/// @brief Same as `focus`, but set the cursor shape to be a blinking underline.
209/// @see focus
210/// @see focusCursorBlock
211/// @see focusCursorBlockBlinking
212/// @see focusCursorBar
213/// @see focusCursorBarBlinking
214/// @see focusCursorUnderline
215/// @see focusCursorUnderlineBlinking
216/// @ingroup dom
218 return std::make_shared<FocusCursor>(unpack(std::move(child)),
220}
221
222} // namespace ftxui
virtual void SetBox(Box box)
Assign a position and a dimension to an element for drawing.
Definition node.cpp:43
virtual void ComputeRequirement()
Compute how much space an elements needs.
Definition node.cpp:21
Element focusCursorBarBlinking(Element)
Same as focus, but set the cursor shape to be a blinking bar.
Definition frame.cpp:189
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
Element xframe(Element)
Same as frame, but only on the x-axis.
Definition frame.cpp:126
Element focusCursorUnderlineBlinking(Element)
Same as focus, but set the cursor shape to be a blinking underline.
Definition frame.cpp:217
Element focusCursorBar(Element)
Same as focus, but set the cursor shape to be a still block.
Definition frame.cpp:175
Element focusCursorBlock(Element)
Same as focus, but set the cursor shape to be a still block.
Definition frame.cpp:147
Element focusCursorUnderline(Element)
Same as focus, but set the cursor shape to be a still underline.
Definition frame.cpp:203
std::vector< Element > Elements
Definition elements.hpp:23
Element yframe(Element)
Same as frame, but only on the y-axis.
Definition frame.cpp:134
Element select(Element e)
Set the child to be the one focused among its siblings.
Definition frame.cpp:108
Element focus(Element)
Set the child to be the one focused among its siblings.
Definition frame.cpp:101
Element frame(Element)
Allow an element to be displayed inside a 'virtual' area. It size can be larger than its container....
Definition frame.cpp:118
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition node.cpp:88
Element focusCursorBlockBlinking(Element)
Same as focus, but set the cursor shape to be a blinking block.
Definition frame.cpp:161
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:12