FTXUI 6.1.9
C++ functional terminal UI.
载入中...
搜索中...
未找到
frame.cpp
浏览该文件的文档.
1// Copyright 2020 Arthur Sonzogni. 保留所有权利。
2// 本源代码受 MIT 许可证约束,该许可证可在 LICENSE 文件中找到。
3#include <algorithm> // for max, min
4#include <memory> // for make_shared, __shared_ptr_access
5#include <utility> // for move
6
7#include "ftxui/dom/elements.hpp" // for Element, unpack, Elements, focus, frame, select, xframe, yframe
8#include "ftxui/dom/node.hpp" // for Node, Elements
9#include "ftxui/dom/requirement.hpp" // for Requirement
10#include "ftxui/screen/box.hpp" // for Box
11#include "ftxui/screen/screen.hpp" // for Screen, Screen::Cursor
12#include "ftxui/util/autoreset.hpp" // for AutoReset
13
14namespace ftxui {
15
16namespace {
17class Focus : public Node {
18 public:
19 explicit Focus(Elements children) : Node(std::move(children)) {}
20
21 void ComputeRequirement() override {
23 requirement_ = children_[0]->requirement();
24 requirement_.focused.enabled = true;
25 requirement_.focused.node = this;
26 requirement_.focused.box.x_min = 0;
27 requirement_.focused.box.y_min = 0;
28 requirement_.focused.box.x_max = requirement_.min_x - 1;
29 requirement_.focused.box.y_max = requirement_.min_y - 1;
30 }
31
32 void SetBox(Box box) override {
33 Node::SetBox(box);
34 children_[0]->SetBox(box);
35 }
36};
37
38class Frame : public Node {
39 public:
40 Frame(Elements children, bool x_frame, bool y_frame)
41 : Node(std::move(children)), x_frame_(x_frame), y_frame_(y_frame) {}
42
43 void SetBox(Box box) override {
44 Node::SetBox(box);
45 auto& focused_box = requirement_.focused.box;
46 Box children_box = box;
47
48 if (x_frame_) {
49 const int external_dimx = box.x_max - box.x_min;
50 const int internal_dimx = std::max(requirement_.min_x, external_dimx);
51 const int focused_dimx = focused_box.x_max - focused_box.x_min;
52 int dx = focused_box.x_min - external_dimx / 2 + focused_dimx / 2;
53 dx = std::max(0, std::min(internal_dimx - external_dimx - 1, dx));
54 children_box.x_min = box.x_min - dx;
55 children_box.x_max = box.x_min + internal_dimx - dx;
56 }
57
58 if (y_frame_) {
59 const int external_dimy = box.y_max - box.y_min;
60 const int internal_dimy = std::max(requirement_.min_y, external_dimy);
61 const int focused_dimy = focused_box.y_max - focused_box.y_min;
62 int dy = focused_box.y_min - external_dimy / 2 + focused_dimy / 2;
63 dy = std::max(0, std::min(internal_dimy - external_dimy - 1, dy));
64 children_box.y_min = box.y_min - dy;
65 children_box.y_max = box.y_min + internal_dimy - dy;
66 }
67
68 children_[0]->SetBox(children_box);
69 }
70
71 void Render(Screen& screen) override {
72 const AutoReset<Box> stencil(&screen.stencil,
73 Box::Intersection(box_, screen.stencil));
74 children_[0]->Render(screen);
75 }
76
77 private:
78 bool x_frame_;
79 bool y_frame_;
80};
81
82class FocusCursor : public Focus {
83 public:
84 FocusCursor(Elements children, Screen::Cursor::Shape shape)
85 : Focus(std::move(children)), shape_(shape) {}
86
87 private:
88 void ComputeRequirement() override {
89 Focus::ComputeRequirement(); // NOLINT
90 requirement_.focused.cursor_shape = shape_;
91 }
93};
94
95} // namespace
96
97/// @brief 将 `child` 设置为其同级元素中获得焦点的元素。
98/// @param child 要获得焦点的元素。
99/// @ingroup dom
101 return std::make_shared<Focus>(unpack(std::move(child)));
102}
103
104/// 此功能已弃用。请改用 `focus`。
105/// @brief 将 `child` 设置为其同级元素中获得焦点的元素。
106/// @param child 要获得焦点的元素。
108 return focus(std::move(child));
109}
110
111/// @brief 允许元素显示在“虚拟”区域内。其大小可以
112/// 大于其容器。在这种情况下,只显示较小的部分。
113/// 视图是可滚动的,以使获得焦点的元素可见。
114/// @see frame
115/// @see xframe
116/// @see yframe
118 return std::make_shared<Frame>(unpack(std::move(child)), true, true);
119}
120
121/// @brief 与 `frame` 相同,但仅限于 x 轴。
122/// @see frame
123/// @see xframe
124/// @see yframe
126 return std::make_shared<Frame>(unpack(std::move(child)), true, false);
127}
128
129/// @brief 与 `frame` 相同,但仅限于 y 轴。
130/// @see frame
131/// @see xframe
132/// @see yframe
134 return std::make_shared<Frame>(unpack(std::move(child)), false, true);
135}
136
137/// @brief 与 `focus` 相同,但将光标形状设置为静态块。
138/// @see focus
139/// @see focusCursorBlock
140/// @see focusCursorBlockBlinking
141/// @see focusCursorBar
142/// @see focusCursorBarBlinking
143/// @see focusCursorUnderline
144/// @see focusCursorUnderlineBlinking
145/// @ingroup dom
146 return std::make_shared<FocusCursor>(unpack(std::move(child)),
148}
149
150/// @brief 与 `focus` 相同,但将光标形状设置为闪烁块。
151/// @see focus
152/// @see focusCursorBlock
153/// @see focusCursorBlockBlinking
154/// @see focusCursorBar
155/// @see focusCursorBarBlinking
156/// @see focusCursorUnderline
157/// @see focusCursorUnderlineBlinking
158/// @ingroup dom
159Element focusCursorBlockBlinking(Element child) {
160 return std::make_shared<FocusCursor>(unpack(std::move(child)),
161 Screen::Cursor::BlockBlinking);
162}
163
164/// @brief 与 `focus` 相同,但将光标形状设置为静态竖线。
165/// @see focus
166/// @see focusCursorBlock
167/// @see focusCursorBlockBlinking
168/// @see focusCursorBar
169/// @see focusCursorBarBlinking
170/// @see focusCursorUnderline
171/// @see focusCursorUnderlineBlinking
172/// @ingroup dom
173Element focusCursorBar(Element child) {
174 return std::make_shared<FocusCursor>(unpack(std::move(child)),
175 Screen::Cursor::Bar);
176}
177
178/// @brief 与 `focus` 相同,但将光标形状设置为闪烁竖线。
179/// @see focus
180/// @see focusCursorBlock
181/// @see focusCursorBlockBlinking
182/// @see focusCursorBar
183/// @see focusCursorBarBlinking
184/// @see focusCursorUnderline
185/// @see focusCursorUnderlineBlinking
186/// @ingroup dom
187Element focusCursorBarBlinking(Element child) {
188 return std::make_shared<FocusCursor>(unpack(std::move(child)),
189 Screen::Cursor::BarBlinking);
190}
191
192/// @brief 与 `focus` 相同,但将光标形状设置为静态下划线。
193/// @see focus
194/// @see focusCursorBlock
195/// @see focusCursorBlockBlinking
196/// @see focusCursorBar
197/// @see focusCursorBarBlinking
198/// @see focusCursorUnderline
199/// @see focusCursorUnderlineBlinking
200/// @ingroup dom
201Element focusCursorUnderline(Element child) {
202 return std::make_shared<FocusCursor>(unpack(std::move(child)),
203 Screen::Cursor::Underline);
204}
205
206/// @brief 与 `focus` 相同,但将光标形状设置为闪烁下划线。
207/// @see focus
208/// @see focusCursorBlock
209/// @see focusCursorBlockBlinking
210/// @see focusCursorBar
211/// @see focusCursorBarBlinking
212/// @see focusCursorUnderline
213/// @see focusCursorUnderlineBlinking
214/// @ingroup dom
215Element focusCursorUnderlineBlinking(Element child) {
216 return std::make_shared<FocusCursor>(unpack(std::move(child)),
217 Screen::Cursor::UnderlineBlinking);
218}
219
220} // namespace ftxui
virtual void SetBox(Box box)
为绘图元素分配位置和尺寸。
virtual void ComputeRequirement()
计算元素所需的空间。
Element focusCursorBarBlinking(Element child)
与 focus 相同,但将光标形状设置为闪烁竖线。
Element focusCursorUnderlineBlinking(Element child)
与 focus 相同,但将光标形状设置为闪烁下划线。
Element focusCursorBar(Element child)
与 focus 相同,但将光标形状设置为静态竖线。
Element focusCursorUnderline(Element child)
与 focus 相同,但将光标形状设置为静态下划线。
Element focus(Element)
将 child 设置为其同级元素中获得焦点的元素。
void Render(Screen &screen, const Element &element)
在 ftxui::Screen 上显示元素。
Element focusCursorBlockBlinking(Element child)
与 focus 相同,但将光标形状设置为闪烁块。
static auto Intersection(Box a, Box b) -> Box
定义 box.cpp:11
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase
std::shared_ptr< Node > Element
Element xframe(Element)
与 frame 相同,但仅限于 x 轴。
std::vector< Element > Elements
Element yframe(Element)
与 frame 相同,但仅限于 y 轴。
Element select(Element e)
将 child 设置为其同级元素中获得焦点的元素。
Element frame(Element)
允许元素显示在“虚拟”区域内。其大小可以 大于其容器。在这种情况下,只显示较小的部分。 视图是可滚动的,以使获得焦点的元素可见。