FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
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 將 `child` 設置為其同級元素中被聚焦的元素。
99/// @param child 要被聚焦的元素。
100/// @ingroup dom
102 return std::make_shared<Focus>(unpack(std::move(child)));
103}
104
105/// This is deprecated. Use `focus` instead.
106/// @brief 將 `child` 設置為其同級元素中被聚焦的元素。
107/// @param child 要被聚焦的元素。
109 return focus(std::move(child));
110}
111
112/// @brief 允許元素顯示在「虛擬」區域內。其大小可以大於其容器。在這種情況下,只會顯示較小的一部分。視圖可滾動以使聚焦元素可見。
113/// @see frame
114/// @see xframe
115/// @see yframe
117 return std::make_shared<Frame>(unpack(std::move(child)), true, true);
118}
119
120/// @brief 與 `frame` 相同,但僅限於 x 軸。
121/// @see frame
122/// @see xframe
123/// @see yframe
125 return std::make_shared<Frame>(unpack(std::move(child)), true, false);
126}
127
128/// @brief 與 `frame` 相同,但僅限於 y 軸。
129/// @see frame
130/// @see xframe
131/// @see yframe
133 return std::make_shared<Frame>(unpack(std::move(child)), false, true);
134}
135
136/// @brief 與 `focus` 相同,但將游標形狀設置為靜止方塊。
137/// @see focus
138/// @see focusCursorBlock
139/// @see focusCursorBlockBlinking
140/// @see focusCursorBar
141/// @see focusCursorBarBlinking
142/// @see focusCursorUnderline
143/// @see focusCursorUnderlineBlinking
144/// @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
160 return std::make_shared<FocusCursor>(unpack(std::move(child)),
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
174 return std::make_shared<FocusCursor>(unpack(std::move(child)),
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
188 return std::make_shared<FocusCursor>(unpack(std::move(child)),
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
202 return std::make_shared<FocusCursor>(unpack(std::move(child)),
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
216 return std::make_shared<FocusCursor>(unpack(std::move(child)),
218}
219
220} // namespace ftxui
virtual void SetBox(Box box)
為元素分配繪圖位置和尺寸。
Definition node.cpp:40
virtual void ComputeRequirement()
計算元素所需的空間大小。
Definition node.cpp:19
Element focusCursorBarBlinking(Element)
與 focus 相同,但將游標形狀設置為閃爍條狀。
Definition frame.cpp:187
Element focusCursorUnderlineBlinking(Element)
與 focus 相同,但將游標形狀設置為閃爍底線。
Definition frame.cpp:215
Element focusCursorBar(Element)
與 focus 相同,但將游標形狀設置為靜止條狀。
Definition frame.cpp:173
Element focusCursorBlock(Element)
與 focus 相同,但將游標形狀設置為靜止方塊。
Definition frame.cpp:145
Element focusCursorUnderline(Element)
與 focus 相同,但將游標形狀設置為靜止底線。
Definition frame.cpp:201
Element focus(Element)
將 child 設置為其同級元素中被聚焦的元素。
Definition frame.cpp:101
Element focusCursorBlockBlinking(Element)
與 focus 相同,但將游標形狀設置為閃爍方塊。
Definition frame.cpp:159
static auto Intersection(Box a, Box b) -> Box
Definition box.cpp:11
FTXUI 的 ftxui:: 命名空間
Definition animation.hpp:10
std::shared_ptr< Node > Element
Definition elements.hpp:22
Element xframe(Element)
與 frame 相同,但僅限於 x 軸。
Definition frame.cpp:124
std::vector< Element > Elements
Definition elements.hpp:23
Element yframe(Element)
與 frame 相同,但僅限於 y 軸。
Definition frame.cpp:132
Element select(Element e)
將 child 設置為其同級元素中被聚焦的元素。
Definition frame.cpp:108
Element frame(Element)
允許元素顯示在「虛擬」區域內。其大小可以大於其容器。在這種情況下,只會顯示較小的一部分。視圖可滾動以使聚焦元素可見。
Definition frame.cpp:116
void Render(Screen &screen, const Element &element)