mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-29 14:45:53 +08:00
Allows components to remove a child or access to children in general (#152)
Allows components to remove a child or access to children in general. Co-authored-by: Felix Heitmann <fheitmann@se-gpu-03.intern.plath.de> Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
parent
23789c2d7b
commit
c34494ce26
@ -26,9 +26,13 @@ class ComponentBase {
|
|||||||
ComponentBase() = default;
|
ComponentBase() = default;
|
||||||
virtual ~ComponentBase();
|
virtual ~ComponentBase();
|
||||||
|
|
||||||
// ComponentBase hierarchy.
|
// Component hierarchy:
|
||||||
ComponentBase* Parent();
|
ComponentBase* Parent();
|
||||||
|
Component& ChildAt(size_t i);
|
||||||
|
size_t ChildCount() const;
|
||||||
void Add(Component children);
|
void Add(Component children);
|
||||||
|
void Detach();
|
||||||
|
void DetachAllChildren();
|
||||||
|
|
||||||
// Renders the component.
|
// Renders the component.
|
||||||
virtual Element Render();
|
virtual Element Render();
|
||||||
@ -67,7 +71,6 @@ class ComponentBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ComponentBase* parent_ = nullptr;
|
ComponentBase* parent_ = nullptr;
|
||||||
void Detach();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using Component = std::shared_ptr<ComponentBase>;
|
using Component = std::shared_ptr<ComponentBase>;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
#include <stddef.h> // for size_t
|
||||||
#include <algorithm> // for find_if, max
|
#include <algorithm> // for find_if, max
|
||||||
|
#include <cassert> // for assert
|
||||||
#include <iterator> // for begin, end
|
#include <iterator> // for begin, end
|
||||||
#include <utility> // for move
|
#include <utility> // for move
|
||||||
|
|
||||||
@ -24,7 +26,6 @@ ComponentBase::~ComponentBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Return the parent ComponentBase, or nul if any.
|
/// @brief Return the parent ComponentBase, or nul if any.
|
||||||
/// @see Attach
|
|
||||||
/// @see Detach
|
/// @see Detach
|
||||||
/// @see Parent
|
/// @see Parent
|
||||||
/// @ingroup component
|
/// @ingroup component
|
||||||
@ -32,7 +33,20 @@ ComponentBase* ComponentBase::Parent() {
|
|||||||
return parent_;
|
return parent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Add a children.
|
/// @brief Access the child at index `i`.
|
||||||
|
/// @ingroup component
|
||||||
|
Component& ComponentBase::ChildAt(size_t i) {
|
||||||
|
assert(i < ChildCount());
|
||||||
|
return children_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns the number of children.
|
||||||
|
/// @ingroup component
|
||||||
|
size_t ComponentBase::ChildCount() const {
|
||||||
|
return children_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Add a child.
|
||||||
/// @@param child The child to be attached.
|
/// @@param child The child to be attached.
|
||||||
/// @ingroup component
|
/// @ingroup component
|
||||||
void ComponentBase::Add(Component child) {
|
void ComponentBase::Add(Component child) {
|
||||||
@ -41,6 +55,29 @@ void ComponentBase::Add(Component child) {
|
|||||||
children_.push_back(std::move(child));
|
children_.push_back(std::move(child));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Detach this child from its parent.
|
||||||
|
/// @see Detach
|
||||||
|
/// @see Parent
|
||||||
|
/// @ingroup component
|
||||||
|
void ComponentBase::Detach() {
|
||||||
|
if (!parent_)
|
||||||
|
return;
|
||||||
|
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);
|
||||||
|
parent_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Remove all children.
|
||||||
|
/// @ingroup component
|
||||||
|
void ComponentBase::DetachAllChildren() {
|
||||||
|
while (!children_.empty())
|
||||||
|
children_[0]->Detach();
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Draw the component.
|
/// @brief Draw the component.
|
||||||
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
|
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
|
||||||
/// ftxui::ComponentBase.
|
/// ftxui::ComponentBase.
|
||||||
@ -129,23 +166,6 @@ CapturedMouse ComponentBase::CaptureMouse(const Event& event) {
|
|||||||
return event.screen_->CaptureMouse();
|
return event.screen_->CaptureMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Detach this children from its parent.
|
|
||||||
/// @see Attach
|
|
||||||
/// @see Detach
|
|
||||||
/// @see Parent
|
|
||||||
/// @ingroup component
|
|
||||||
void ComponentBase::Detach() {
|
|
||||||
if (!parent_)
|
|
||||||
return;
|
|
||||||
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);
|
|
||||||
parent_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
|
||||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include <memory> // for shared_ptr, allocator, make_shared, __shared_ptr_access
|
#include <gtest/gtest-message.h> // for Message
|
||||||
|
#include <gtest/gtest-test-part.h> // for TestPartResult
|
||||||
|
#include <memory> // for shared_ptr, __shared_ptr_access, allocator, make_shared
|
||||||
|
|
||||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||||
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
|
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
|
||||||
#include "gtest/gtest_pred_impl.h" // for Test, SuiteApiResolver, TEST, TestFactoryImpl
|
#include "gtest/gtest_pred_impl.h" // for EXPECT_EQ, Test, SuiteApiResolver, TEST, TestFactoryImpl
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
@ -30,6 +32,129 @@ TEST(ContainerTest, DeleteChildFirst) {
|
|||||||
parent.reset();
|
parent.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ContainerTest, Detach) {
|
||||||
|
auto parent = Make();
|
||||||
|
auto child_1 = Make();
|
||||||
|
auto child_2 = Make();
|
||||||
|
auto child_3 = Make();
|
||||||
|
parent->Add(child_1);
|
||||||
|
parent->Add(child_2);
|
||||||
|
parent->Add(child_3);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 3u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_3->Parent(), parent.get());
|
||||||
|
|
||||||
|
child_2->Detach();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 2u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_3->Parent(), parent.get());
|
||||||
|
|
||||||
|
child_2->Detach();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 2u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_3->Parent(), parent.get());
|
||||||
|
|
||||||
|
child_1->Detach();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 1u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_3->Parent(), parent.get());
|
||||||
|
|
||||||
|
child_3->Detach();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 0u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_3->Parent(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ContainerTest, DetachAllChild) {
|
||||||
|
auto parent = Make();
|
||||||
|
auto child_1 = Make();
|
||||||
|
auto child_2 = Make();
|
||||||
|
auto child_3 = Make();
|
||||||
|
parent->Add(child_1);
|
||||||
|
parent->Add(child_2);
|
||||||
|
parent->Add(child_3);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 3u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_3->Parent(), parent.get());
|
||||||
|
|
||||||
|
parent->DetachAllChild();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 0u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_3->Parent(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ContainerTest, Add) {
|
||||||
|
auto parent = Make();
|
||||||
|
auto child_1 = Make();
|
||||||
|
auto child_2 = Make();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 0u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), nullptr);
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
|
||||||
|
parent->Add(child_1);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 1u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
|
||||||
|
parent->Add(child_1);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 1u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), nullptr);
|
||||||
|
|
||||||
|
parent->Add(child_2);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 2u);
|
||||||
|
EXPECT_EQ(child_1->Parent(), parent.get());
|
||||||
|
EXPECT_EQ(child_2->Parent(), parent.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ContainerTest, ChildAt) {
|
||||||
|
auto parent = Make();
|
||||||
|
auto child_1 = Make();
|
||||||
|
auto child_2 = Make();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 0u);
|
||||||
|
|
||||||
|
parent->Add(child_1);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 1u);
|
||||||
|
EXPECT_EQ(parent->ChildAt(0u), child_1);
|
||||||
|
|
||||||
|
parent->Add(child_2);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 2u);
|
||||||
|
EXPECT_EQ(parent->ChildAt(0u), child_1);
|
||||||
|
EXPECT_EQ(parent->ChildAt(1u), child_2);
|
||||||
|
|
||||||
|
parent->Add(child_1);
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 2u);
|
||||||
|
EXPECT_EQ(parent->ChildAt(0u), child_2);
|
||||||
|
EXPECT_EQ(parent->ChildAt(1u), child_1);
|
||||||
|
|
||||||
|
child_1->Detach();
|
||||||
|
|
||||||
|
EXPECT_EQ(parent->ChildCount(), 1u);
|
||||||
|
EXPECT_EQ(parent->ChildAt(0u), child_2);
|
||||||
|
}
|
||||||
|
|
||||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||||
// Use of this source code is governed by the MIT license that can be found in
|
// Use of this source code is governed by the MIT license that can be found in
|
||||||
// the LICENSE file.
|
// the LICENSE file.
|
||||||
|
Loading…
Reference in New Issue
Block a user