Remove container.hpp

This commit is contained in:
ArthurSonzogni 2021-07-10 12:51:11 +02:00 committed by Arthur Sonzogni
parent 26db8228f9
commit 0ca7da630b
5 changed files with 176 additions and 234 deletions

View File

@ -76,7 +76,6 @@ add_library(component STATIC
include/ftxui/component/captured_mouse.hpp
include/ftxui/component/component.hpp
include/ftxui/component/component_base.hpp
include/ftxui/component/container.hpp
include/ftxui/component/event.hpp
include/ftxui/component/menu.hpp
include/ftxui/component/mouse.hpp

View File

@ -1,61 +0,0 @@
#ifndef FTXUI_COMPONENT_CONTAINER_HPP
#define FTXUI_COMPONENT_CONTAINER_HPP
#include "ftxui/component/component.hpp" // for Component, Components
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/event.hpp" // for Event
#include "ftxui/dom/elements.hpp" // for Element
namespace ftxui {
/// @brief A component where focus and events are automatically handled for you.
class ContainerBase : public ComponentBase {
public:
static Component Vertical();
static Component Vertical(Components children);
static Component Vertical(Components children, int* selector);
static Component Horizontal();
static Component Horizontal(Components children);
static Component Horizontal(Components children, int* selector);
static Component Tab(int* selector);
static Component Tab(Components children, int* selector);
~ContainerBase() override = default;
// Component override.
bool OnEvent(Event event) override;
Element Render() override;
Component ActiveChild() override;
virtual void SetActiveChild(ComponentBase*) override;
protected:
// Handlers
using EventHandler = bool (ContainerBase::*)(Event);
bool VerticalEvent(Event event);
bool HorizontalEvent(Event event);
bool TabEvent(Event) { return false; }
EventHandler event_handler_;
using RenderHandler = Element (ContainerBase::*)();
Element VerticalRender();
Element HorizontalRender();
Element TabRender();
RenderHandler render_handler_;
int selected_ = 0;
int* selector_ = nullptr;
bool is_tab_ = false;
private:
bool OnMouseEvent(Event event);
};
} // namespace ftxui
#endif /* end of include guard: FTXUI_COMPONENT_CONTAINER_HPP */
// 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.

View File

@ -5,10 +5,169 @@
#include <utility> // for move
#include <vector> // for vector, __alloc_traits<>::value_type
#include "ftxui/component/container.hpp"
#include "ftxui/component/component.hpp"
#include "ftxui/component/event.hpp"
namespace ftxui {
/// @brief A component where focus and events are automatically handled for you.
class ContainerBase : public ComponentBase {
public:
static Component Vertical() { return Vertical({}); }
static Component Vertical(Components children) {
return Vertical(std::move(children), /*selector=*/nullptr);
}
static Component Vertical(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->event_handler_ = &ContainerBase::VerticalEvent;
container->render_handler_ = &ContainerBase::VerticalRender;
container->selector_ = selector ? selector : &container->selected_;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
static Component Horizontal() { return Horizontal({}); }
static Component Horizontal(Components children) {
return Horizontal(std::move(children), /*selector=*/nullptr);
}
static Component Horizontal(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->event_handler_ = &ContainerBase::HorizontalEvent;
container->render_handler_ = &ContainerBase::HorizontalRender;
container->selector_ = selector ? selector : &container->selected_;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
static Component Tab(int* selector) { return Tab({}, selector); }
static Component Tab(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->selector_ = selector ? selector : &container->selected_;
container->event_handler_ = &ContainerBase::TabEvent;
container->render_handler_ = &ContainerBase::TabRender;
container->is_tab_ = true;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
~ContainerBase() override = default;
// Component override.
bool OnEvent(Event event) override {
if (event.is_mouse())
return OnMouseEvent(event);
if (!Focused())
return false;
if (ActiveChild() && ActiveChild()->OnEvent(event))
return true;
return (this->*event_handler_)(event);
}
Component ActiveChild() override {
if (children_.size() == 0)
return nullptr;
return children_[*selector_ % children_.size()];
}
void SetActiveChild(ComponentBase* child) override {
for (size_t i = 0; i < children_.size(); ++i) {
if (children_[i].get() == child) {
*selector_ = i;
return;
}
}
}
private:
// Handlers
bool VerticalEvent(Event event) {
int old_selected = *selector_;
if (event == Event::ArrowUp || event == Event::Character('k'))
(*selector_)--;
if (event == Event::ArrowDown || event == Event::Character('j'))
(*selector_)++;
if (event == Event::Tab && children_.size())
*selector_ = (*selector_ + 1) % children_.size();
if (event == Event::TabReverse && children_.size())
*selector_ = (*selector_ + children_.size() - 1) % children_.size();
*selector_ = std::max(0, std::min(int(children_.size()) - 1, *selector_));
return old_selected != *selector_;
}
bool HorizontalEvent(Event event) {
int old_selected = *selector_;
if (event == Event::ArrowLeft || event == Event::Character('h'))
(*selector_)--;
if (event == Event::ArrowRight || event == Event::Character('l'))
(*selector_)++;
if (event == Event::Tab && children_.size())
*selector_ = (*selector_ + 1) % children_.size();
if (event == Event::TabReverse && children_.size())
*selector_ = (*selector_ + children_.size() - 1) % children_.size();
*selector_ = std::max(0, std::min(int(children_.size()) - 1, *selector_));
return old_selected != *selector_;
}
bool TabEvent(Event) { return false; }
bool OnMouseEvent(Event event) {
if (is_tab_)
return ActiveChild()->OnEvent(event);
for (Component& child : children_) {
if (child->OnEvent(event))
return true;
}
return false;
}
using EventHandler = bool (ContainerBase::*)(Event);
using RenderHandler = Element (ContainerBase::*)();
Element Render() override { return (this->*render_handler_)(); }
Element VerticalRender() {
Elements elements;
for (auto& it : children_)
elements.push_back(it->Render());
if (elements.size() == 0)
return text(L"Empty container");
return vbox(std::move(elements));
}
Element HorizontalRender() {
Elements elements;
for (auto& it : children_)
elements.push_back(it->Render());
if (elements.size() == 0)
return text(L"Empty container");
return hbox(std::move(elements));
}
Element TabRender() {
Component active_child = ActiveChild();
if (active_child)
return active_child->Render();
return text(L"Empty container");
}
EventHandler event_handler_;
RenderHandler render_handler_;
int selected_ = 0;
int* selector_ = nullptr;
bool is_tab_ = false;
};
namespace Container {
/// @brief A list of components, drawn one by one vertically and navigated
@ -120,163 +279,6 @@ Component Tab(Components children, int* selector) {
} // namespace Container
// static
Component ContainerBase::Vertical() {
return Vertical({});
}
// static
Component ContainerBase::Vertical(Components children) {
return Vertical(std::move(children), /*selector=*/nullptr);
}
// static
Component ContainerBase::Vertical(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->event_handler_ = &ContainerBase::VerticalEvent;
container->render_handler_ = &ContainerBase::VerticalRender;
container->selector_ = selector ? selector : &container->selected_;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
// static
Component ContainerBase::Horizontal() {
return Horizontal({});
}
// static
Component ContainerBase::Horizontal(Components children) {
return Horizontal(std::move(children), /*selector=*/nullptr);
}
Component ContainerBase::Horizontal(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->event_handler_ = &ContainerBase::HorizontalEvent;
container->render_handler_ = &ContainerBase::HorizontalRender;
container->selector_ = selector ? selector : &container->selected_;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
// static
Component ContainerBase::Tab(int* selector) {
return Tab({}, selector);
}
// static
Component ContainerBase::Tab(Components children, int* selector) {
auto container = std::make_shared<ContainerBase>();
container->selector_ = selector ? selector : &container->selected_;
container->event_handler_ = &ContainerBase::TabEvent;
container->render_handler_ = &ContainerBase::TabRender;
container->is_tab_ = true;
for (Component& child : children)
container->Add(std::move(child));
return container;
}
bool ContainerBase::OnEvent(Event event) {
if (event.is_mouse())
return OnMouseEvent(event);
if (!Focused())
return false;
if (ActiveChild() && ActiveChild()->OnEvent(event))
return true;
return (this->*event_handler_)(event);
}
Component ContainerBase::ActiveChild() {
if (children_.size() == 0)
return nullptr;
return children_[*selector_ % children_.size()];
}
void ContainerBase::SetActiveChild(ComponentBase* child) {
for (size_t i = 0; i < children_.size(); ++i) {
if (children_[i].get() == child) {
*selector_ = i;
return;
}
}
}
bool ContainerBase::VerticalEvent(Event event) {
int old_selected = *selector_;
if (event == Event::ArrowUp || event == Event::Character('k'))
(*selector_)--;
if (event == Event::ArrowDown || event == Event::Character('j'))
(*selector_)++;
if (event == Event::Tab && children_.size())
*selector_ = (*selector_ + 1) % children_.size();
if (event == Event::TabReverse && children_.size())
*selector_ = (*selector_ + children_.size() - 1) % children_.size();
*selector_ = std::max(0, std::min(int(children_.size()) - 1, *selector_));
return old_selected != *selector_;
}
bool ContainerBase::HorizontalEvent(Event event) {
int old_selected = *selector_;
if (event == Event::ArrowLeft || event == Event::Character('h'))
(*selector_)--;
if (event == Event::ArrowRight || event == Event::Character('l'))
(*selector_)++;
if (event == Event::Tab && children_.size())
*selector_ = (*selector_ + 1) % children_.size();
if (event == Event::TabReverse && children_.size())
*selector_ = (*selector_ + children_.size() - 1) % children_.size();
*selector_ = std::max(0, std::min(int(children_.size()) - 1, *selector_));
return old_selected != *selector_;
}
Element ContainerBase::Render() {
return (this->*render_handler_)();
}
Element ContainerBase::VerticalRender() {
Elements elements;
for (auto& it : children_)
elements.push_back(it->Render());
if (elements.size() == 0)
return text(L"Empty container");
return vbox(std::move(elements));
}
Element ContainerBase::HorizontalRender() {
Elements elements;
for (auto& it : children_)
elements.push_back(it->Render());
if (elements.size() == 0)
return text(L"Empty container");
return hbox(std::move(elements));
}
Element ContainerBase::TabRender() {
Component active_child = ActiveChild();
if (active_child)
return active_child->Render();
return text(L"Empty container");
}
bool ContainerBase::OnMouseEvent(Event event) {
if (is_tab_)
return ActiveChild()->OnEvent(event);
for (Component& child : children_) {
if (child->OnEvent(event))
return true;
}
return false;
}
} // namespace ftxui
// Copyright 2020 Arthur Sonzogni. All rights reserved.

View File

@ -3,13 +3,14 @@
#include <memory> // for __shared_ptr_access, shared_ptr, allocator
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/container.hpp"
#include "ftxui/component/component.hpp" // for AssertionResult, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, Test, TEST
#include "ftxui/component/event.hpp" // for AssertionResult, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, Test, TEST
#include "gtest/gtest_pred_impl.h" // for AssertionResult, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, Test, TEST
using namespace ftxui;
TEST(ContainerTest, HorizontalEvent) {
auto container = ContainerBase::Horizontal();
auto container = Container::Horizontal({});
auto c0 = Container::Horizontal({});
auto c1 = Container::Horizontal({});
auto c2 = Container::Horizontal({});
@ -82,7 +83,7 @@ TEST(ContainerTest, HorizontalEvent) {
}
TEST(ContainerTest, VerticalEvent) {
auto container = ContainerBase::Vertical();
auto container = Container::Vertical({});
auto c0 = Container::Horizontal({});
auto c1 = Container::Horizontal({});
auto c2 = Container::Horizontal({});
@ -155,7 +156,7 @@ TEST(ContainerTest, VerticalEvent) {
}
TEST(ContainerTest, SetActiveChild) {
auto container = ContainerBase::Horizontal();
auto container = Container::Horizontal({});
auto c0 = Container::Horizontal({});
auto c1 = Container::Horizontal({});
auto c2 = Container::Horizontal({});
@ -209,16 +210,16 @@ TEST(ContainerTest, SetActiveChild) {
}
TEST(ContainerTest, TakeFocus) {
auto c = ContainerBase::Horizontal();
auto c1 = ContainerBase::Vertical();
auto c2 = ContainerBase::Vertical();
auto c3 = ContainerBase::Vertical();
auto c11 = ContainerBase::Horizontal();
auto c12 = ContainerBase::Horizontal();
auto c13 = ContainerBase::Horizontal();
auto c21 = ContainerBase::Horizontal();
auto c22 = ContainerBase::Horizontal();
auto c23 = ContainerBase::Horizontal();
auto c = Container::Horizontal({});
auto c1 = Container::Vertical({});
auto c2 = Container::Vertical({});
auto c3 = Container::Vertical({});
auto c11 = Container::Horizontal({});
auto c12 = Container::Horizontal({});
auto c13 = Container::Horizontal({});
auto c21 = Container::Horizontal({});
auto c22 = Container::Horizontal({});
auto c23 = Container::Horizontal({});
c->Add(c1);
c->Add(c2);

View File

@ -4,6 +4,7 @@
#include <utility> // for move
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
#include "ftxui/component/component.hpp" // for CapturedMouse
#include "ftxui/component/event.hpp" // for Event, Event::ArrowDown, Event::ArrowUp, Event::Return, Event::Tab, Event::TabReverse
#include "ftxui/component/menu.hpp"
#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Released