mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-29 14:45:53 +08:00
Refactor component containers.
This commit is contained in:
parent
21644eea6b
commit
dba019139b
@ -1,31 +1,29 @@
|
|||||||
#include <chrono>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "ftxui/component/component_vertical.hpp"
|
#include "ftxui/component/container.hpp"
|
||||||
#include "ftxui/component/input.hpp"
|
#include "ftxui/component/input.hpp"
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class MyComponent : ComponentVertical {
|
class MyComponent : public Component {
|
||||||
public:
|
public:
|
||||||
MyComponent(Delegate* delegate)
|
MyComponent() {
|
||||||
: ComponentVertical(delegate),
|
Add(&container);
|
||||||
input_1(delegate->NewChild()),
|
container.Add(&input_1);
|
||||||
input_2(delegate->NewChild()),
|
container.Add(&input_2);
|
||||||
input_3(delegate->NewChild()) {
|
container.Add(&input_3);
|
||||||
|
|
||||||
input_1.placeholder = L"input1";
|
input_1.placeholder = L"input1";
|
||||||
input_2.placeholder = L"input2";
|
input_2.placeholder = L"input2";
|
||||||
input_3.placeholder = L"input3";
|
input_3.placeholder = L"input3";
|
||||||
Focus(&input_1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = []() {};
|
std::function<void()> on_enter = []() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Container container = Container::Vertical();
|
||||||
Input input_1;
|
Input input_1;
|
||||||
Input input_2;
|
Input input_2;
|
||||||
Input input_3;
|
Input input_3;
|
||||||
@ -44,7 +42,7 @@ class MyComponent : ComponentVertical {
|
|||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component(screen.delegate());
|
MyComponent component;
|
||||||
component.on_enter = screen.ExitLoopClosure();
|
component.on_enter = screen.ExitLoopClosure();
|
||||||
screen.Loop();
|
screen.Loop(&component);
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,13 @@
|
|||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
auto screen = ScreenInteractive::FixedSize(30, 3);
|
auto screen = ScreenInteractive::FixedSize(30, 3);
|
||||||
Menu menu(screen.delegate());
|
|
||||||
|
Menu menu;
|
||||||
menu.entries = {L"entry 1", L"entry 2", L"entry 3"};
|
menu.entries = {L"entry 1", L"entry 2", L"entry 3"};
|
||||||
menu.selected = 0;
|
menu.selected = 0;
|
||||||
menu.on_enter = screen.ExitLoopClosure();
|
menu.on_enter = screen.ExitLoopClosure();
|
||||||
|
|
||||||
screen.Loop();
|
screen.Loop(&menu);
|
||||||
|
|
||||||
|
std::cout << "Selected element = " << menu.selected << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -2,20 +2,20 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ftxui/component/component_horizontal.hpp"
|
#include "ftxui/component/container.hpp"
|
||||||
#include "ftxui/component/component_vertical.hpp"
|
|
||||||
#include "ftxui/component/menu.hpp"
|
#include "ftxui/component/menu.hpp"
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class MyComponent : ComponentHorizontal {
|
class MyComponent : public Component {
|
||||||
public:
|
public:
|
||||||
MyComponent(Delegate* delegate)
|
MyComponent() {
|
||||||
: ComponentHorizontal(delegate),
|
Add(&container);
|
||||||
left_menu(delegate->NewChild()),
|
container.Add(&left_menu);
|
||||||
right_menu(delegate->NewChild()) {
|
container.Add(&right_menu);
|
||||||
|
|
||||||
left_menu.entries = {L"0%", L"10%", L"20%", L"30%", L"40%", L"50%",
|
left_menu.entries = {L"0%", L"10%", L"20%", L"30%", L"40%", L"50%",
|
||||||
L"60%", L"70%", L"80%", L"90%"};
|
L"60%", L"70%", L"80%", L"90%"};
|
||||||
right_menu.entries = {L"0%", L"1%", L"2%", L"3%", L"4%", L"5%",
|
right_menu.entries = {L"0%", L"1%", L"2%", L"3%", L"4%", L"5%",
|
||||||
@ -23,11 +23,11 @@ class MyComponent : ComponentHorizontal {
|
|||||||
|
|
||||||
left_menu.on_enter = [this]() { on_enter(); };
|
left_menu.on_enter = [this]() { on_enter(); };
|
||||||
right_menu.on_enter = [this]() { on_enter(); };
|
right_menu.on_enter = [this]() { on_enter(); };
|
||||||
Focus(&left_menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = [](){};
|
std::function<void()> on_enter = [](){};
|
||||||
private:
|
private:
|
||||||
|
Container container = Container::Horizontal();
|
||||||
Menu left_menu;
|
Menu left_menu;
|
||||||
Menu right_menu;
|
Menu right_menu;
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ class MyComponent : ComponentHorizontal {
|
|||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component(screen.delegate());
|
MyComponent component;
|
||||||
component.on_enter = screen.ExitLoopClosure();
|
component.on_enter = screen.ExitLoopClosure();
|
||||||
screen.Loop();
|
screen.Loop(&component);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,20 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ftxui/component/component_horizontal.hpp"
|
#include "ftxui/component/container.hpp"
|
||||||
#include "ftxui/component/menu.hpp"
|
#include "ftxui/component/menu.hpp"
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class MyComponent : ComponentHorizontal {
|
class MyComponent : public Component {
|
||||||
public:
|
public:
|
||||||
MyComponent(Delegate* delegate)
|
MyComponent() {
|
||||||
: ComponentHorizontal(delegate),
|
Add(&container);
|
||||||
menu_1(delegate->NewChild()),
|
|
||||||
menu_2(delegate->NewChild()),
|
|
||||||
menu_3(delegate->NewChild()),
|
|
||||||
menu_4(delegate->NewChild()),
|
|
||||||
menu_5(delegate->NewChild()),
|
|
||||||
menu_6(delegate->NewChild()) {
|
|
||||||
|
|
||||||
for(Menu* menu : {&menu_1, &menu_2, &menu_3, &menu_4, &menu_5, &menu_6}) {
|
for(Menu* menu : {&menu_1, &menu_2, &menu_3, &menu_4, &menu_5, &menu_6}) {
|
||||||
|
container.Add(menu);
|
||||||
menu->entries = {
|
menu->entries = {
|
||||||
L"Monkey",
|
L"Monkey",
|
||||||
L"Dog",
|
L"Dog",
|
||||||
@ -46,12 +41,11 @@ class MyComponent : ComponentHorizontal {
|
|||||||
menu_6.normal_style = dim | color(Color::Blue);
|
menu_6.normal_style = dim | color(Color::Blue);
|
||||||
menu_6.selected_style = color(Color::Blue);
|
menu_6.selected_style = color(Color::Blue);
|
||||||
menu_6.active_style = bold | color(Color::Blue);
|
menu_6.active_style = bold | color(Color::Blue);
|
||||||
|
|
||||||
Focus(&menu_1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = [](){};
|
std::function<void()> on_enter = [](){};
|
||||||
private:
|
private:
|
||||||
|
Container container = Container::Horizontal();
|
||||||
Menu menu_1;
|
Menu menu_1;
|
||||||
Menu menu_2;
|
Menu menu_2;
|
||||||
Menu menu_3;
|
Menu menu_3;
|
||||||
@ -75,7 +69,7 @@ class MyComponent : ComponentHorizontal {
|
|||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component(screen.delegate());
|
MyComponent component;
|
||||||
component.on_enter = screen.ExitLoopClosure();
|
component.on_enter = screen.ExitLoopClosure();
|
||||||
screen.Loop();
|
screen.Loop(&component);
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ftxui/component/component_vertical.hpp"
|
#include "ftxui/component/container.hpp"
|
||||||
#include "ftxui/component/menu.hpp"
|
#include "ftxui/component/menu.hpp"
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/component/toggle.hpp"
|
#include "ftxui/component/toggle.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class MyComponent : ComponentVertical {
|
class MyComponent : public Component {
|
||||||
public:
|
public:
|
||||||
MyComponent(Delegate* delegate)
|
MyComponent() {
|
||||||
: ComponentVertical(delegate),
|
Add(&container);
|
||||||
toggle(delegate->NewChild()),
|
container.Add(&toggle);
|
||||||
menu(delegate->NewChild()) {
|
container.Add(&menu);
|
||||||
|
|
||||||
toggle.options = {L" left ", L" middle ", L" end "};
|
toggle.options = {L" left ", L" middle ", L" end "};
|
||||||
menu.entries = {L" top ", L" middle ", L" bottom "};
|
menu.entries = {L" top ", L" middle ", L" bottom "};
|
||||||
Focus(&toggle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = [](){};
|
std::function<void()> on_enter = [](){};
|
||||||
private:
|
private:
|
||||||
|
Container container = Container::Vertical();
|
||||||
Toggle toggle;
|
Toggle toggle;
|
||||||
Menu menu;
|
Menu menu;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class MyComponent : ComponentVertical {
|
|||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component(screen.delegate());
|
MyComponent component;
|
||||||
component.on_enter = screen.ExitLoopClosure();
|
component.on_enter = screen.ExitLoopClosure();
|
||||||
screen.Loop();
|
screen.Loop(&component);
|
||||||
}
|
}
|
||||||
|
@ -2,33 +2,32 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "ftxui/component/component_horizontal.hpp"
|
#include "ftxui/component/container.hpp"
|
||||||
#include "ftxui/component/component_vertical.hpp"
|
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/component/toggle.hpp"
|
#include "ftxui/component/toggle.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class MyComponent : ComponentVertical {
|
class MyComponent : public Component {
|
||||||
public:
|
public:
|
||||||
MyComponent(Delegate* delegate)
|
MyComponent() {
|
||||||
: ComponentVertical(delegate),
|
Add(&container);
|
||||||
toggle_1(delegate->NewChild()),
|
container.Add(&toggle_1);
|
||||||
toggle_2(delegate->NewChild()),
|
container.Add(&toggle_2);
|
||||||
toggle_3(delegate->NewChild()),
|
container.Add(&toggle_3);
|
||||||
toggle_4(delegate->NewChild()) {
|
container.Add(&toggle_4);
|
||||||
|
|
||||||
toggle_1.options = {L"On", L"Off"};
|
toggle_1.options = {L"On", L"Off"};
|
||||||
toggle_2.options = {L"Enabled", L"Disabled"};
|
toggle_2.options = {L"Enabled", L"Disabled"};
|
||||||
toggle_3.options = {L"10€", L"0€"};
|
toggle_3.options = {L"10€", L"0€"};
|
||||||
toggle_4.options = {L"Nothing", L"One element", L"Several elements"};
|
toggle_4.options = {L"Nothing", L"One element", L"Several elements"};
|
||||||
|
|
||||||
Focus(&toggle_1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = []() {};
|
std::function<void()> on_enter = []() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Container container = Container::Vertical();
|
||||||
Toggle toggle_1;
|
Toggle toggle_1;
|
||||||
Toggle toggle_2;
|
Toggle toggle_2;
|
||||||
Toggle toggle_3;
|
Toggle toggle_3;
|
||||||
@ -45,23 +44,11 @@ class MyComponent : ComponentVertical {
|
|||||||
hbox(text(L" * Number of elements : "), toggle_4.Render())
|
hbox(text(L" * Number of elements : "), toggle_4.Render())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnEvent(Event event) override {
|
|
||||||
if (ComponentVertical::OnEvent(event))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (event == Event::Return) {
|
|
||||||
on_enter();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component(screen.delegate());
|
MyComponent component;
|
||||||
component.on_enter = screen.ExitLoopClosure();
|
component.on_enter = screen.ExitLoopClosure();
|
||||||
screen.Loop();
|
screen.Loop(&component);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "ftxui/dom/elements.hpp"
|
#include "ftxui/dom/elements.hpp"
|
||||||
#include "ftxui/screen/screen.hpp"
|
#include "ftxui/screen/screen.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "ftxui/screen/screen.hpp"
|
#include "ftxui/screen/screen.hpp"
|
||||||
#include "ftxui/dom/elements.hpp"
|
#include "ftxui/dom/elements.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -4,17 +4,16 @@
|
|||||||
|
|
||||||
#include "ftxui/component/component.hpp"
|
#include "ftxui/component/component.hpp"
|
||||||
#include "ftxui/component/screen_interactive.hpp"
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
class DrawKey : public Component {
|
class DrawKey : public Component {
|
||||||
public:
|
public:
|
||||||
DrawKey(Component::Delegate* delegate)
|
~DrawKey() override = default;
|
||||||
: Component(delegate) {}
|
|
||||||
|
|
||||||
Element Render() override {
|
Element Render() override {
|
||||||
Children children;
|
Elements children;
|
||||||
for (size_t i = std::max(0, (int)keys.size() - 10); i < keys.size(); ++i) {
|
for (size_t i = std::max(0, (int)keys.size() - 10); i < keys.size(); ++i) {
|
||||||
std::string code = "";
|
std::string code = "";
|
||||||
for (size_t j = 0; j < 5; ++j)
|
for (size_t j = 0; j < 5; ++j)
|
||||||
@ -44,6 +43,6 @@ class DrawKey : public Component {
|
|||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
auto screen = ScreenInteractive::FixedSize(80, 10);
|
auto screen = ScreenInteractive::FixedSize(80, 10);
|
||||||
DrawKey draw_key(screen.delegate());
|
DrawKey draw_key;
|
||||||
screen.Loop();
|
screen.Loop(&draw_key);
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,7 @@ add_library(dom
|
|||||||
|
|
||||||
add_library(component
|
add_library(component
|
||||||
src/ftxui/component/component.cpp
|
src/ftxui/component/component.cpp
|
||||||
src/ftxui/component/component_direction.cpp
|
src/ftxui/component/container.cpp
|
||||||
src/ftxui/component/component_horizontal.cpp
|
|
||||||
src/ftxui/component/component_vertical.cpp
|
|
||||||
src/ftxui/component/event.cpp
|
src/ftxui/component/event.cpp
|
||||||
src/ftxui/component/input.cpp
|
src/ftxui/component/input.cpp
|
||||||
src/ftxui/component/menu.cpp
|
src/ftxui/component/menu.cpp
|
||||||
|
@ -13,50 +13,43 @@ class Focus;
|
|||||||
class Component {
|
class Component {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Delegate {
|
|
||||||
public:
|
|
||||||
Delegate() {}
|
|
||||||
virtual ~Delegate() {}
|
|
||||||
|
|
||||||
// A Delegate shadows a component.
|
|
||||||
virtual void Register(Component* component) = 0;
|
|
||||||
virtual Component* component() = 0;
|
|
||||||
|
|
||||||
// Create new children.
|
|
||||||
virtual Delegate* NewChild() = 0;
|
|
||||||
virtual std::vector<Delegate*> children() = 0;
|
|
||||||
|
|
||||||
// Navigate in the tree.
|
|
||||||
virtual Delegate* PreviousSibling() = 0;
|
|
||||||
virtual Delegate* NextSibling() = 0;
|
|
||||||
virtual Delegate* Parent() = 0;
|
|
||||||
virtual Delegate* Root() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor/Destructor.
|
// Constructor/Destructor.
|
||||||
Component(Delegate* delegate);
|
Component() = default;
|
||||||
virtual ~Component();
|
virtual ~Component();
|
||||||
|
|
||||||
// Render the component.
|
// Component hierarchy.
|
||||||
|
Component* Parent() { return parent_; }
|
||||||
|
void Add(Component* children);
|
||||||
|
|
||||||
|
// Renders the component.
|
||||||
virtual Element Render();
|
virtual Element Render();
|
||||||
|
|
||||||
// Handle an event. By default, it calls this function on each children.
|
// Handles an event.
|
||||||
virtual bool OnEvent(Event even);
|
// By default, reduce on children with a lazy OR.
|
||||||
|
//
|
||||||
|
// Returns whether the event was handled or not.
|
||||||
|
virtual bool OnEvent(Event);
|
||||||
|
|
||||||
// If this component contains children, this indicates which one is active. It
|
// Focus management ----------------------------------------------------------
|
||||||
// can be none of them.
|
//
|
||||||
// We say an element has the focus if the chain of GetActiveChild() from the
|
// If this component contains children, this indicates which one is active,
|
||||||
|
// nullptr if none is active.
|
||||||
|
//
|
||||||
|
// We say an element has the focus if the chain of ActiveChild() from the
|
||||||
// root component contains this object.
|
// root component contains this object.
|
||||||
virtual Component* GetActiveChild() { return nullptr; }
|
virtual Component* ActiveChild();
|
||||||
bool Active(); // True is this component is an active child.
|
// Whether this is the active child of its parent.
|
||||||
bool Focused(); // True if all the ancestors are active childs.
|
bool Active();
|
||||||
|
// Whether all the ancestors are active.
|
||||||
Component* Parent();
|
bool Focused();
|
||||||
Component* PreviousSibling();
|
|
||||||
Component* NextSibling();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Delegate* delegate_;
|
Component* parent_ = nullptr;
|
||||||
|
void Detach();
|
||||||
|
void Attach(Component* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<Component*> children_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#ifndef FTXUI_COMPONENT_COMPONENT_DIRECTION_H_
|
|
||||||
#define FTXUI_COMPONENT_COMPONENT_DIRECTION_H_
|
|
||||||
|
|
||||||
#include "ftxui/component/component.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
// A component where focus and events are automatically handled for you.
|
|
||||||
// Please use ComponentVertical or ComponentHorizontal.
|
|
||||||
class ComponentDirection : public Component {
|
|
||||||
public:
|
|
||||||
ComponentDirection(Delegate* delegate);
|
|
||||||
bool OnEvent(Event) override;
|
|
||||||
Component* GetActiveChild() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Focus(Component* child);
|
|
||||||
virtual bool HandleDirection(Event) = 0;
|
|
||||||
Component* active_child_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ftxui
|
|
||||||
|
|
||||||
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_DIRECTION_H_ */
|
|
@ -1,18 +0,0 @@
|
|||||||
#ifndef FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_
|
|
||||||
#define FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_
|
|
||||||
|
|
||||||
#include "ftxui/component/component_direction.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
// A component where focus and events are automatically handled for you.
|
|
||||||
// It assumes its children are put in the horizontal direction.
|
|
||||||
class ComponentHorizontal : public ComponentDirection {
|
|
||||||
public:
|
|
||||||
ComponentHorizontal(Delegate*);
|
|
||||||
bool HandleDirection(Event) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ftxui
|
|
||||||
|
|
||||||
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_HORIZONTAL_H_ */
|
|
@ -1,18 +0,0 @@
|
|||||||
#ifndef FTXUI_COMPONENT_COMPONENT_VERTICAL_H_
|
|
||||||
#define FTXUI_COMPONENT_COMPONENT_VERTICAL_H_
|
|
||||||
|
|
||||||
#include "ftxui/component/component_direction.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
// A component where focus and events are automatically handled for you.
|
|
||||||
// It assumes its children are put in the vertical direction.
|
|
||||||
class ComponentVertical : public ComponentDirection {
|
|
||||||
public:
|
|
||||||
ComponentVertical(Delegate*);
|
|
||||||
bool HandleDirection(Event) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ftxui
|
|
||||||
|
|
||||||
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_VERTICAL_H_ */
|
|
36
ftxui/include/ftxui/component/container.hpp
Normal file
36
ftxui/include/ftxui/component/container.hpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef FTXUI_COMPONENT_CONTAINER_HPP
|
||||||
|
#define FTXUI_COMPONENT_CONTAINER_HPP
|
||||||
|
|
||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
// A component where focus and events are automatically handled for you.
|
||||||
|
// List of container:
|
||||||
|
//
|
||||||
|
// Please use HorizontalContainer or VerticalContainer.
|
||||||
|
class Container : public Component {
|
||||||
|
public:
|
||||||
|
static Container Vertical();
|
||||||
|
static Container Horizontal();
|
||||||
|
|
||||||
|
~Container() override = default;
|
||||||
|
|
||||||
|
// Component override.
|
||||||
|
bool OnEvent(Event event) override;
|
||||||
|
Component* ActiveChild() override;
|
||||||
|
protected:
|
||||||
|
// Handlers
|
||||||
|
using Handler = bool (Container::*)(Event);
|
||||||
|
Handler handler_;
|
||||||
|
bool Vertical(Event event);
|
||||||
|
bool Horizontal(Event event);
|
||||||
|
|
||||||
|
size_t selected_ = 0;
|
||||||
|
|
||||||
|
Container(Handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ftxui
|
||||||
|
|
||||||
|
#endif /* end of include guard: FTXUI_COMPONENT_CONTAINER_HPP */
|
@ -9,8 +9,8 @@ namespace ftxui {
|
|||||||
class Input : public Component {
|
class Input : public Component {
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
Input(Delegate*);
|
Input() = default;
|
||||||
~Input() override;
|
~Input() override = default;
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
std::wstring content;
|
std::wstring content;
|
||||||
|
@ -10,7 +10,8 @@ namespace ftxui {
|
|||||||
class Menu : public Component {
|
class Menu : public Component {
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
Menu(Delegate*);
|
Menu() = default;
|
||||||
|
~Menu() override = default;
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
std::vector<std::wstring> entries = {};
|
std::vector<std::wstring> entries = {};
|
||||||
|
@ -1,31 +1,25 @@
|
|||||||
#ifndef FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
|
#ifndef FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
|
||||||
#define FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
|
#define FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
|
||||||
|
|
||||||
#include "ftxui/component/component.hpp"
|
|
||||||
#include "ftxui/screen/screen.hpp"
|
#include "ftxui/screen/screen.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
class Component;
|
||||||
|
|
||||||
|
class ScreenInteractive : public Screen {
|
||||||
class ScreenInteractive : public ftxui::Screen {
|
|
||||||
public:
|
public:
|
||||||
static ScreenInteractive FixedSize(size_t dimx, size_t dimy);
|
static ScreenInteractive FixedSize(size_t dimx, size_t dimy);
|
||||||
static ScreenInteractive Fullscreen();
|
static ScreenInteractive Fullscreen();
|
||||||
static ScreenInteractive TerminalOutput();
|
static ScreenInteractive TerminalOutput();
|
||||||
|
|
||||||
~ScreenInteractive();
|
~ScreenInteractive();
|
||||||
void Loop();
|
void Loop(Component*);
|
||||||
std::function<void()> ExitLoopClosure();
|
std::function<void()> ExitLoopClosure();
|
||||||
|
|
||||||
Component::Delegate* delegate();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Delegate;
|
void Draw(Component* component);
|
||||||
std::unique_ptr<Delegate> delegate_;
|
|
||||||
|
|
||||||
void PrepareDraw();
|
|
||||||
bool quit_ = false;
|
bool quit_ = false;
|
||||||
|
|
||||||
enum class Dimension {
|
enum class Dimension {
|
||||||
@ -34,7 +28,6 @@ class ScreenInteractive : public ftxui::Screen {
|
|||||||
Fullscreen,
|
Fullscreen,
|
||||||
};
|
};
|
||||||
Dimension dimension_ = Dimension::Fixed;
|
Dimension dimension_ = Dimension::Fixed;
|
||||||
|
|
||||||
ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension);
|
ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace ftxui {
|
|||||||
class Toggle : public Component {
|
class Toggle : public Component {
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
Toggle(Delegate*);
|
~Toggle() override = default;
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
size_t activated = 0;
|
size_t activated = 0;
|
||||||
|
@ -9,15 +9,13 @@
|
|||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
using Element = std::unique_ptr<Node>;
|
using Element = std::unique_ptr<Node>;
|
||||||
|
using Elements = std::vector<Element>;
|
||||||
using Decorator = std::function<Element(Element)>;
|
using Decorator = std::function<Element(Element)>;
|
||||||
using Child = std::unique_ptr<Node>;
|
|
||||||
using Children = std::vector<Child>;
|
|
||||||
using Color = ftxui::Color;
|
|
||||||
|
|
||||||
// --- Layout ----
|
// --- Layout ----
|
||||||
Element vbox(Children);
|
Element vbox(Elements);
|
||||||
Element hbox(Children);
|
Element hbox(Elements);
|
||||||
Element dbox(Children);
|
Element dbox(Elements);
|
||||||
|
|
||||||
// -- Flexibility --
|
// -- Flexibility --
|
||||||
Element filler();
|
Element filler();
|
||||||
@ -29,7 +27,7 @@ Element text(std::wstring text);
|
|||||||
Element separator();
|
Element separator();
|
||||||
Element gauge(float ratio);
|
Element gauge(float ratio);
|
||||||
Element frame(Element);
|
Element frame(Element);
|
||||||
Element window(Child title, Child content);
|
Element window(Element title, Element content);
|
||||||
Element spinner(int charset_index, size_t image_index);
|
Element spinner(int charset_index, size_t image_index);
|
||||||
|
|
||||||
// -- Decorator ---
|
// -- Decorator ---
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// Turn a set of arguments into a vector.
|
// Turn a set of arguments into a vector.
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
Children unpack(Args... args) {
|
Elements unpack(Args... args) {
|
||||||
using T = std::common_type_t<Args...>;
|
using T = std::common_type_t<Args...>;
|
||||||
std::vector<T> vec;
|
std::vector<T> vec;
|
||||||
(vec.push_back(std::forward<Args>(args)), ...);
|
(vec.push_back(std::forward<Args>(args)), ...);
|
||||||
|
@ -1,57 +1,53 @@
|
|||||||
#include "ftxui/component/component.hpp"
|
#include "ftxui/component/component.hpp"
|
||||||
#include "ftxui/component/delegate.hpp"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
void Component::Detach() { if (!parent_) return; auto it = std::find(std::begin(parent_->children_),
|
||||||
|
std::end(parent_->children_), this);
|
||||||
|
parent_->children_.erase(it);
|
||||||
|
|
||||||
Component::Component(Delegate* delegate) {
|
|
||||||
delegate_ = delegate;
|
|
||||||
delegate_->Register(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component::~Component() {}
|
void Component::Attach(Component* parent) {
|
||||||
|
Detach();
|
||||||
|
parent_ = parent;
|
||||||
|
parent_->children_.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
Element Component::Render() {
|
void Component::Add(Component* child) {
|
||||||
using namespace ftxui;
|
child->Attach(this);
|
||||||
return text(L"Not implemented component");
|
}
|
||||||
|
|
||||||
|
Component::~Component() {
|
||||||
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Component::OnEvent(Event event) {
|
bool Component::OnEvent(Event event) {
|
||||||
|
for(Component* child : children_) {
|
||||||
|
if (child->OnEvent(event))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component* Component::ActiveChild() {
|
||||||
|
return children_.empty() ? nullptr : children_.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
Element Component::Render() {
|
||||||
|
return text(L"Not implemented component");
|
||||||
|
}
|
||||||
|
|
||||||
bool Component::Focused() {
|
bool Component::Focused() {
|
||||||
Delegate* current = delegate_->Root();
|
Component* current = this;
|
||||||
while (current) {
|
for(;;) {
|
||||||
if (current == delegate_)
|
Component* parent = current->parent_;
|
||||||
|
if (!parent)
|
||||||
return true;
|
return true;
|
||||||
|
if (parent->ActiveChild() != current)
|
||||||
Component* active_child = current->component()->GetActiveChild();
|
|
||||||
current = active_child ? active_child->delegate_ : nullptr;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
current = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Component::Active() {
|
|
||||||
Delegate* parent = delegate_->Parent();
|
|
||||||
return parent && parent->component()->GetActiveChild() == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component* Component::PreviousSibling() {
|
|
||||||
Delegate* sibling = delegate_->PreviousSibling();
|
|
||||||
return sibling ? sibling->component() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component* Component::NextSibling() {
|
|
||||||
Delegate* sibling = delegate_->NextSibling();
|
|
||||||
return sibling ? sibling->component() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component* Component::Parent() {
|
|
||||||
Delegate* parent_delegate = delegate_->Parent();
|
|
||||||
if (!parent_delegate)
|
|
||||||
return nullptr;
|
|
||||||
return parent_delegate->component();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#include "ftxui/component/component_direction.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
ComponentDirection::ComponentDirection(Delegate* delegate)
|
|
||||||
: Component(delegate), active_child_(nullptr) {}
|
|
||||||
|
|
||||||
bool ComponentDirection::OnEvent(Event event) {
|
|
||||||
if (!Focused())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!active_child_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (active_child_->OnEvent(event))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return HandleDirection(event);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Component* ComponentDirection::GetActiveChild() {
|
|
||||||
return active_child_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComponentDirection::Focus(Component* child) {
|
|
||||||
active_child_ = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ftxui::Component
|
|
@ -1,30 +0,0 @@
|
|||||||
#include "ftxui/component/component_horizontal.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
ComponentHorizontal::ComponentHorizontal(Delegate* delegate)
|
|
||||||
: ComponentDirection(delegate) {}
|
|
||||||
|
|
||||||
bool ComponentHorizontal::HandleDirection(Event event) {
|
|
||||||
// Left pressed ?
|
|
||||||
if (event == Event::ArrowLeft || event == Event::Character('h')) {
|
|
||||||
Component* previous_sibling = active_child_->PreviousSibling();
|
|
||||||
if (previous_sibling) {
|
|
||||||
active_child_ = previous_sibling;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left pressed ?
|
|
||||||
if (event == Event::ArrowRight || event == Event::Character('l')) {
|
|
||||||
Component* next_sibling = active_child_->NextSibling();
|
|
||||||
if (next_sibling) {
|
|
||||||
active_child_ = next_sibling;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ftxui
|
|
@ -1,30 +0,0 @@
|
|||||||
#include "ftxui/component/component_vertical.hpp"
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
ComponentVertical::ComponentVertical(Delegate* delegate)
|
|
||||||
: ComponentDirection(delegate) {}
|
|
||||||
|
|
||||||
bool ComponentVertical::HandleDirection(Event event) {
|
|
||||||
// Up pressed ?
|
|
||||||
if (event == Event::ArrowUp || event == Event::Character('k')) {
|
|
||||||
Component* previous_sibling = active_child_->PreviousSibling();
|
|
||||||
if (previous_sibling) {
|
|
||||||
active_child_ = previous_sibling;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down pressed ?
|
|
||||||
if (event == Event::ArrowDown || event == Event::Character('j')) {
|
|
||||||
Component* next_sibling = active_child_->NextSibling();
|
|
||||||
if (next_sibling) {
|
|
||||||
active_child_ = next_sibling;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ftxui
|
|
73
ftxui/src/ftxui/component/container.cpp
Normal file
73
ftxui/src/ftxui/component/container.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "ftxui/component/container.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
// static
|
||||||
|
Container Container::Horizontal() {
|
||||||
|
return Container(&Container::Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Container Container::Vertical() {
|
||||||
|
return Container(&Container::Vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container::Container(Container::Handler handler) : handler_(handler) {}
|
||||||
|
|
||||||
|
bool Container::OnEvent(Event event) {
|
||||||
|
if (!Focused())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ActiveChild()->OnEvent(event))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return (this->*handler_)(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component* Container::ActiveChild() {
|
||||||
|
return children_[selected_ % children_.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Container::Vertical(Event event) {
|
||||||
|
selected_ %= children_.size();
|
||||||
|
// Left pressed ?
|
||||||
|
if (event == Event::ArrowUp || event == Event::Character('k')) {
|
||||||
|
if (selected_ != 0) {
|
||||||
|
selected_--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left pressed ?
|
||||||
|
if (event == Event::ArrowDown || event == Event::Character('j')) {
|
||||||
|
if (selected_ != children_.size() - 1) {
|
||||||
|
selected_++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Container::Horizontal(Event event) {
|
||||||
|
selected_ %= children_.size();
|
||||||
|
// Left pressed ?
|
||||||
|
if (event == Event::ArrowLeft || event == Event::Character('h')) {
|
||||||
|
if (selected_ != 0) {
|
||||||
|
selected_--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left pressed ?
|
||||||
|
if (event == Event::ArrowRight || event == Event::Character('l')) {
|
||||||
|
if (selected_ != children_.size() - 1) {
|
||||||
|
selected_++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ftxui
|
@ -1,11 +1,8 @@
|
|||||||
#include "ftxui/component/input.hpp"
|
#include "ftxui/component/input.hpp"
|
||||||
#include "ftxui/util/string.hpp"
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
Input::Input(Delegate* delegate): Component(delegate) {}
|
|
||||||
Input::~Input() {}
|
|
||||||
|
|
||||||
// Component implementation.
|
// Component implementation.
|
||||||
Element Input::Render() {
|
Element Input::Render() {
|
||||||
bool is_focused = Focused();
|
bool is_focused = Focused();
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
Menu::Menu(Delegate* delegate) : Component(delegate) {}
|
|
||||||
|
|
||||||
Element Menu::Render() {
|
Element Menu::Render() {
|
||||||
std::vector<Element> elements;
|
std::vector<Element> elements;
|
||||||
bool focused = Focused();
|
bool focused = Focused();
|
||||||
|
@ -45,53 +45,10 @@ Event GetEvent() {
|
|||||||
|
|
||||||
}; // namespace
|
}; // namespace
|
||||||
|
|
||||||
class ScreenInteractive::Delegate : public Component::Delegate {
|
|
||||||
public:
|
|
||||||
Delegate() : root_(this) {}
|
|
||||||
|
|
||||||
void Register(Component* c) override { component_ = c; }
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Delegate>> child_;
|
|
||||||
Delegate* NewChild() override {
|
|
||||||
Delegate* child = new Delegate;
|
|
||||||
child->root_ = root_;
|
|
||||||
child->parent_ = this;
|
|
||||||
|
|
||||||
if (!child_.empty()) {
|
|
||||||
child_.back()->next_sibling_ = child;
|
|
||||||
child->previous_sibling_ = child_.back().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
child_.emplace_back(child);
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnEvent(Event event) { component_->OnEvent(event); }
|
|
||||||
|
|
||||||
std::vector<Component::Delegate*> children() override {
|
|
||||||
std::vector<Component::Delegate*> ret;
|
|
||||||
for (auto& it : child_)
|
|
||||||
ret.push_back(it.get());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component::Delegate* root_;
|
|
||||||
Component::Delegate* parent_ = nullptr;
|
|
||||||
Component::Delegate* previous_sibling_ = nullptr;
|
|
||||||
Component::Delegate* next_sibling_ = nullptr;
|
|
||||||
Component* component_;
|
|
||||||
|
|
||||||
Component::Delegate* Root() override { return root_; }
|
|
||||||
Component::Delegate* Parent() override { return parent_; }
|
|
||||||
Component::Delegate* PreviousSibling() override { return previous_sibling_; }
|
|
||||||
Component::Delegate* NextSibling() override { return next_sibling_; }
|
|
||||||
Component* component() override { return component_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
ScreenInteractive::ScreenInteractive(size_t dimx,
|
ScreenInteractive::ScreenInteractive(size_t dimx,
|
||||||
size_t dimy,
|
size_t dimy,
|
||||||
Dimension dimension)
|
Dimension dimension)
|
||||||
: Screen(dimx, dimy), delegate_(new Delegate), dimension_(dimension) {}
|
: Screen(dimx, dimy), dimension_(dimension) {}
|
||||||
ScreenInteractive::~ScreenInteractive() {}
|
ScreenInteractive::~ScreenInteractive() {}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -109,10 +66,10 @@ ScreenInteractive ScreenInteractive::TerminalOutput() {
|
|||||||
return ScreenInteractive(0, 0, Dimension::TerminalOutput);
|
return ScreenInteractive(0, 0, Dimension::TerminalOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenInteractive::Loop() {
|
void ScreenInteractive::Loop(Component* component) {
|
||||||
std::cout << "\033[?9h"; /* Send Mouse Row & Column on Button Press */
|
//std::cout << "\033[?9h"; [> Send Mouse Row & Column on Button Press <]
|
||||||
std::cout << "\033[?1000h"; /* Send Mouse X & Y on button press and release */
|
//std::cout << "\033[?1000h"; [> Send Mouse X & Y on button press and release <]
|
||||||
std::cout << std::flush;
|
//std::cout << std::flush;
|
||||||
|
|
||||||
// Save the old terminal configuration.
|
// Save the old terminal configuration.
|
||||||
struct termios terminal_configuration_old;
|
struct termios terminal_configuration_old;
|
||||||
@ -130,23 +87,27 @@ void ScreenInteractive::Loop() {
|
|||||||
|
|
||||||
std::string reset_position;
|
std::string reset_position;
|
||||||
while (!quit_) {
|
while (!quit_) {
|
||||||
PrepareDraw();
|
Draw(component);
|
||||||
std::cout << reset_position << ToString() << std::flush;
|
std::cout << reset_position << ToString() << std::flush;
|
||||||
reset_position = ResetPosition();
|
reset_position = ResetPosition();
|
||||||
Clear();
|
Clear();
|
||||||
delegate_->OnEvent(GetEvent());
|
component->OnEvent(GetEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the old terminal configuration.
|
// Restore the old terminal configuration.
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_old);
|
tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_old);
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenInteractive::PrepareDraw() {
|
void ScreenInteractive::Draw(Component* component) {
|
||||||
auto document = delegate_->component()->Render();
|
auto document = component->Render();
|
||||||
size_t dimx;
|
size_t dimx;
|
||||||
size_t dimy;
|
size_t dimy;
|
||||||
switch (dimension_) {
|
switch (dimension_) {
|
||||||
case Dimension::Fixed:
|
case Dimension::Fixed:
|
||||||
|
dimx = dimx_;
|
||||||
|
dimy = dimy_;
|
||||||
break;
|
break;
|
||||||
case Dimension::TerminalOutput:
|
case Dimension::TerminalOutput:
|
||||||
document->ComputeRequirement();
|
document->ComputeRequirement();
|
||||||
@ -161,8 +122,10 @@ void ScreenInteractive::PrepareDraw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dimx != dimx_ || dimy != dimy_) {
|
if (dimx != dimx_ || dimy != dimy_) {
|
||||||
|
std::cerr << dimx_ << " " << dimy_ << std::endl;
|
||||||
dimx_ = dimx;
|
dimx_ = dimx;
|
||||||
dimy_ = dimy;
|
dimy_ = dimy;
|
||||||
|
std::cerr << dimx_ << " " << dimy_ << std::endl;
|
||||||
pixels_ = std::vector<std::vector<Pixel>>(
|
pixels_ = std::vector<std::vector<Pixel>>(
|
||||||
dimy, std::vector<Pixel>(dimx));
|
dimy, std::vector<Pixel>(dimx));
|
||||||
}
|
}
|
||||||
@ -170,10 +133,6 @@ void ScreenInteractive::PrepareDraw() {
|
|||||||
Render(*this, document.get());
|
Render(*this, document.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Component::Delegate* ScreenInteractive::delegate() {
|
|
||||||
return delegate_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::function<void()> ScreenInteractive::ExitLoopClosure() {
|
std::function<void()> ScreenInteractive::ExitLoopClosure() {
|
||||||
return [this]() { quit_ = true; };
|
return [this]() { quit_ = true; };
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
Toggle::Toggle(Delegate* delegate) : Component(delegate) {}
|
|
||||||
|
|
||||||
Element Toggle::Render() {
|
Element Toggle::Render() {
|
||||||
auto highlight = Focused() ? inverted : bold;
|
auto highlight = Focused() ? inverted : bold;
|
||||||
|
|
||||||
Children children;
|
Elements children;
|
||||||
|
|
||||||
for(size_t i = 0; i<options.size(); ++i) {
|
for(size_t i = 0; i<options.size(); ++i) {
|
||||||
// Separator.
|
// Separator.
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class Blink : public NodeDecorator {
|
class Blink : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
Blink(Children children) : NodeDecorator(std::move(children)) {}
|
Blink(Elements children) : NodeDecorator(std::move(children)) {}
|
||||||
~Blink() override {}
|
~Blink() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -18,7 +18,7 @@ class Blink : public NodeDecorator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> blink(Child child) {
|
std::unique_ptr<Node> blink(Element child) {
|
||||||
return std::make_unique<Blink>(unpack(std::move(child)));
|
return std::make_unique<Blink>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class Bold : public NodeDecorator {
|
class Bold : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
Bold(Children children) : NodeDecorator(std::move(children)) {}
|
Bold(Elements children) : NodeDecorator(std::move(children)) {}
|
||||||
~Bold() override {}
|
~Bold() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -18,7 +18,7 @@ class Bold : public NodeDecorator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> bold(Child child) {
|
std::unique_ptr<Node> bold(Element child) {
|
||||||
return std::make_unique<Bold>(unpack(std::move(child)));
|
return std::make_unique<Bold>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class BgColor : public NodeDecorator {
|
class BgColor : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
BgColor(Children children, Color color)
|
BgColor(Elements children, Color color)
|
||||||
: NodeDecorator(std::move(children)), color_(color) {}
|
: NodeDecorator(std::move(children)), color_(color) {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -22,7 +22,7 @@ class BgColor : public NodeDecorator {
|
|||||||
|
|
||||||
class FgColor : public NodeDecorator {
|
class FgColor : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
FgColor(Children children, Color color)
|
FgColor(Elements children, Color color)
|
||||||
: NodeDecorator(std::move(children)), color_(color) {}
|
: NodeDecorator(std::move(children)), color_(color) {}
|
||||||
~FgColor() override {}
|
~FgColor() override {}
|
||||||
|
|
||||||
@ -38,22 +38,22 @@ class FgColor : public NodeDecorator {
|
|||||||
Color color_;
|
Color color_;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> color(Color c, Child child) {
|
std::unique_ptr<Node> color(Color c, Element child) {
|
||||||
return std::make_unique<FgColor>(unpack(std::move(child)), c);
|
return std::make_unique<FgColor>(unpack(std::move(child)), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Node> bgcolor(Color c, Child child) {
|
std::unique_ptr<Node> bgcolor(Color c, Element child) {
|
||||||
return std::make_unique<BgColor>(unpack(std::move(child)), c);
|
return std::make_unique<BgColor>(unpack(std::move(child)), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
Decorator color(Color c) {
|
Decorator color(Color c) {
|
||||||
return [c](Child child) {
|
return [c](Element child) {
|
||||||
return color(c, std::move(child));
|
return color(c, std::move(child));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Decorator bgcolor(Color c) {
|
Decorator bgcolor(Color c) {
|
||||||
return [c](Child child) {
|
return [c](Element child) {
|
||||||
return bgcolor(c, std::move(child));
|
return bgcolor(c, std::move(child));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class DBox : public Node {
|
class DBox : public Node {
|
||||||
public:
|
public:
|
||||||
DBox(Children children) : Node(std::move(children)) {}
|
DBox(Elements children) : Node(std::move(children)) {}
|
||||||
~DBox() {}
|
~DBox() {}
|
||||||
|
|
||||||
void ComputeRequirement() override {
|
void ComputeRequirement() override {
|
||||||
@ -28,7 +28,7 @@ class DBox : public Node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> dbox(Children children) {
|
std::unique_ptr<Node> dbox(Elements children) {
|
||||||
return std::make_unique<DBox>(std::move(children));
|
return std::make_unique<DBox>(std::move(children));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ using ftxui::Screen;
|
|||||||
|
|
||||||
class Dim : public NodeDecorator {
|
class Dim : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
Dim(Children children) : NodeDecorator(std::move(children)) {}
|
Dim(Elements children) : NodeDecorator(std::move(children)) {}
|
||||||
~Dim() override {}
|
~Dim() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -20,7 +20,7 @@ class Dim : public NodeDecorator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> dim(Child child) {
|
std::unique_ptr<Node> dim(Element child) {
|
||||||
return std::make_unique<Dim>(unpack(std::move(child)));
|
return std::make_unique<Dim>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ static wchar_t charset[] = L"┌┐└┘─│┬┴┤├";
|
|||||||
|
|
||||||
class Frame : public Node {
|
class Frame : public Node {
|
||||||
public:
|
public:
|
||||||
Frame(Children children) : Node(std::move(children)) {}
|
Frame(Elements children) : Node(std::move(children)) {}
|
||||||
~Frame() override {}
|
~Frame() override {}
|
||||||
|
|
||||||
void ComputeRequirement() override {
|
void ComputeRequirement() override {
|
||||||
@ -81,16 +81,16 @@ class Frame : public Node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> frame(Child child) {
|
std::unique_ptr<Node> frame(Element child) {
|
||||||
return std::make_unique<Frame>(unpack(std::move(child)));
|
return std::make_unique<Frame>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Node> window(Child title, Child content) {
|
std::unique_ptr<Node> window(Element title, Element content) {
|
||||||
return std::make_unique<Frame>(unpack(std::move(content), std::move(title)));
|
return std::make_unique<Frame>(unpack(std::move(content), std::move(title)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Decorator boxed() {
|
Decorator boxed() {
|
||||||
return [](Child child) {
|
return [](Element child) {
|
||||||
return frame(std::move(child));
|
return frame(std::move(child));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class HBox : public Node {
|
class HBox : public Node {
|
||||||
public:
|
public:
|
||||||
HBox(Children children) : Node(std::move(children)) {}
|
HBox(Elements children) : Node(std::move(children)) {}
|
||||||
~HBox() {}
|
~HBox() {}
|
||||||
|
|
||||||
void ComputeRequirement() override {
|
void ComputeRequirement() override {
|
||||||
@ -59,7 +59,7 @@ class HBox : public Node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> hbox(Children children) {
|
std::unique_ptr<Node> hbox(Elements children) {
|
||||||
return std::make_unique<HBox>(std::move(children));
|
return std::make_unique<HBox>(std::move(children));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ using ftxui::Screen;
|
|||||||
|
|
||||||
class Inverted : public NodeDecorator {
|
class Inverted : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
Inverted(Children children) : NodeDecorator(std::move(children)) {}
|
Inverted(Elements children) : NodeDecorator(std::move(children)) {}
|
||||||
~Inverted() override {}
|
~Inverted() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -20,7 +20,7 @@ class Inverted : public NodeDecorator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> inverted(Child child) {
|
std::unique_ptr<Node> inverted(Element child) {
|
||||||
return std::make_unique<Inverted>(unpack(std::move(child)));
|
return std::make_unique<Inverted>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ namespace ftxui {
|
|||||||
// Helper class.
|
// Helper class.
|
||||||
class NodeDecorator : public Node {
|
class NodeDecorator : public Node {
|
||||||
public:
|
public:
|
||||||
NodeDecorator(Children children) : Node(std::move(children)) {}
|
NodeDecorator(Elements children) : Node(std::move(children)) {}
|
||||||
~NodeDecorator() override {}
|
~NodeDecorator() override {}
|
||||||
void ComputeRequirement() override;
|
void ComputeRequirement() override;
|
||||||
void SetBox(Box box) override;
|
void SetBox(Box box) override;
|
||||||
|
@ -7,7 +7,7 @@ using ftxui::Screen;
|
|||||||
|
|
||||||
class Underlined : public NodeDecorator {
|
class Underlined : public NodeDecorator {
|
||||||
public:
|
public:
|
||||||
Underlined(Children children) : NodeDecorator(std::move(children)) {}
|
Underlined(Elements children) : NodeDecorator(std::move(children)) {}
|
||||||
~Underlined() override {}
|
~Underlined() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
@ -20,7 +20,7 @@ class Underlined : public NodeDecorator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> underlined(Child child) {
|
std::unique_ptr<Node> underlined(Element child) {
|
||||||
return std::make_unique<Underlined>(unpack(std::move(child)));
|
return std::make_unique<Underlined>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ namespace ftxui {
|
|||||||
|
|
||||||
class VBox : public Node {
|
class VBox : public Node {
|
||||||
public:
|
public:
|
||||||
VBox(Children children) : Node(std::move(children)) {}
|
VBox(Elements children) : Node(std::move(children)) {}
|
||||||
~VBox() {}
|
~VBox() {}
|
||||||
|
|
||||||
void ComputeRequirement() {
|
void ComputeRequirement() {
|
||||||
@ -59,7 +59,7 @@ class VBox : public Node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Node> vbox(Children children) {
|
std::unique_ptr<Node> vbox(Elements children) {
|
||||||
return std::make_unique<VBox>(std::move(children));
|
return std::make_unique<VBox>(std::move(children));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user