Add option for Toggle.

This commit is contained in:
ArthurSonzogni 2021-07-10 11:03:01 +02:00 committed by Arthur Sonzogni
parent ae6473363d
commit fac373494d
7 changed files with 43 additions and 29 deletions

View File

@ -23,7 +23,7 @@ class ButtonBase : public ComponentBase {
// Constructor. // Constructor.
ButtonBase(ConstStringRef label, ButtonBase(ConstStringRef label,
std::function<void()> on_click, std::function<void()> on_click,
ConstRef<ButtonOption> option); ConstRef<ButtonOption> option = {});
~ButtonBase() override = default; ~ButtonBase() override = default;
// Component implementation. // Component implementation.

View File

@ -39,7 +39,9 @@ Component Menu(const std::vector<std::wstring>* entries,
Component Radiobox(const std::vector<std::wstring>* entries, Component Radiobox(const std::vector<std::wstring>* entries,
int* selected_, int* selected_,
ConstRef<RadioboxOption> option = {}); ConstRef<RadioboxOption> option = {});
Component Toggle(const std::vector<std::wstring>* entries, int* selected); Component Toggle(const std::vector<std::wstring>* entries,
int* selected,
ConstRef<ToggleOption> option = {});
template <class T> // T = {int, float, long} template <class T> // T = {int, float, long}
Component Slider(StringRef label, T* value, T min, T max, T increment); Component Slider(StringRef label, T* value, T min, T max, T increment);
Component Renderer(Component child, std::function<Element()>); Component Renderer(Component child, std::function<Element()>);

View File

@ -46,6 +46,17 @@ struct RadioboxOption {
std::function<void()> on_change = []() {}; std::function<void()> on_change = []() {};
}; };
struct ToggleOption {
Decorator normal_style = dim;
Decorator focused_style = inverted;
Decorator selected_style = bold;
Decorator selected_focused_style = focused_style | selected_style;
// Callback.
std::function<void()> on_change = []() {};
std::function<void()> on_enter = []() {};
};
}; // namespace ftxui }; // namespace ftxui
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */ #endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */

View File

@ -24,7 +24,7 @@ class RadioboxBase : public ComponentBase {
// Constructor. // Constructor.
RadioboxBase(const std::vector<std::wstring>* entries, RadioboxBase(const std::vector<std::wstring>* entries,
int* selected, int* selected,
ConstRef<RadioboxOption> option); ConstRef<RadioboxOption> option = {});
~RadioboxBase() override = default; ~RadioboxBase() override = default;
int focused = 0; int focused = 0;

View File

@ -21,21 +21,14 @@ class ToggleBase : public ComponentBase {
static ToggleBase* From(Component component); static ToggleBase* From(Component component);
// Constructor. // Constructor.
ToggleBase(const std::vector<std::wstring>* entries, int* selected); ToggleBase(const std::vector<std::wstring>* entries,
int* selected,
ConstRef<ToggleOption> option = {});
~ToggleBase() override = default; ~ToggleBase() override = default;
// State. // State.
int focused = 0; int focused = 0;
Decorator normal_style = dim;
Decorator focused_style = inverted;
Decorator selected_style = bold;
Decorator selected_focused_style = focused_style | selected_style;
// Callback.
std::function<void()> on_change = []() {};
std::function<void()> on_enter = []() {};
// Component implementation. // Component implementation.
Element Render() override; Element Render() override;
bool OnEvent(Event) override; bool OnEvent(Event) override;
@ -46,6 +39,7 @@ class ToggleBase : public ComponentBase {
bool OnMouseEvent(Event event); bool OnMouseEvent(Event event);
std::vector<Box> boxes_; std::vector<Box> boxes_;
ConstRef<ToggleOption> option_;
}; };
} // namespace ftxui } // namespace ftxui

View File

