FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
component.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// このソースコードの使用は、LICENSEファイルにあるMITライセンスに準拠しています。
3#include <algorithm> // for find_if
4#include <cassert> // for assert
5#include <cstddef> // for size_t
6#include <iterator> // for begin, end
7#include <memory> // for unique_ptr, make_unique
8#include <utility> // for move
9#include <vector> // for vector, __alloc_traits<>::value_type
10
11#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse, CapturedMouseInterface
13#include "ftxui/component/component_base.hpp" // for ComponentBase, Components
14#include "ftxui/component/event.hpp" // for Event
15#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
16#include "ftxui/dom/elements.hpp" // for text, Element
17#include "ftxui/dom/node.hpp" // for Node, Elements
18#include "ftxui/screen/box.hpp" // for Box
19
20namespace ftxui::animation {
21class Params;
22} // namespace ftxui::animation
23
24namespace ftxui {
25
26namespace {
27class CaptureMouseImpl : public CapturedMouseInterface {};
28} // namespace
29
33
34/// @brief 親のComponentBaseを返します。存在しない場合はnullを返します。
35/// @see Detach
36/// @see Parent
38 return parent_;
39}
40
41/// @brief インデックス`i`の子にアクセスします。
43 assert(i < ChildCount()); // NOLINT
44 return children_[i];
45}
46
47/// @brief 子の数を返します。
49 return children_.size();
50}
51
52/// @brief 親におけるコンポーネントのインデックスを返します。親がない場合は-1を返します。
54 if (parent_ == nullptr) {
55 return -1;
56 }
57 int index = 0;
58 for (const Component& child : parent_->children_) {
59 if (child.get() == this) {
60 return index;
61 }
62 index++;
63 }
64 return -1; // Not reached.
65}
66
67/// @brief 子を追加します。
68/// @@param child 添付する子。
70 child->Detach();
71 child->parent_ = this;
72 children_.push_back(std::move(child));
73}
74
75/// @brief この子を親からデタッチします。
76/// @see Detach
77/// @see Parent
79 if (parent_ == nullptr) {
80 return;
81 }
82 auto it = std::find_if(std::begin(parent_->children_), //
83 std::end(parent_->children_), //
84 [this](const Component& that) { //
85 return this == that.get();
86 });
87 ComponentBase* parent = parent_;
88 parent_ = nullptr;
89 parent->children_.erase(it); // Might delete |this|.
90}
91
92/// @brief すべての子を削除します。
94 while (!children_.empty()) {
95 children_[0]->Detach();
96 }
97}
98
99/// @brief コンポーネントを描画します。
100/// このftxui::ComponentBaseを表すftxui::Screen上に描画されるftxui::Elementを構築します。レンダリングを変更するにはOnRender()をオーバーライドしてください。
102 // Some users might call `ComponentBase::Render()` from
103 // `T::OnRender()`. To avoid infinite recursion, we use a flag.
104 if (in_render) {
106 }
107
108 in_render = true;
109 Element element = OnRender();
110 in_render = false;
111
112 class Wrapper : public Node {
113 public:
114 bool active_ = false;
115
116 Wrapper(Element child, bool active)
117 : Node({std::move(child)}), active_(active) {}
118
119 void SetBox(Box box) override {
120 Node::SetBox(box);
121 children_[0]->SetBox(box);
122 }
123
124 void ComputeRequirement() override {
125 Node::ComputeRequirement();
126 requirement_.focused.component_active = active_;
127 }
128 };
129
130 return std::make_shared<Wrapper>(std::move(element), Active());
131}
132
133/// @brief コンポーネントを描画します。
134/// このftxui::ComponentBaseを表すftxui::Screen上に描画されるftxui::Elementを構築します。この関数はオーバーライドされることを意図しています。
136 if (children_.size() == 1) {
137 return children_.front()->Render();
138 }
139
140 return text("Not implemented component");
141}
142
143/// @brief イベントに応じて呼び出されます。
144/// @param event イベント。
145/// @return イベントが処理された場合はtrue。
146/// デフォルトの実装では、いずれかの子がtrueを返すまで、すべての子でOnEventを呼び出します。どれもtrueを返さない場合は、falseを返します。
147bool ComponentBase::OnEvent(Event event) { // NOLINT
148 for (Component& child : children_) { // NOLINT
149 if (child->OnEvent(event)) {
150 return true;
151 }
152 }
153 return false;
154}
155
156/// @brief アニメーションイベントに応じて呼び出されます。
157/// @param params アニメーションのパラメータ
158/// デフォルトの実装では、イベントをすべての子にディスパッチします。
160 for (const Component& child : children_) {
161 child->OnAnimation(params);
162 }
163}
164
165/// @brief 現在アクティブな子を返します。
166/// @return 現在アクティブな子。
168 for (auto& child : children_) {
169 if (child->Focusable()) {
170 return child;
171 }
172 }
173 return nullptr;
174}
175
176/// @brief コンポーネントがフォーカス可能な要素を含んでいる場合にtrueを返します。
177/// フォーカス不可能なコンポーネントは、キーボードでナビゲートする際にスキップされます。
179 for (const Component& child : children_) { // NOLINT
180 if (child->Focusable()) {
181 return true;
182 }
183 }
184 return false;
185}
186
187/// @brief 要素が現在親のアクティブな子であるかどうかを返します。
189 return parent_ == nullptr || parent_->ActiveChild().get() == this;
190}
191
192/// @brief 要素がユーザーによってフォーカスされているかどうかを返します。
193/// ComponentBaseがユーザーによってフォーカスされている場合にtrueを返します。要素は、そのすべての子孫が親のActiveChild()であり、かつFocusable()である場合にフォーカスされます。
195 const auto* current = this;
196 while (current && current->Active()) {
197 current = current->parent_;
198 }
199 return !current && Focusable();
200}
201
202/// @brief |child|を「アクティブ」にします。
203/// @param child アクティブにする子。
204
205/// @brief |child|を「アクティブ」にします。
206/// @param child アクティブにする子。
208 SetActiveChild(child.get());
209}
210
211/// @brief このコンポーネントにフォーカスを与えるように、すべての祖先を設定します。
213 ComponentBase* child = this;
214 while (ComponentBase* parent = child->parent_) {
215 parent->SetActiveChild(child);
216 child = parent;
217 }
218}
219
220/// @brief 利用可能であればCapturedMouseを取得します。コンポーネントは1つしかありません。これは他のコンポーネントよりも優先されるコンポーネントを表します。
221/// @param event イベント
223 if (event.screen_) {
224 return event.screen_->CaptureMouse();
225 }
226 return std::make_unique<CaptureMouseImpl>();
227}
228
229} // namespace ftxui
virtual bool Focusable() const
コンポーネントがフォーカス可能な要素を含んでいる場合にtrueを返します。 フォーカス不可能なコンポーネントは、キーボードでナビゲートする際にスキップされます。
bool Focused() const
要素がユーザーによってフォーカスされているかどうかを返します。 ComponentBaseがユーザーによってフォーカスされている場合にtrueを返します。要素は、そのすべての子孫が親のActiveChi...
CapturedMouse CaptureMouse(const Event &event)
利用可能であればCapturedMouseを取得します。コンポーネントは1つしかありません。これは他のコンポーネントよりも優先されるコンポーネントを表します。
void Add(Component children)
子を追加します。 @param child 添付する子。
Definition component.cpp:69
Element Render()
コンポーネントを描画します。 このftxui::ComponentBaseを表すftxui::Screen上に描画されるftxui::Elementを構築します。レンダリングを変更するにはOnRende...
void TakeFocus()
このコンポーネントにフォーカスを与えるように、すべての祖先を設定します。
bool Active() const
要素が現在親のアクティブな子であるかどうかを返します。
ScreenInteractive * screen_
Definition event.hpp:123
virtual Component ActiveChild()
現在アクティブな子を返します。
void DetachAllChildren()
すべての子を削除します。
Definition component.cpp:93
int Index() const
親におけるコンポーネントのインデックスを返します。親がない場合は-1を返します。
Definition component.cpp:53
size_t ChildCount() const
子の数を返します。
Definition component.cpp:48
ComponentBase * Parent() const
親のComponentBaseを返します。存在しない場合はnullを返します。
Definition component.cpp:37
virtual void SetActiveChild(ComponentBase *child)
virtual Element OnRender()
コンポーネントを描画します。 このftxui::ComponentBaseを表すftxui::Screen上に描画されるftxui::Elementを構築します。この関数はオーバーライドされることを意図...
virtual bool OnEvent(Event)
イベントに応じて呼び出されます。
void Detach()
この子を親からデタッチします。
Definition component.cpp:78
Component & ChildAt(size_t i)
インデックスiの子にアクセスします。
Definition component.cpp:42
virtual ~ComponentBase()
Definition component.cpp:30
virtual void OnAnimation(animation::Params &params)
アニメーションイベントに応じて呼び出されます。
ftxui::Elementとして自身のレンダリングを実装します。ftxui::Eventに応答してキーボードナビゲーションを実装します。
イベントを表します。キープレスイベント、ターミナルのリサイズなど、さまざまなイベントがあります。
Definition event.hpp:28
NodeはDOMツリー内のすべての要素の基底クラスです。
Definition node.hpp:36
Element text(std::wstring text)
ユニコードテキストを表示します。
Definition text.cpp:160
Boxは、2D空間における矩形領域を表す構造体です。
Definition box.hpp:14
FTXUIのftxui::animation::名前空間。
Definition animation.hpp:9
FTXUI ftxui:: 名前空間
Definition animation.hpp:9
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< Node > Element
Definition elements.hpp:21
std::shared_ptr< ComponentBase > Component