mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-25 20:27:31 +08:00
Remove container.hpp
This commit is contained in:
parent
26db8228f9
commit
0ca7da630b
@ -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
|
||||
|
@ -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.
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user