@ -10,8 +10,10 @@
namespace ftxui { namespace ftxui {
Component Toggle(const std::vector<std::wstring>* entries, int* selected) { Component Toggle(const std::vector<std::wstring>* entries,
return Make<ToggleBase>(entries, selected); int* selected,
ConstRef<ToggleOption> option) {
return Make<ToggleBase>(entries, selected, std::move(option));
} }
// static // static
@ -19,8 +21,10 @@ ToggleBase* ToggleBase::From(Component component) {
return static_cast<ToggleBase*>(component.get()); return static_cast<ToggleBase*>(component.get());
} }
ToggleBase::ToggleBase(const std::vector<std::wstring>* entries, int* selected) ToggleBase::ToggleBase(const std::vector<std::wstring>* entries,
: entries_(entries), selected_(selected) {} int* selected,
ConstRef<ToggleOption> option)
: entries_(entries), selected_(selected), option_(std::move(option)) {}
Element ToggleBase::Render() { Element ToggleBase::Render() {
Elements children; Elements children;
@ -34,9 +38,10 @@ Element ToggleBase::Render() {
bool is_focused = (focused == int(i)) && is_toggle_focused; bool is_focused = (focused == int(i)) && is_toggle_focused;
bool is_selected = (*selected_ == int(i)); bool is_selected = (*selected_ == int(i));
auto style = is_selected auto style = is_selected ? (is_focused ? option_->selected_focused_style
? (is_focused ? selected_focused_style : selected_style) : option_->selected_style)
: (is_focused ? focused_style : normal_style); : (is_focused ? option_->focused_style
: option_->normal_style);
auto focus_management = !is_selected ? nothing auto focus_management = !is_selected ? nothing
: is_toggle_focused ? focus : is_toggle_focused ? focus
: select; : select;
@ -64,12 +69,12 @@ bool ToggleBase::OnEvent(Event event) {
if (old_selected != *selected_) { if (old_selected != *selected_) {
focused = *selected_; focused = *selected_;
on_change(); option_->on_change();
return true; return true;
} }
if (event == Event::Return) { if (event == Event::Return) {
on_enter(); option_->on_enter();
return true; return true;
} }
@ -90,7 +95,7 @@ bool ToggleBase::OnMouseEvent(Event event) {
TakeFocus(); TakeFocus();
if (*selected_ != i) { if (*selected_ != i) {
*selected_ = i; *selected_ = i;
on_change(); option_->on_change();
} }
return true; return true;
} }

View File

@ -83,10 +83,11 @@ TEST(ToggleTest, Tab) {
TEST(ToggleTest, OnChange) { TEST(ToggleTest, OnChange) {
std::vector<std::wstring> entries = {L"1", L"2", L"3"}; std::vector<std::wstring> entries = {L"1", L"2", L"3"};
int selected = 0; int selected = 0;
auto toggle = Toggle(&entries, &selected);
int counter = 0; int counter = 0;
ToggleBase::From(toggle)->on_change = [&] { counter++; }; auto option = ToggleOption();
option.on_change = [&] { counter++; };
auto toggle = Toggle(&entries, &selected, &option);
EXPECT_FALSE(toggle->OnEvent(Event::ArrowLeft)); // Reached far left. EXPECT_FALSE(toggle->OnEvent(Event::ArrowLeft)); // Reached far left.
EXPECT_EQ(counter, 0); EXPECT_EQ(counter, 0);
@ -111,10 +112,11 @@ TEST(ToggleTest, OnChange) {
TEST(ToggleTest, OnEnter) { TEST(ToggleTest, OnEnter) {
std::vector<std::wstring> entries = {L"1", L"2", L"3"}; std::vector<std::wstring> entries = {L"1", L"2", L"3"};
int selected = 0; int selected = 0;
auto toggle = Toggle(&entries, &selected);
int counter = 0; int counter = 0;
ToggleBase::From(toggle)->on_enter = [&] { counter++; };
auto option = ToggleOption();
option.on_enter = [&] { counter++; };
auto toggle = Toggle(&entries, &selected, &option);
EXPECT_FALSE(toggle->OnEvent(Event::ArrowLeft)); // Reached far left. EXPECT_FALSE(toggle->OnEvent(Event::ArrowLeft)); // Reached far left.
EXPECT_TRUE(toggle->OnEvent(Event::Return)); EXPECT_TRUE(toggle->OnEvent(Event::Return));