mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 10:38:09 +08:00 
			
		
		
		
	Add menu styles.
This commit is contained in:
		| @@ -1,5 +1,4 @@ | ||||
| cmake_minimum_required(VERSION 3.0) | ||||
| project(ftxui) | ||||
|  | ||||
| add_library(ftxui | ||||
|   src/ftxui/component/component.cpp | ||||
| @@ -13,6 +12,7 @@ add_library(ftxui | ||||
|   src/ftxui/dom/bold.cpp | ||||
|   src/ftxui/dom/color.cpp | ||||
|   src/ftxui/dom/composite_decorator.cpp | ||||
|   src/ftxui/dom/dbox.cpp | ||||
|   src/ftxui/dom/dim.cpp | ||||
|   src/ftxui/dom/flex.cpp | ||||
|   src/ftxui/dom/frame.cpp | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #define FTXUI_COMPONENT_MENU | ||||
|  | ||||
| #include "ftxui/component/component.hpp" | ||||
| #include "ftxui/dom/elements.hpp" | ||||
| #include <functional> | ||||
|  | ||||
| namespace ftxui { | ||||
| @@ -16,6 +17,10 @@ class Menu : public Component { | ||||
|   std::vector<std::wstring> entries = {}; | ||||
|   int selected = 0; | ||||
|  | ||||
|   dom::Decorator active_style = dom::inverted; | ||||
|   dom::Decorator selected_style = dom::bold; | ||||
|   dom::Decorator normal_style = dom::nothing; | ||||
|  | ||||
|   // State update callback. | ||||
|   std::function<void()> on_change = [](){}; | ||||
|   std::function<void()> on_enter = [](){}; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
| #include "ftxui/component/component.hpp" | ||||
| #include <functional> | ||||
| #include <string> | ||||
|  | ||||
| namespace ftxui { | ||||
| namespace component { | ||||
| @@ -13,9 +14,8 @@ class Toggle : public Component { | ||||
|   Toggle(Delegate*); | ||||
|  | ||||
|   // State. | ||||
|   bool activated = true; | ||||
|   std::wstring on = L"On"; | ||||
|   std::wstring off = L"Off"; | ||||
|   size_t activated = 0; | ||||
|   std::vector<std::wstring> options = {L"On", L"Off"}; | ||||
|  | ||||
|   // Callback. | ||||
|   std::function<void()> on_change = [](){}; | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| #ifndef FTXUI_DOM_ELEMENTS_HPP | ||||
| #define FTXUI_DOM_ELEMENTS_HPP | ||||
|  | ||||
| #include <functional> | ||||
|  | ||||
| #include "ftxui/color.hpp" | ||||
| #include "ftxui/dom/node.hpp" | ||||
|  | ||||
| @@ -8,12 +10,14 @@ namespace ftxui { | ||||
| namespace dom { | ||||
|  | ||||
| using Element = std::unique_ptr<Node>; | ||||
| using Decorator = std::function<Element(Element)>; | ||||
| using Child = std::unique_ptr<Node>; | ||||
| using Children = std::vector<Child>; | ||||
|  | ||||
| // --- Layout ---- | ||||
| Element vbox(Children); | ||||
| Element hbox(Children); | ||||
| Element dbox(Children); | ||||
| Element flex(); | ||||
| Element flex(Element); | ||||
|  | ||||
| @@ -32,6 +36,8 @@ Element underlined(Element); | ||||
| Element blink(Element); | ||||
| Element color(Color, Element); | ||||
| Element bgcolor(Color, Element); | ||||
| Decorator color(Color); | ||||
| Decorator bgcolor(Color); | ||||
|  | ||||
| // --- Util --- | ||||
| Element hcenter(Element); | ||||
| @@ -40,6 +46,7 @@ Element center(Element); | ||||
|  | ||||
| // --- Util --- | ||||
| Element nothing(Element element); | ||||
| Decorator compose(Decorator, Decorator); | ||||
|  | ||||
| template <class... Args> | ||||
| Children unpack(Args... args) { | ||||
| @@ -58,6 +65,11 @@ Element hbox(Args... children) { | ||||
|   return hbox(unpack(std::forward<Args>(children)...)); | ||||
| } | ||||
|  | ||||
| template <class... Args> | ||||
| Element dbox(Args... children) { | ||||
|   return dbox(unpack(std::forward<Args>(children)...)); | ||||
| } | ||||
|  | ||||
| };  // namespace dom | ||||
| };  // namespace ftxui | ||||
|  | ||||
|   | ||||
| @@ -24,9 +24,6 @@ dom::Element Input::Render() { | ||||
|   if (!is_focused) | ||||
|     return flex(text(content)); | ||||
|  | ||||
|   std::wstring sub_content = content; | ||||
|   size_t sub_cursor_position = cursor_position; | ||||
|  | ||||
|   std::wstring part_before_cursor = content.substr(0,cursor_position); | ||||
|   std::wstring part_at_cursor = cursor_position < (int)content.size() | ||||
|                                     ? content.substr(cursor_position, 1) | ||||
|   | ||||
| @@ -14,12 +14,12 @@ dom::Element Menu::Render() { | ||||
|   for (size_t i = 0; i < entries.size(); ++i) { | ||||
|     if (size_t(selected) == i) { | ||||
|       if (focused) | ||||
|         elements.push_back(inverted(text(L"> " + entries[i]))); | ||||
|         elements.push_back(active_style(text(L"> " + entries[i]))); | ||||
|       else | ||||
|         elements.push_back(bold(text(L"> " + entries[i]))); | ||||
|         elements.push_back(selected_style(text(L"> " + entries[i]))); | ||||
|     } | ||||
|     else { | ||||
|       elements.push_back(text(L"  " + entries[i])); | ||||
|       elements.push_back(normal_style(text(L"  " + entries[i]))); | ||||
|     } | ||||
|   } | ||||
|   return vbox(std::move(elements)); | ||||
|   | ||||
| @@ -11,32 +11,33 @@ dom::Element Toggle::Render() { | ||||
|  | ||||
|   Children children; | ||||
|   children.push_back(text(L"[")); | ||||
|   if (activated) { | ||||
|     children.push_back(highlight(text(on))); | ||||
|     children.push_back(text(L"|")); | ||||
|     children.push_back(dim(text(off))); | ||||
|   } else { | ||||
|     children.push_back(dim(text(on))); | ||||
|     children.push_back(text(L"|")); | ||||
|     children.push_back(highlight(text(off))); | ||||
|  | ||||
|   for(size_t i = 0; i<options.size(); ++i) { | ||||
|     // Separator. | ||||
|     if (i != 0) | ||||
|       children.push_back(text(L"|")); | ||||
|  | ||||
|     // Entry. | ||||
|     auto style = i == activated ? highlight : dim; | ||||
|     children.push_back(style(text(options[i]))); | ||||
|   } | ||||
|   children.push_back(text(L"]")); | ||||
|   return hbox(std::move(children)); | ||||
| } | ||||
|  | ||||
| bool Toggle::OnEvent(Event event) { | ||||
|   if (activated) { | ||||
|     if (event == Event::ArrowRight || event == Event::Character('l')) { | ||||
|       activated = false; | ||||
|       on_change(); | ||||
|       return true; | ||||
|     } | ||||
|   } else { | ||||
|     if (event == Event::ArrowLeft || event == Event::Character('h')) { | ||||
|       activated = true; | ||||
|       on_change(); | ||||
|       return true; | ||||
|     } | ||||
|   if (activated > 0 && | ||||
|       (event == Event::ArrowLeft || event == Event::Character('h'))) { | ||||
|     activated--; | ||||
|     on_change(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   if (activated < options.size() - 1 && | ||||
|       (event == Event::ArrowRight || event == Event::Character('l'))) { | ||||
|     activated++; | ||||
|     on_change(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
|   | ||||
| @@ -47,5 +47,17 @@ std::unique_ptr<Node> bgcolor(Color c, Child child) { | ||||
|   return std::make_unique<BgColor>(unpack(std::move(child)), c); | ||||
| } | ||||
|  | ||||
| Decorator color(Color c) { | ||||
|   return [c](Child child) { | ||||
|     return color(c, std::move(child)); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| Decorator bgcolor(Color c) { | ||||
|   return [c](Child child) { | ||||
|     return bgcolor(c, std::move(child)); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| };  // namespace dom | ||||
| };  // namespace ftxui | ||||
|   | ||||
							
								
								
									
										37
									
								
								ftxui/src/ftxui/dom/dbox.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ftxui/src/ftxui/dom/dbox.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #include "ftxui/dom/node.hpp" | ||||
| #include "ftxui/dom/elements.hpp" | ||||
|  | ||||
| namespace ftxui { | ||||
| namespace dom { | ||||
|  | ||||
| class DBox : public Node { | ||||
|  public: | ||||
|   DBox(Children children) : Node(std::move(children)) {} | ||||
|   ~DBox() {} | ||||
|  | ||||
|   void ComputeRequirement() override { | ||||
|     requirement_.min.x = 0; | ||||
|     requirement_.min.y = 0; | ||||
|     requirement_.flex.x = 1; | ||||
|     requirement_.flex.y = 0; | ||||
|     for (auto& child : children) { | ||||
|       child->ComputeRequirement(); | ||||
|       requirement_.min.x = std::max(requirement_.min.x, child->requirement().min.x); | ||||
|       requirement_.min.y = std::max(requirement_.min.y, child->requirement().min.y); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void SetBox(Box box) override { | ||||
|     Node::SetBox(box); | ||||
|  | ||||
|     for (auto& child : children) | ||||
|       child->SetBox(box); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| std::unique_ptr<Node> dbox(Children children) { | ||||
|   return std::make_unique<DBox>(std::move(children)); | ||||
| } | ||||
|  | ||||
| };  // namespace dom | ||||
| };  // namespace ftxui | ||||
| @@ -7,5 +7,14 @@ Element nothing(Element element) { | ||||
|   return std::move(element); | ||||
| } | ||||
|  | ||||
| Decorator compose(Decorator a, Decorator b) { | ||||
|   return [ | ||||
|     a = std::move(a), | ||||
|     b = std::move(b) | ||||
|   ](Element element) { | ||||
|     return a(b(std::move(element))); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| };  // namespace dom | ||||
| };  // namespace ftxui | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni