diff --git a/include/ftxui/component/button.hpp b/include/ftxui/component/button.hpp index 5623c66..1765f64 100644 --- a/include/ftxui/component/button.hpp +++ b/include/ftxui/component/button.hpp @@ -23,7 +23,7 @@ class ButtonBase : public ComponentBase { // Constructor. ButtonBase(ConstStringRef label, std::function on_click, - ConstRef option); + ConstRef option = {}); ~ButtonBase() override = default; // Component implementation. diff --git a/include/ftxui/component/component.hpp b/include/ftxui/component/component.hpp index f8624cd..06faecb 100644 --- a/include/ftxui/component/component.hpp +++ b/include/ftxui/component/component.hpp @@ -39,7 +39,9 @@ Component Menu(const std::vector* entries, Component Radiobox(const std::vector* entries, int* selected_, ConstRef option = {}); -Component Toggle(const std::vector* entries, int* selected); +Component Toggle(const std::vector* entries, + int* selected, + ConstRef option = {}); template // T = {int, float, long} Component Slider(StringRef label, T* value, T min, T max, T increment); Component Renderer(Component child, std::function); diff --git a/include/ftxui/component/component_options.hpp b/include/ftxui/component/component_options.hpp index 13f69d2..a734178 100644 --- a/include/ftxui/component/component_options.hpp +++ b/include/ftxui/component/component_options.hpp @@ -46,6 +46,17 @@ struct RadioboxOption { std::function 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 on_change = []() {}; + std::function on_enter = []() {}; +}; + }; // namespace ftxui #endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */ diff --git a/include/ftxui/component/radiobox.hpp b/include/ftxui/component/radiobox.hpp index 897a7fe..82850e2 100644 --- a/include/ftxui/component/radiobox.hpp +++ b/include/ftxui/component/radiobox.hpp @@ -24,7 +24,7 @@ class RadioboxBase : public ComponentBase { // Constructor. RadioboxBase(const std::vector* entries, int* selected, - ConstRef option); + ConstRef option = {}); ~RadioboxBase() override = default; int focused = 0; diff --git a/include/ftxui/component/toggle.hpp b/include/ftxui/component/toggle.hpp index af2f22a..e54faa0 100644 --- a/include/ftxui/component/toggle.hpp +++ b/include/ftxui/component/toggle.hpp @@ -21,21 +21,14 @@ class ToggleBase : public ComponentBase { static ToggleBase* From(Component component); // Constructor. - ToggleBase(const std::vector* entries, int* selected); + ToggleBase(const std::vector* entries, + int* selected, + ConstRef option = {}); ~ToggleBase() override = default; // State. 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 on_change = []() {}; - std::function on_enter = []() {}; - // Component implementation. Element Render() override; bool OnEvent(Event) override; @@ -46,6 +39,7 @@ class ToggleBase : public ComponentBase { bool OnMouseEvent(Event event); std::vector boxes_; + ConstRef option_; }; } // namespace ftxui diff --git a/src/ftxui/component/toggle.cpp b/src/ftxui/component/toggle.cpp index ca00069..72a2860 100644 --- a/src/ftxui/component/toggle.cpp +++ b/src/ftxui/component/toggle.cpp @@ -10,8 +10,10 @@ namespace ftxui { -Component Toggle(const std::vector* entries, int* selected) { - return Make(entries, selected); +Component Toggle(const std::vector* entries, + int* selected, + ConstRef option) { + return Make(entries, selected, std::move(option)); } // static @@ -19,8 +21,10 @@ ToggleBase* ToggleBase::From(Component component) { return static_cast(component.get()); } -ToggleBase::ToggleBase(const std::vector* entries, int* selected) - : entries_(entries), selected_(selected) {} +ToggleBase::ToggleBase(const std::vector* entries, + int* selected, + ConstRef option) + : entries_(entries), selected_(selected), option_(std::move(option)) {} Element ToggleBase::Render() { Elements children; @@ -34,9 +38,10 @@ Element ToggleBase::Render() { bool is_focused = (focused == int(i)) && is_toggle_focused; bool is_selected = (*selected_ == int(i)); - auto style = is_selected - ? (is_focused ? selected_focused_style : selected_style) - : (is_focused ? focused_style : normal_style); + auto style = is_selected ? (is_focused ? option_->selected_focused_style + : option_->selected_style) + : (is_focused ? option_->focused_style + : option_->normal_style); auto focus_management = !is_selected ? nothing : is_toggle_focused ? focus : select; @@ -64,12 +69,12 @@ bool ToggleBase::OnEvent(Event event) { if (old_selected != *selected_) { focused = *selected_; - on_change(); + option_->on_change(); return true; } if (event == Event::Return) { - on_enter(); + option_->on_enter(); return true; } @@ -90,7 +95,7 @@ bool ToggleBase::OnMouseEvent(Event event) { TakeFocus(); if (*selected_ != i) { *selected_ = i; - on_change(); + option_->on_change(); } return true; } diff --git a/src/ftxui/component/toggle_test.cpp b/src/ftxui/component/toggle_test.cpp index f25e84d..d4752f3 100644 --- a/src/ftxui/component/toggle_test.cpp +++ b/src/ftxui/component/toggle_test.cpp @@ -83,10 +83,11 @@ TEST(ToggleTest, Tab) { TEST(ToggleTest, OnChange) { std::vector entries = {L"1", L"2", L"3"}; int selected = 0; - auto toggle = Toggle(&entries, &selected); - 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_EQ(counter, 0); @@ -111,10 +112,11 @@ TEST(ToggleTest, OnChange) { TEST(ToggleTest, OnEnter) { std::vector entries = {L"1", L"2", L"3"}; int selected = 0; - auto toggle = Toggle(&entries, &selected); - 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_TRUE(toggle->OnEvent(Event::Return));