FTXUI  3.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
component.cpp
Go to the documentation of this file.
1#include <algorithm> // for find_if
2#include <cassert> // for assert
3#include <cstddef> // for size_t
4#include <iterator> // for begin, end
5#include <utility> // for move
6#include <vector> // for vector, __alloc_traits<>::value_type
7
8#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse, CapturedMouseInterface
10#include "ftxui/component/component_base.hpp" // for ComponentBase, Components
11#include "ftxui/component/event.hpp" // for Event
12#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
13#include "ftxui/dom/elements.hpp" // for text, Element
14
15namespace ftxui::animation {
16class Params;
17} // namespace ftxui::animation
18
19namespace ftxui {
20
21namespace {
22class CaptureMouseImpl : public CapturedMouseInterface {};
23} // namespace
24
28
29/// @brief Return the parent ComponentBase, or nul if any.
30/// @see Detach
31/// @see Parent
32/// @ingroup component
34 return parent_;
35}
36
37/// @brief Access the child at index `i`.
38/// @ingroup component
40 assert(i < ChildCount()); // NOLINT
41 return children_[i];
42}
43
44/// @brief Returns the number of children.
45/// @ingroup component
47 return children_.size();
48}
49
50/// @brief Add a child.
51/// @@param child The child to be attached.
52/// @ingroup component
54 child->Detach();
55 child->parent_ = this;
56 children_.push_back(std::move(child));
57}
58
59/// @brief Detach this child from its parent.
60/// @see Detach
61/// @see Parent
62/// @ingroup component
64 if (parent_ == nullptr) {
65 return;
66 }
67 auto it = std::find_if(std::begin(parent_->children_), //
68 std::end(parent_->children_), //
69 [this](const Component& that) { //
70 return this == that.get();
71 });
72 ComponentBase* parent = parent_;
73 parent_ = nullptr;
74 parent->children_.erase(it); // Might delete |this|.
75}
76
77/// @brief Remove all children.
78/// @ingroup component
80 while (!children_.empty()) {
81 children_[0]->Detach();
82 }
83}
84
85/// @brief Draw the component.
86/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
87/// ftxui::ComponentBase.
88/// @ingroup component
90 if (children_.size() == 1) {
91 return children_.front()->Render();
92 }
93
94 return text("Not implemented component");
95}
96
97/// @brief Called in response to an event.
98/// @param event The event.
99/// @return True when the event has been handled.
100/// The default implementation called OnEvent on every child until one return
101/// true. If none returns true, return false.
102/// @ingroup component
103bool ComponentBase::OnEvent(Event event) { // NOLINT
104 for (Component& child : children_) { // NOLINT
105 if (child->OnEvent(event)) {
106 return true;
107 }
108 }
109 return false;
110}
111
112/// @brief Called in response to an animation event.
113/// @param animation_params the parameters of the animation
114/// The default implementation dispatch the event to every child.
115/// @ingroup component
117 for (Component& child : children_) {
118 child->OnAnimation(params);
119 }
120}
121
122/// @brief Return the currently Active child.
123/// @return the currently Active child.
124/// @ingroup component
126 for (auto& child : children_) {
127 if (child->Focusable()) {
128 return child;
129 }
130 }
131 return nullptr;
132}
133
134/// @brief Return true when the component contains focusable elements.
135/// The non focusable Components will be skipped when navigating using the
136/// keyboard.
137/// @ingroup component
139 for (const Component& child : children_) { // NOLINT
140 if (child->Focusable()) {
141 return true;
142 }
143 }
144 return false;
145}
146
147/// @brief Returns if the element if the currently active child of its parent.
148/// @ingroup component
150 return parent_ == nullptr || parent_->ActiveChild().get() == this;
151}
152
153/// @brief Returns if the elements if focused by the user.
154/// True when the ComponentBase is focused by the user. An element is Focused
155/// when it is with all its ancestors the ActiveChild() of their parents, and it
156/// Focusable().
157/// @ingroup component
159 const auto* current = this;
160 while (current && current->Active()) {
161 current = current->parent_;
162 }
163 return !current && Focusable();
164}
165
166/// @brief Make the |child| to be the "active" one.
167/// @param child the child to become active.
168/// @ingroup component
170
171/// @brief Make the |child| to be the "active" one.
172/// @param child the child to become active.
173/// @ingroup component
175 SetActiveChild(child.get());
176}
177
178/// @brief Configure all the ancestors to give focus to this component.
179/// @ingroup component
181 ComponentBase* child = this;
182 while (ComponentBase* parent = child->parent_) {
183 parent->SetActiveChild(child);
184 child = parent;
185 }
186}
187
188/// @brief Take the CapturedMouse if available. There is only one component of
189/// them. It represents a component taking priority over others.
190/// @param event
191/// @ingroup component
193 if (event.screen_) {
194 return event.screen_->CaptureMouse();
195 }
196 return std::make_unique<CaptureMouseImpl>();
197}
198
199} // namespace ftxui
200
201// Copyright 2020 Arthur Sonzogni. All rights reserved.
202// Use of this source code is governed by the MIT license that can be found in
203// the LICENSE file.
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:53
virtual Element Render()
Draw the component. Build a ftxui::Element to be drawn on the ftxi::Screen representing this ftxui::C...
Definition component.cpp:89
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:79
virtual void SetActiveChild(ComponentBase *child)
Make the |child| to be the "active" one.
size_t ChildCount() const
Returns the number of children.
Definition component.cpp:46
ComponentBase * Parent() const
Return the parent ComponentBase, or nul if any.
Definition component.cpp:33
virtual bool OnEvent(Event)
Called in response to an event.
void Detach()
Detach this child from its parent.
Definition component.cpp:63
Component & ChildAt(size_t i)
Access the child at index i.
Definition component.cpp:39
virtual ~ComponentBase()
Definition component.cpp:25
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:18
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:111
std::shared_ptr< ComponentBase > Component
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:26
ScreenInteractive * screen_
Definition event.hpp:78