mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 18:48:11 +08:00 
			
		
		
		
	Add option for Toggle.
This commit is contained in:
		 ArthurSonzogni
					ArthurSonzogni
				
			
				
					committed by
					
						 Arthur Sonzogni
						Arthur Sonzogni
					
				
			
			
				
	
			
			
			 Arthur Sonzogni
						Arthur Sonzogni
					
				
			
						parent
						
							ae6473363d
						
					
				
				
					commit
					fac373494d
				
			| @@ -23,7 +23,7 @@ class ButtonBase : public ComponentBase { | ||||
|   // Constructor. | ||||
|   ButtonBase(ConstStringRef label, | ||||
|              std::function<void()> on_click, | ||||
|              ConstRef<ButtonOption> option); | ||||
|              ConstRef<ButtonOption> option = {}); | ||||
|   ~ButtonBase() override = default; | ||||
|  | ||||
|   // Component implementation. | ||||
|   | ||||
| @@ -39,7 +39,9 @@ Component Menu(const std::vector<std::wstring>* entries, | ||||
| Component Radiobox(const std::vector<std::wstring>* entries, | ||||
|                    int* selected_, | ||||
|                    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} | ||||
| Component Slider(StringRef label, T* value, T min, T max, T increment); | ||||
| Component Renderer(Component child, std::function<Element()>); | ||||
|   | ||||
| @@ -46,6 +46,17 @@ struct RadioboxOption { | ||||
|   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 | ||||
|  | ||||
| #endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */ | ||||
|   | ||||
| @@ -24,7 +24,7 @@ class RadioboxBase : public ComponentBase { | ||||
|   // Constructor. | ||||
|   RadioboxBase(const std::vector<std::wstring>* entries, | ||||
|                int* selected, | ||||
|                ConstRef<RadioboxOption> option); | ||||
|                ConstRef<RadioboxOption> option = {}); | ||||
|   ~RadioboxBase() override = default; | ||||
|  | ||||
|   int focused = 0; | ||||
|   | ||||
| @@ -21,21 +21,14 @@ class ToggleBase : public ComponentBase { | ||||
|   static ToggleBase* From(Component component); | ||||
|  | ||||
|   // 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; | ||||
|  | ||||
|   // 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<void()> on_change = []() {}; | ||||
|   std::function<void()> 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<Box> boxes_; | ||||
|   ConstRef<ToggleOption> option_; | ||||
| }; | ||||
|  | ||||
| }  // namespace ftxui | ||||
|   | ||||
| @@ -10,8 +10,10 @@ | ||||
|  | ||||
| namespace ftxui { | ||||
|  | ||||
| Component Toggle(const std::vector<std::wstring>* entries, int* selected) { | ||||
|   return Make<ToggleBase>(entries, selected); | ||||
| Component Toggle(const std::vector<std::wstring>* entries, | ||||
|                  int* selected, | ||||
|                  ConstRef<ToggleOption> option) { | ||||
|   return Make<ToggleBase>(entries, selected, std::move(option)); | ||||
| } | ||||
|  | ||||
| // static | ||||
| @@ -19,8 +21,10 @@ ToggleBase* ToggleBase::From(Component component) { | ||||
|   return static_cast<ToggleBase*>(component.get()); | ||||
| } | ||||
|  | ||||
| ToggleBase::ToggleBase(const std::vector<std::wstring>* entries, int* selected) | ||||
|     : entries_(entries), selected_(selected) {} | ||||
| ToggleBase::ToggleBase(const std::vector<std::wstring>* entries, | ||||
|                        int* selected, | ||||
|                        ConstRef<ToggleOption> 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; | ||||
|     } | ||||
|   | ||||
| @@ -83,10 +83,11 @@ TEST(ToggleTest, Tab) { | ||||
| TEST(ToggleTest, OnChange) { | ||||
|   std::vector<std::wstring> 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<std::wstring> 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)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user