28class CaptureMouseImpl :
public CapturedMouseInterface {};
31struct ComponentBase::Impl {
33 ComponentBase* parent =
nullptr;
34 bool in_render =
false;
37ComponentBase::ComponentBase() : impl_(std::make_unique<Impl>()) {}
39ComponentBase::ComponentBase(Components children)
40 : impl_(std::make_unique<Impl>()) {
41 impl_->children = std::move(children);
44ComponentBase::~ComponentBase() {
49 return impl_->children;
52const Components& ComponentBase::children()
const {
53 return impl_->children;
59ComponentBase* ComponentBase::Parent()
const {
64Component& ComponentBase::ChildAt(
size_t i) {
65 assert(i < ChildCount());
66 return impl_->children[i];
70size_t ComponentBase::ChildCount()
const {
71 return impl_->children.size();
75int ComponentBase::Index()
const {
76 if (impl_->parent ==
nullptr) {
80 for (
const Component& child : impl_->parent->impl_->children) {
81 if (child.get() ==
this) {
91void ComponentBase::Add(Component child) {
93 child->impl_->parent =
this;
94 impl_->children.push_back(std::move(child));
100void ComponentBase::Detach() {
101 if (impl_->parent ==
nullptr) {
104 auto it = std::find_if(std::begin(impl_->parent->impl_->children),
105 std::end(impl_->parent->impl_->children),
106 [
this](
const Component& that) {
107 return this == that.get();
109 ComponentBase* parent = impl_->parent;
110 impl_->parent =
nullptr;
111 parent->impl_->children.erase(it);
115void ComponentBase::DetachAllChildren() {
116 while (!impl_->children.empty()) {
117 impl_->children[0]->Detach();
124Element ComponentBase::Render() {
127 if (impl_->in_render) {
128 return ComponentBase::OnRender();
131 impl_->in_render =
true;
133 impl_->in_render =
false;
135 class Wrapper :
public Node {
137 bool active_ =
false;
138 bool focused_ =
false;
140 Wrapper(Element child,
bool active,
bool focused)
141 : Node({std::move(child)}), active_(active), focused_(focused) {}
143 void SetBox(Box box)
override {
145 children_[0]->SetBox(box);
148 void ComputeRequirement()
override {
149 Node::ComputeRequirement();
150 requirement_.focused.component_active = active_;
151 requirement_.focused.component_focused = focused_;
155 return std::make_shared<Wrapper>(std::move(element), Active(), Focused());
161Element ComponentBase::OnRender() {
162 if (impl_->children.size() == 1) {
163 return impl_->children.front()->Render();
166 return text(
"Not implemented component");
174bool ComponentBase::OnEvent(Event event) {
175 for (Component& child : impl_->children) {
176 if (child->OnEvent(event)) {
186void ComponentBase::OnAnimation(animation::Params& params) {
187 for (
const Component& child : impl_->children) {
188 child->OnAnimation(params);
195 for (
auto& child : impl_->children) {
196 if (child->Focusable()) {
206bool ComponentBase::Focusable()
const {
207 for (
const Component& child : impl_->children) {
208 if (child->Focusable()) {
216bool ComponentBase::Active()
const {
217 return impl_->parent ==
nullptr || impl_->parent->ActiveChild().get() ==
this;
224bool ComponentBase::Focused()
const {
225 const auto* current =
this;
226 while (current && current->Active()) {
227 current = current->impl_->parent;
229 return !current && Focusable();
234void ComponentBase::SetActiveChild([[maybe_unused]] ComponentBase* child) {}
238void ComponentBase::SetActiveChild(Component child) {
239 SetActiveChild(child.get());
243void ComponentBase::TakeFocus() {
244 ComponentBase* child =
this;
245 while (ComponentBase* parent = child->impl_->parent) {
246 parent->SetActiveChild(child);
254CapturedMouse ComponentBase::CaptureMouse(
const Event& event) {
256 return event.screen_->CaptureMouse();
258 return std::make_unique<CaptureMouseImpl>();
The FTXUI ftxui:: namespace.
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< Node > Element
std::vector< Component > Components
std::shared_ptr< ComponentBase > Component