FTXUI  5.0.0
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// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
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
19namespace ftxui::animation {
20class Params;
21} // namespace ftxui::animation
22
23namespace ftxui {
24
25namespace {
26class CaptureMouseImpl : public CapturedMouseInterface {};
27} // namespace
28
32
33/// @brief Return the parent ComponentBase, or nul if any.
34/// @see Detach
35/// @see Parent
36/// @ingroup component
38 return parent_;
39}
40
41/// @brief Access the child at index `i`.
42/// @ingroup component
44 assert(i < ChildCount()); // NOLINT
45 return children_[i];
46}
47
48/// @brief Returns the number of children.
49/// @ingroup component
51 return children_.size();
52}
53
54/// @brief Return index of the component in its parent. -1 if no parent.
55/// @ingroup component
57 if (parent_ == nullptr) {
58 return -1;
59 }
60 int index = 0;
61 for (const Component& child : parent_->children_) {
62 if (child.get() == this) {
63 return index;
64 }
65 index++;
66 }
67 return -1; // Not reached.
68}
69
70/// @brief Add a child.
71/// @@param child The child to be attached.
72/// @ingroup component
74 child->Detach();
75 child->parent_ = this;
76 children_.push_back(std::move(child));
77}
78
79/// @brief Detach this child from its parent.
80/// @see Detach
81/// @see Parent
82/// @ingroup component
84 if (parent_ == nullptr) {
85 return;
86 }
87 auto it = std::find_if(std::begin(parent_->children_), //
88 std::end(parent_->children_), //
89 [this](const Component& that) { //
90 return this == that.get();
91 });
92 ComponentBase* parent = parent_;
93 parent_ = nullptr;
94 parent->children_.erase(it); // Might delete |this|.
95}
96
97/// @brief Remove all children.
98/// @ingroup component
100 while (!children_.empty()) {
101 children_[0]->Detach();
102 }
103}
104
105/// @brief Draw the component.
106/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
107/// ftxui::ComponentBase.
108/// @ingroup component
110 if (children_.size() == 1) {
111 return children_.front()->Render();
112 }
113
114 return text("Not implemented component");
115}
116
117/// @brief Called in response to an event.
118/// @param event The event.
119/// @return True when the event has been handled.
120/// The default implementation called OnEvent on every child until one return
121/// true. If none returns true, return false.
122/// @ingroup component
124 for (Component& child : children_) { // NOLINT
125 if (child->OnEvent(event)) {
126 return true;
127 }
128 }
129 return false;
130}
131
132/// @brief Called in response to an animation event.
133/// @param params the parameters of the animation
134/// The default implementation dispatch the event to every child.
135/// @ingroup component
137 for (const Component& child : children_) {
138 child->OnAnimation(params);
139 }
140}
141
142/// @brief Return the currently Active child.
143/// @return the currently Active child.
144/// @ingroup component
146 for (auto& child : children_) {
147 if (child->Focusable()) {
148 return child;
149 }
150 }
151 return nullptr;
152}
153
154/// @brief Return true when the component contains focusable elements.
155/// The non focusable Components will be skipped when navigating using the
156/// keyboard.
157/// @ingroup component
159 for (const Component& child : children_) { // NOLINT
160 if (child->Focusable()) {
161 return true;
162 }
163 }
164 return false;
165}
166
167/// @brief Returns if the element if the currently active child of its parent.
168/// @ingroup component
170 return parent_ == nullptr || parent_->ActiveChild().get() == this;
171}
172
173/// @brief Returns if the elements if focused by the user.
174/// True when the ComponentBase is focused by the user. An element is Focused
175/// when it is with all its ancestors the ActiveChild() of their parents, and it
176/// Focusable().
177/// @ingroup component
179 const auto* current = this;
180 while (current && current->Active()) {
181 current = current->parent_;
182 }
183 return !current && Focusable();
184}
185
186/// @brief Make the |child| to be the "active" one.
187/// @param child the child to become active.
188/// @ingroup component
190
191/// @brief Make the |child| to be the "active" one.
192/// @param child the child to become active.
193/// @ingroup component
197
198/// @brief Configure all the ancestors to give focus to this component.
199/// @ingroup component
201 ComponentBase* child = this;
202 while (ComponentBase* parent = child->parent_) {
204 child = parent;
205 }
206}
207
208/// @brief Take the CapturedMouse if available. There is only one component of
209/// them. It represents a component taking priority over others.
210/// @param event The event
211/// @ingroup component
213 if (event.screen_) {
214 return event.screen_->CaptureMouse();
215 }
216 return std::make_unique<CaptureMouseImpl>();
217}
218
219} // namespace ftxui
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
virtual bool Focusable() const
Return true when the component contains focusable elements. The non focusable Components will be skip...
bool Focused() const
Returns if the elements if focused by the user. True when the ComponentBase is focused by the user....
CapturedMouse CaptureMouse(const Event &event)
Take the CapturedMouse if available. There is only one component of them. It represents a component t...
void Add(Component children)
Add a child. @param child The child to be attached.
Definition component.cpp:73
virtual Element Render()
Draw the component. Build a ftxui::Element to be drawn on the ftxi::Screen representing this ftxui::C...
void TakeFocus()
Configure all the ancestors to give focus to this component.
bool Active() const
Returns if the element if the currently active child of its parent.
virtual Component ActiveChild()
Return the currently Active child.
void DetachAllChildren()
Remove all children.
Definition component.cpp:99
virtual void SetActiveChild(ComponentBase *child)
Make the |child| to be the "active" one.
int Index() const
Return index of the component in its parent. -1 if no parent.
Definition component.cpp:56
size_t ChildCount() const
Returns the number of children.
Definition component.cpp:50
ComponentBase * Parent() const
Return the parent ComponentBase, or nul if any.
Definition component.cpp:37
virtual bool OnEvent(Event)
Called in response to an event.
void Detach()
Detach this child from its parent.
Definition component.cpp:83
Component & ChildAt(size_t i)
Access the child at index i.
Definition component.cpp:43
virtual ~ComponentBase()
Definition component.cpp:29
virtual void OnAnimation(animation::Params &params)
Called in response to an animation event.
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
std::shared_ptr< ComponentBase > Component
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:119
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:27