2018-10-10 01:06:03 +08:00
|
|
|
#include "ftxui/component/component.hpp"
|
2020-03-23 05:32:44 +08:00
|
|
|
|
2018-10-10 01:06:03 +08:00
|
|
|
#include <assert.h>
|
|
|
|
|
2020-03-23 05:32:44 +08:00
|
|
|
#include <algorithm>
|
|
|
|
|
2019-01-12 22:00:08 +08:00
|
|
|
namespace ftxui {
|
2018-10-10 01:06:03 +08:00
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
Component::~Component() {
|
2019-01-13 01:24:46 +08:00
|
|
|
Detach();
|
|
|
|
}
|
2018-10-10 01:06:03 +08:00
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Return the parent Component, or nul if any.
|
|
|
|
/// @see Attach
|
|
|
|
/// @see Detach
|
2020-09-06 19:46:56 +08:00
|
|
|
/// @see Parent
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @ingroup component
|
|
|
|
Component* Component::Parent() {
|
|
|
|
return parent_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Add a children.
|
|
|
|
/// @@param child The child to be attached.
|
|
|
|
/// @ingroup component
|
2019-01-13 01:24:46 +08:00
|
|
|
void Component::Add(Component* child) {
|
|
|
|
child->Attach(this);
|
2018-10-10 01:06:03 +08:00
|
|
|
}
|
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Draw the component.
|
|
|
|
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
|
|
|
|
/// ftxui::Component.
|
|
|
|
/// @ingroup component
|
|
|
|
Element Component::Render() {
|
|
|
|
if (children_.size() == 1)
|
|
|
|
return children_.front()->Render();
|
|
|
|
|
|
|
|
return text(L"Not implemented component");
|
2018-10-10 01:06:03 +08:00
|
|
|
}
|
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Called in response to an event.
|
|
|
|
/// @param event The event.
|
|
|
|
/// @return True when the event has been handled.
|
|
|
|
/// The default implementation called OnEvent on every child until one return
|
|
|
|
/// true. If none returns true, return false.
|
|
|
|
/// @ingroup component
|
2019-01-13 01:24:46 +08:00
|
|
|
bool Component::OnEvent(Event event) {
|
2020-03-23 05:32:44 +08:00
|
|
|
for (Component* child : children_) {
|
2019-01-13 01:24:46 +08:00
|
|
|
if (child->OnEvent(event))
|
2018-10-10 01:06:03 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Return the currently Active child.
|
|
|
|
/// @return the currently Active child.
|
|
|
|
/// @ingroup component
|
2019-01-13 01:24:46 +08:00
|
|
|
Component* Component::ActiveChild() {
|
|
|
|
return children_.empty() ? nullptr : children_.front();
|
2018-10-10 01:06:03 +08:00
|
|
|
}
|
|
|
|
|
2020-08-26 20:57:42 +08:00
|
|
|
/// @brief Returns if the element if the currently active child of its parent.
|
|
|
|
/// @ingroup component
|
|
|
|
bool Component::Active() {
|
|
|
|
return !parent_ || parent_->ActiveChild() == this;
|
|
|
|
}
|
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Returns if the elements if focused by the user.
|
|
|
|
/// True when the Component is focused by the user. An element is Focused when
|
|
|
|
/// it is with all its ancestors the ActiveChild() of their parents.
|
2020-08-26 20:57:42 +08:00
|
|
|
/// @ingroup component
|
2019-01-13 01:24:46 +08:00
|
|
|
bool Component::Focused() {
|
|
|
|
Component* current = this;
|
2020-03-23 05:32:44 +08:00
|
|
|
for (;;) {
|
2019-01-13 01:24:46 +08:00
|
|
|
Component* parent = current->parent_;
|
|
|
|
if (!parent)
|
|
|
|
return true;
|
|
|
|
if (parent->ActiveChild() != current)
|
|
|
|
return false;
|
|
|
|
current = parent;
|
|
|
|
}
|
2018-10-10 01:06:03 +08:00
|
|
|
}
|
|
|
|
|
2020-08-26 20:57:42 +08:00
|
|
|
/// @brief Make the |child| to be the "active" one.
|
|
|
|
/// @argument child the child to become active.
|
|
|
|
/// @ingroup component
|
|
|
|
void Component::SetActiveChild(Component*) {}
|
|
|
|
|
|
|
|
/// @brief Configure all the ancestors to give focus to this component.
|
|
|
|
/// @ingroup component
|
|
|
|
void Component::TakeFocus() {
|
|
|
|
Component* child = this;
|
|
|
|
Component* parent = parent_;
|
|
|
|
while (parent) {
|
|
|
|
parent->SetActiveChild(child);
|
|
|
|
child = parent;
|
|
|
|
parent = parent->parent_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @brief Detach this children from its parent.
|
|
|
|
/// @see Attach
|
|
|
|
/// @see Detach
|
2020-09-06 19:46:56 +08:00
|
|
|
/// @see Parent
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @ingroup component
|
|
|
|
void Component::Detach() {
|
|
|
|
if (!parent_)
|
|
|
|
return;
|
|
|
|
auto it = std::find(std::begin(parent_->children_),
|
|
|
|
std::end(parent_->children_), this);
|
|
|
|
parent_->children_.erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Attach this element to its parent.
|
|
|
|
/// @see Attach
|
|
|
|
/// @see Detach
|
2020-09-06 19:46:56 +08:00
|
|
|
/// @see Parent
|
2020-08-16 08:24:50 +08:00
|
|
|
/// @ingroup component
|
|
|
|
void Component::Attach(Component* parent) {
|
|
|
|
Detach();
|
|
|
|
parent_ = parent;
|
|
|
|
parent_->children_.push_back(this);
|
|
|
|
}
|
|
|
|
|
2019-01-12 22:00:08 +08:00
|
|
|
} // namespace ftxui
|
2020-08-16 06:24:18 +08:00
|
|
|
|
|
|
|
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
|
|
|
// Use of this source code is governed by the MIT license that can be found in
|
|
|
|
// the LICENSE file.
|