mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 18:48:11 +08:00 
			
		
		
		
	Add hflow.
This commit is contained in:
		| @@ -73,7 +73,7 @@ class MyComponent : public Component { | |||||||
|         separator(), |         separator(), | ||||||
|         Render(L"radiobox", radiobox), |         Render(L"radiobox", radiobox), | ||||||
|         separator(), |         separator(), | ||||||
|         Render(L"input", input) |         Render(L"input", input) | size(WIDTH, EQUAL, 20) | ||||||
|       ) | border; |       ) | border; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -16,4 +16,6 @@ example(style_dim) | |||||||
| example(style_gallery) | example(style_gallery) | ||||||
| example(style_inverted) | example(style_inverted) | ||||||
| example(style_underlined) | example(style_underlined) | ||||||
|  | example(size) | ||||||
| example(vbox_hbox) | example(vbox_hbox) | ||||||
|  | example(hflow) | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								examples/dom/hflow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								examples/dom/hflow.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | #include "ftxui/screen/screen.hpp" | ||||||
|  | #include "ftxui/screen/string.hpp" | ||||||
|  | #include "ftxui/dom/elements.hpp" | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  | int main(int argc, const char *argv[]) | ||||||
|  | { | ||||||
|  |   using namespace ftxui; | ||||||
|  |   auto make_box = [](size_t dimx, size_t dimy) { | ||||||
|  |     std::wstring title = to_wstring(dimx) + L"x" + to_wstring(dimy); | ||||||
|  |     return | ||||||
|  |       window( | ||||||
|  |         text(title) | hcenter | bold, | ||||||
|  |         text(L"content") | hcenter | dim | ||||||
|  |       ) | size(WIDTH, EQUAL, dimx) | ||||||
|  |         | size(HEIGHT, EQUAL, dimy) | ||||||
|  |         ; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   auto document = | ||||||
|  |     hflow( | ||||||
|  |       make_box(7,7), | ||||||
|  |       make_box(7,5), | ||||||
|  |       make_box(5,7), | ||||||
|  |       make_box(10,4), | ||||||
|  |       make_box(10,4), | ||||||
|  |       make_box(10,4), | ||||||
|  |       make_box(10,4), | ||||||
|  |       make_box(11,4), | ||||||
|  |       make_box(11,4), | ||||||
|  |       make_box(11,4), | ||||||
|  |       make_box(11,4), | ||||||
|  |       make_box(12,4), | ||||||
|  |       make_box(12,5), | ||||||
|  |       make_box(12,4), | ||||||
|  |       make_box(13,4), | ||||||
|  |       make_box(13,3), | ||||||
|  |       make_box(13,3), | ||||||
|  |       make_box(10,3) | ||||||
|  |     ) | size(WIDTH, GREATER_THAN, 20) | ||||||
|  |       | border | ||||||
|  |       | size(HEIGHT, GREATER_THAN, 30) | ||||||
|  |       | size(WIDTH, LESS_THAN, 50) | ||||||
|  |       ; | ||||||
|  |  | ||||||
|  |   auto screen = Screen::TerminalOutput(document); | ||||||
|  |   Render(screen, document.get()); | ||||||
|  |   std::cout << screen.ToString() << std::endl; | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								examples/dom/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								examples/dom/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | #include "ftxui/screen/screen.hpp" | ||||||
|  | #include "ftxui/screen/string.hpp" | ||||||
|  | #include "ftxui/dom/elements.hpp" | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  | int main(int argc, const char *argv[]) | ||||||
|  | { | ||||||
|  |   using namespace ftxui; | ||||||
|  |   auto make_box = [](const std::wstring title) { | ||||||
|  |     return | ||||||
|  |       window( | ||||||
|  |         text(title) | hcenter | bold, | ||||||
|  |         text(L"content") | hcenter | dim | ||||||
|  |       ); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   Elements content; | ||||||
|  |   for(int x = 3; x<30; ++x) { | ||||||
|  |     content.push_back( | ||||||
|  |       make_box(to_wstring(x)) | ||||||
|  |         | size(WIDTH, EQUAL, x) | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |   auto document = hbox(std::move(content)); | ||||||
|  |   auto screen = Screen::FitDocument(document); | ||||||
|  |   Render(screen, document.get()); | ||||||
|  |   std::cout << screen.ToString() << std::endl; | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
| @@ -19,6 +19,7 @@ add_library(dom | |||||||
|   src/ftxui/dom/frame.cpp |   src/ftxui/dom/frame.cpp | ||||||
|   src/ftxui/dom/gauge.cpp |   src/ftxui/dom/gauge.cpp | ||||||
|   src/ftxui/dom/hbox.cpp |   src/ftxui/dom/hbox.cpp | ||||||
|  |   src/ftxui/dom/hflow.cpp | ||||||
|   src/ftxui/dom/inverted.cpp |   src/ftxui/dom/inverted.cpp | ||||||
|   src/ftxui/dom/node.cpp |   src/ftxui/dom/node.cpp | ||||||
|   src/ftxui/dom/node_decorator.cpp |   src/ftxui/dom/node_decorator.cpp | ||||||
|   | |||||||
| @@ -33,9 +33,10 @@ Element bgcolor(Color, Element); | |||||||
|  |  | ||||||
| // --- Layout --- | // --- Layout --- | ||||||
| // Horizontal, Vertical or stacked set of elements. | // Horizontal, Vertical or stacked set of elements. | ||||||
| Element vbox(Elements); |  | ||||||
| Element hbox(Elements); | Element hbox(Elements); | ||||||
|  | Element vbox(Elements); | ||||||
| Element dbox(Elements); | Element dbox(Elements); | ||||||
|  | Element hflow(Elements); | ||||||
|  |  | ||||||
| // -- Flexibility --- | // -- Flexibility --- | ||||||
| // Define how to share the remaining space when not all of it is used inside a | // Define how to share the remaining space when not all of it is used inside a | ||||||
| @@ -73,6 +74,7 @@ Decorator operator|(Decorator, Decorator); | |||||||
| TAKE_ANY_ARGS(vbox) | TAKE_ANY_ARGS(vbox) | ||||||
| TAKE_ANY_ARGS(hbox) | TAKE_ANY_ARGS(hbox) | ||||||
| TAKE_ANY_ARGS(dbox) | TAKE_ANY_ARGS(dbox) | ||||||
|  | TAKE_ANY_ARGS(hflow) | ||||||
|  |  | ||||||
| };  // namespace ftxui | };  // namespace ftxui | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ class Screen { | |||||||
|   // Constructor using the terminal. |   // Constructor using the terminal. | ||||||
|   static Screen TerminalFullscreen(); |   static Screen TerminalFullscreen(); | ||||||
|   static Screen TerminalOutput(std::unique_ptr<Node>& element); |   static Screen TerminalOutput(std::unique_ptr<Node>& element); | ||||||
|  |   static Screen FitDocument(std::unique_ptr<Node>& element); | ||||||
|  |  | ||||||
|   // Node write into the screen using Screen::at. |   // Node write into the screen using Screen::at. | ||||||
|   wchar_t& at(size_t x, size_t y); |   wchar_t& at(size_t x, size_t y); | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								ftxui/src/ftxui/dom/hflow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								ftxui/src/ftxui/dom/hflow.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | #include "ftxui/dom/node.hpp" | ||||||
|  | #include "ftxui/dom/elements.hpp" | ||||||
|  |  | ||||||
|  | namespace ftxui { | ||||||
|  |  | ||||||
|  | class HFlow : public Node { | ||||||
|  |  public: | ||||||
|  |   HFlow(Elements children) : Node(std::move(children)) {} | ||||||
|  |   ~HFlow() {} | ||||||
|  |  | ||||||
|  |   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(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void SetBox(Box box) override { | ||||||
|  |     Node::SetBox(box); | ||||||
|  |  | ||||||
|  |     // The position of the first component. | ||||||
|  |     int x = box.x_min; | ||||||
|  |     int y = box.y_min; | ||||||
|  |     int y_next = y; // The position of next row of elements. | ||||||
|  |  | ||||||
|  |     for (auto& child : children) { | ||||||
|  |       Requirement requirement = child->requirement(); | ||||||
|  |  | ||||||
|  |       // Does it fit the end of the row? | ||||||
|  |       if (x + requirement.min.x > box.x_max) { | ||||||
|  |         // No? Use the next row. | ||||||
|  |         x = box.x_min; | ||||||
|  |         y = y_next; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Does the current row big enough to contain the element? | ||||||
|  |       if (y + requirement.min.y > box.y_max) | ||||||
|  |         break; // No? Ignore the element. | ||||||
|  |  | ||||||
|  |       Box children_box; | ||||||
|  |       children_box.x_min = x; | ||||||
|  |       children_box.x_max = x + requirement.min.x; | ||||||
|  |       children_box.y_min = y; | ||||||
|  |       children_box.y_max = y + requirement.min.y; | ||||||
|  |       child->SetBox(children_box); | ||||||
|  |  | ||||||
|  |       x = x + requirement.min.x + 1; | ||||||
|  |       y_next = std::max(y_next, y + requirement.min.y + 1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | std::unique_ptr<Node> hflow(Elements children) { | ||||||
|  |   return std::make_unique<HFlow>(std::move(children)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | };  // namespace ftxui | ||||||
| @@ -39,6 +39,8 @@ class Size : public Node { | |||||||
|  |  | ||||||
|   void SetBox(Box box) override { |   void SetBox(Box box) override { | ||||||
|     Node::SetBox(box); |     Node::SetBox(box); | ||||||
|  |     if (constraint_ == LESS_THAN) | ||||||
|  |       box.x_max = std::min(box.x_min + value_ + 1, box.x_max); | ||||||
|     children[0]->SetBox(box); |     children[0]->SetBox(box); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -109,6 +109,17 @@ Screen Screen::TerminalOutput(std::unique_ptr<Node>& element) { | |||||||
|   return Screen(size.dimx, element->requirement().min.y); |   return Screen(size.dimx, element->requirement().min.y); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // static | ||||||
|  | Screen Screen::FitDocument(std::unique_ptr<Node>& element) { | ||||||
|  |   element->ComputeRequirement(); | ||||||
|  |   Terminal::Dimensions size = Terminal::Size(); | ||||||
|  |   return | ||||||
|  |     Screen( | ||||||
|  |       std::min(size.dimx, element->requirement().min.x), | ||||||
|  |       std::min(size.dimy, element->requirement().min.y) | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
| std::string Screen::ResetPosition() { | std::string Screen::ResetPosition() { | ||||||
|   std::stringstream ss; |   std::stringstream ss; | ||||||
|   ss << MOVE_LEFT << CLEAR_LINE; |   ss << MOVE_LEFT << CLEAR_LINE; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni