FTXUI 6.1.9
C++ functional terminal UI.
载入中...
搜索中...
未找到
component.cpp
浏览该文件的文档.
1// Copyright 2020 Arthur Sonzogni. 版权所有。
2// 本源代码的使用受 MIT 许可证的约束,该许可证可在
3// LICENSE 文件中找到。
4#include <algorithm> // for find_if
5#include <cassert> // for assert
6#include <cstddef> // for size_t
7#include <iterator> // for begin, end
8#include <memory> // for unique_ptr, make_unique
9#include <utility> // for move
10#include <vector> // for vector, __alloc_traits<>::value_type
11
12#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse, CapturedMouseInterface
14#include "ftxui/component/component_base.hpp" // for ComponentBase, Components
15#include "ftxui/component/event.hpp" // for Event
16#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
17#include "ftxui/dom/elements.hpp" // for text, Element
18#include "ftxui/dom/node.hpp" // for Node, Elements
19#include "ftxui/screen/box.hpp" // for Box
20
21namespace ftxui::animation {
22class Params;
23} // namespace ftxui::animation
24
25namespace ftxui {
26
27namespace {
28class CaptureMouseImpl : public CapturedMouseInterface {};
29} // namespace
30
34
35/// @brief 返回父 ComponentBase,如果没有则返回 null。
36/// @see Detach
37/// @see Parent
39 return parent_;
40}
41
42/// @brief 访问索引 `i` 处的子项。
44 assert(i < ChildCount()); // NOLINT
45 return children_[i];
46}
47
48/// @brief 返回子项的数量。
50 return children_.size();
51}
52
53/// @brief 返回组件在其父级中的索引。如果没有父级,则返回 -1。
55 if (parent_ == nullptr) {
56 return -1;
57 }
58 int index = 0;
59 for (const Component& child : parent_->children_) {
60 if (child.get() == this) {
61 return index;
62 }
63 index++;
64 }
65 return -1; // Not reached.
66}
67
68/// @brief 添加一个子项。
69/// @@param child 要附加的子项。
71 child->Detach();
72 child->parent_ = this;
73 children_.push_back(std::move(child));
74}
75
76/// @brief 将此子项从其父级分离。
77/// @see Detach
78/// @see Parent
80 if (parent_ == nullptr) {
81 return;
82 }
83 auto it = std::find_if(std::begin(parent_->children_), //
84 std::end(parent_->children_), //
85 [this](const Component& that) { //
86 return this == that.get();
87 });
88 ComponentBase* parent = parent_;
89 parent_ = nullptr;
90 parent->children_.erase(it); // Might delete |this|.
91}
92
93/// @brief 移除所有子项。
95 while (!children_.empty()) {
96 children_[0]->Detach();
97 }
98}
99
100/// @brief 绘制组件。
101/// 构建一个 ftxui::Element,用于在表示此 ftxui::ComponentBase 的 ftxui::Screen 上绘制。
102/// 请覆盖 OnRender() 以修改渲染。
104// 某些用户可能会从 `T::OnRender()` 调用 `ComponentBase::Render()`。
105// 为避免无限递归,我们使用一个标志。
106 if (in_render) {
108 }
109
110 in_render = true;
111 Element element = OnRender();
112 in_render = false;
113
114 class Wrapper : public Node {
115 public:
116 bool active_ = false;
117
118 Wrapper(Element child, bool active)
119 : Node({std::move(child)}), active_(active) {}
120
121 void SetBox(Box box) override {
122 Node::SetBox(box);
123 children_[0]->SetBox(box);
124 }
125
126 void ComputeRequirement() override {
127 Node::ComputeRequirement();
128 requirement_.focused.component_active = active_;
129 }
130 };
131
132 return std::make_shared<Wrapper>(std::move(element), Active());
133}
134
135/// @brief 绘制组件。
136/// 构建一个 ftxui::Element,用于在表示此 ftxui::ComponentBase 的 ftxui::Screen 上绘制。
137/// 此函数旨在被覆盖。
139 if (children_.size() == 1) {
140 return children_.front()->Render();
141 }
142
143 return text("Not implemented component");
144}
145
146/// @brief 响应事件时调用。
147/// @param event 事件。
148/// @return 当事件已处理时返回 true。
149/// 默认实现会在每个子项上调用 OnEvent,直到有一个返回 true。
150/// 如果都没有返回 true,则返回 false。
151bool ComponentBase::OnEvent(Event event) { // NOLINT
152 for (Component& child : children_) { // NOLINT
153 if (child->OnEvent(event)) {
154 return true;
155 }
156 }
157 return false;
158}
159
160/// @brief 响应动画事件时调用。
161/// @param params 动画的参数
162/// 默认实现将事件分派给每个子项。
164 for (const Component& child : children_) {
165 child->OnAnimation(params);
166 }
167}
168
169/// @brief 返回当前活动的子项。
170/// @return 当前活动的子项。
172 for (auto& child : children_) {
173 if (child->Focusable()) {
174 return child;
175 }
176 }
177 return nullptr;
178}
179
180/// @brief 当组件包含可聚焦元素时返回 true。
181/// 使用键盘导航时,不可聚焦的组件将被跳过。
183 for (const Component& child : children_) { // NOLINT
184 if (child->Focusable()) {
185 return true;
186 }
187 }
188 return false;
189}
190
191/// @brief 返回该元素是否是其父级的当前活动子项。
193 return parent_ == nullptr || parent_->ActiveChild().get() == this;
194}
195
196/// @brief 返回元素是否被用户聚焦。
197/// 当 ComponentBase 被用户聚焦时返回 true。当一个元素及其所有祖先都是其父级的 ActiveChild() 并且它是 Focusable() 时,该元素被聚焦。
199 const auto* current = this;
200 while (current && current->Active()) {
201 current = current->parent_;
202 }
203 return !current && Focusable();
204}
205
206/// @brief 使 |child| 成为“活动”子项。
207/// @param child 将成为活动状态的子项。
208void ComponentBase::SetActiveChild([[maybe_unused]] ComponentBase* child) {}
209
210/// @brief 使 |child| 成为“活动”子项。
211/// @param child 将成为活动状态的子项。
213 SetActiveChild(child.get());
214}
215
216/// @brief 配置所有祖先以将焦点赋予此组件。
218 ComponentBase* child = this;
219 while (ComponentBase* parent = child->parent_) {
220 parent->SetActiveChild(child);
221 child = parent;
222 }
223}
224
225/// @brief 如果可用,则捕获 CapturedMouse。只有一个组件可以捕获它。
226/// 它表示一个优先于其他组件的组件。
227/// @param event 事件
229 if (event.screen_) {
230 return event.screen_->CaptureMouse();
231 }
232 return std::make_unique<CaptureMouseImpl>();
233}
234
235} // namespace ftxui
virtual bool Focusable() const
当组件包含可聚焦元素时返回 true。 使用键盘导航时,不可聚焦的组件将被跳过。
bool Focused() const
返回元素是否被用户聚焦。 当 ComponentBase 被用户聚焦时返回 true。当一个元素及其所有祖先都是其父级的 ActiveChild() 并且它是 Focusable() 时,该元素被聚焦。
CapturedMouse CaptureMouse(const Event &event)
如果可用,则捕获 CapturedMouse。只有一个组件可以捕获它。 它表示一个优先于其他组件的组件。
void Add(Component children)
添加一个子项。 @param child 要附加的子项。
Element Render()
绘制组件。 构建一个 ftxui::Element,用于在表示此 ftxui::ComponentBase 的 ftxui::Screen 上绘制。 请覆盖 OnRender() 以修改渲染。
void TakeFocus()
配置所有祖先以将焦点赋予此组件。
bool Active() const
返回该元素是否是其父级的当前活动子项。
ScreenInteractive * screen_
virtual Component ActiveChild()
返回当前活动的子项。
void DetachAllChildren()
移除所有子项。
virtual void SetActiveChild(ComponentBase *child)
使 |child| 成为“活动”子项。
int Index() const
返回组件在其父级中的索引。如果没有父级,则返回 -1。
size_t ChildCount() const
返回子项的数量。
ComponentBase * Parent() const
返回父 ComponentBase,如果没有则返回 null。
virtual Element OnRender()
绘制组件。 构建一个 ftxui::Element,用于在表示此 ftxui::ComponentBase 的 ftxui::Screen 上绘制。 此函数旨在被覆盖。
virtual bool OnEvent(Event)
响应事件时调用。
void Detach()
将此子项从其父级分离。
Component & ChildAt(size_t i)
访问索引 i 处的子项。
virtual void OnAnimation(animation::Params &params)
响应动画事件时调用。
它将自身实现为 ftxui::Element。它通过响应 ftxui::Event 来实现键盘导航。
代表一个事件。它可以是按键事件、终端大小调整等等...
Node 是 DOM 树中所有元素的基类。
Element text(std::wstring text)
显示一段Unicode文本。
Box是一个表示2D空间中矩形区域的结构体。
定义 box.hpp:15
FTXUI ftxui::animation:: 命名空间
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< Node > Element
std::shared_ptr< ComponentBase > Component