mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-18 17:18:08 +08:00
Make component more functionnal
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
#include <algorithm> // for find_if
|
||||
#include <ext/alloc_traits.h> // for __alloc_traits<>::value_type
|
||||
#include <iterator> // for begin, end
|
||||
#include <utility> // for move
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse, CapturedMouseInterface
|
||||
#include "ftxui/component/component.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp"
|
||||
#include "ftxui/component/event.hpp"
|
||||
#include "ftxui/component/screen_interactive.hpp"
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
|
||||
#include "ftxui/component/event.hpp" // for Event
|
||||
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for text, Element
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
@@ -13,33 +17,35 @@ class CaptureMouseImpl : public CapturedMouseInterface {
|
||||
public:
|
||||
~CaptureMouseImpl() override {}
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Component::~Component() {
|
||||
ComponentBase::~ComponentBase() {
|
||||
Detach();
|
||||
}
|
||||
|
||||
/// @brief Return the parent Component, or nul if any.
|
||||
/// @brief Return the parent ComponentBase, or nul if any.
|
||||
/// @see Attach
|
||||
/// @see Detach
|
||||
/// @see Parent
|
||||
/// @ingroup component
|
||||
Component* Component::Parent() {
|
||||
ComponentBase* ComponentBase::Parent() {
|
||||
return parent_;
|
||||
}
|
||||
|
||||
/// @brief Add a children.
|
||||
/// @@param child The child to be attached.
|
||||
/// @ingroup component
|
||||
void Component::Add(Component* child) {
|
||||
child->Attach(this);
|
||||
void ComponentBase::Add(Component child) {
|
||||
child->Detach();
|
||||
child->parent_ = this;
|
||||
children_.push_back(std::move(child));
|
||||
}
|
||||
|
||||
/// @brief Draw the component.
|
||||
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
|
||||
/// ftxui::Component.
|
||||
/// ftxui::ComponentBase.
|
||||
/// @ingroup component
|
||||
Element Component::Render() {
|
||||
Element ComponentBase::Render() {
|
||||
if (children_.size() == 1)
|
||||
return children_.front()->Render();
|
||||
|
||||
@@ -52,8 +58,8 @@ Element Component::Render() {
|
||||
/// The default implementation called OnEvent on every child until one return
|
||||
/// true. If none returns true, return false.
|
||||
/// @ingroup component
|
||||
bool Component::OnEvent(Event event) {
|
||||
for (Component* child : children_) {
|
||||
bool ComponentBase::OnEvent(Event event) {
|
||||
for (Component& child : children_) {
|
||||
if (child->OnEvent(event))
|
||||
return true;
|
||||
}
|
||||
@@ -63,27 +69,27 @@ bool Component::OnEvent(Event event) {
|
||||
/// @brief Return the currently Active child.
|
||||
/// @return the currently Active child.
|
||||
/// @ingroup component
|
||||
Component* Component::ActiveChild() {
|
||||
Component ComponentBase::ActiveChild() {
|
||||
return children_.empty() ? nullptr : children_.front();
|
||||
}
|
||||
|
||||
/// @brief Returns if the element if the currently active child of its parent.
|
||||
/// @ingroup component
|
||||
bool Component::Active() {
|
||||
return !parent_ || parent_->ActiveChild() == this;
|
||||
bool ComponentBase::Active() {
|
||||
return !parent_ || parent_->ActiveChild().get() == this;
|
||||
}
|
||||
|
||||
/// @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.
|
||||
/// True when the ComponentBase is focused by the user. An element is Focused
|
||||
/// when it is with all its ancestors the ActiveChild() of their parents.
|
||||
/// @ingroup component
|
||||
bool Component::Focused() {
|
||||
Component* current = this;
|
||||
bool ComponentBase::Focused() {
|
||||
ComponentBase* current = this;
|
||||
for (;;) {
|
||||
Component* parent = current->parent_;
|
||||
ComponentBase* parent = current->parent_;
|
||||
if (!parent)
|
||||
return true;
|
||||
if (parent->ActiveChild() != current)
|
||||
if (parent->ActiveChild().get() != current)
|
||||
return false;
|
||||
current = parent;
|
||||
}
|
||||
@@ -92,13 +98,20 @@ bool Component::Focused() {
|
||||
/// @brief Make the |child| to be the "active" one.
|
||||
/// @argument child the child to become active.
|
||||
/// @ingroup component
|
||||
void Component::SetActiveChild(Component*) {}
|
||||
void ComponentBase::SetActiveChild(ComponentBase*) {}
|
||||
|
||||
/// @brief Make the |child| to be the "active" one.
|
||||
/// @argument child the child to become active.
|
||||
/// @ingroup component
|
||||
void ComponentBase::SetActiveChild(Component child) {
|
||||
SetActiveChild(child.get());
|
||||
}
|
||||
|
||||
/// @brief Configure all the ancestors to give focus to this component.
|
||||
/// @ingroup component
|
||||
void Component::TakeFocus() {
|
||||
Component* child = this;
|
||||
Component* parent = parent_;
|
||||
void ComponentBase::TakeFocus() {
|
||||
ComponentBase* child = this;
|
||||
ComponentBase* parent = parent_;
|
||||
while (parent) {
|
||||
parent->SetActiveChild(child);
|
||||
child = parent;
|
||||
@@ -110,7 +123,7 @@ void Component::TakeFocus() {
|
||||
/// them. It represents a component taking priority over others.
|
||||
/// @argument event
|
||||
/// @ingroup component
|
||||
CapturedMouse Component::CaptureMouse(const Event& event) {
|
||||
CapturedMouse ComponentBase::CaptureMouse(const Event& event) {
|
||||
if (!event.screen_)
|
||||
return std::make_unique<CaptureMouseImpl>();
|
||||
return event.screen_->CaptureMouse();
|
||||
@@ -121,25 +134,17 @@ CapturedMouse Component::CaptureMouse(const Event& event) {
|
||||
/// @see Detach
|
||||
/// @see Parent
|
||||
/// @ingroup component
|
||||
void Component::Detach() {
|
||||
void ComponentBase::Detach() {
|
||||
if (!parent_)
|
||||
return;
|
||||
auto it = std::find(std::begin(parent_->children_),
|
||||
std::end(parent_->children_), this);
|
||||
auto it = std::find_if(std::begin(parent_->children_), //
|
||||
std::end(parent_->children_), //
|
||||
[this](const Component& that) { //
|
||||
return this == that.get();
|
||||
});
|
||||
parent_->children_.erase(it);
|
||||
}
|
||||
|
||||
/// @brief Attach this element to its parent.
|
||||
/// @see Attach
|
||||
/// @see Detach
|
||||
/// @see Parent
|
||||
/// @ingroup component
|
||||
void Component::Attach(Component* parent) {
|
||||
Detach();
|
||||
parent_ = parent;
|
||||
parent_->children_.push_back(this);
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
Reference in New Issue
Block a user