mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 10:38:09 +08:00 
			
		
		
		
	Implement flexbox (#277)
This implement the flexbox elements, following the HTML one. Built from them, there is also the following elements: - `paragraph` - `paragraphAlignLeft` - `paragraphAlignRight` - `paragraphAlignCenter` - `paragraphAlignJustify` This is a breaking change.
This commit is contained in:
		| @@ -4,6 +4,7 @@ | ||||
| #include <functional> | ||||
| #include <memory> | ||||
|  | ||||
| #include "ftxui/dom/flexbox_config.hpp" | ||||
| #include "ftxui/dom/node.hpp" | ||||
| #include "ftxui/screen/box.hpp" | ||||
| #include "ftxui/screen/color.hpp" | ||||
| @@ -49,7 +50,11 @@ Decorator borderStyled(BorderStyle); | ||||
| Decorator borderWith(Pixel); | ||||
| Element window(Element title, Element content); | ||||
| Element spinner(int charset_index, size_t image_index); | ||||
| Elements paragraph(std::string text);  // Use inside hflow(). Split by space. | ||||
| Element paragraph(std::string text); | ||||
| Element paragraphAlignLeft(std::string text); | ||||
| Element paragraphAlignRight(std::string text); | ||||
| Element paragraphAlignCenter(std::string text); | ||||
| Element paragraphAlignJustify(std::string text); | ||||
| Element graph(GraphFunction); | ||||
| Element emptyElement(); | ||||
|  | ||||
| @@ -69,8 +74,11 @@ Element bgcolor(Color, Element); | ||||
| Element hbox(Elements); | ||||
| Element vbox(Elements); | ||||
| Element dbox(Elements); | ||||
| Element flexbox(Elements, FlexboxConfig config = FlexboxConfig()); | ||||
| Element gridbox(std::vector<Elements> lines); | ||||
| Element hflow(Elements); | ||||
|  | ||||
| Element hflow(Elements);  // Helper: default flexbox with row direction. | ||||
| Element vflow(Elements);  // Helper: default flexbox with column direction. | ||||
|  | ||||
| // -- Flexibility --- | ||||
| // Define how to share the remaining space when not all of it is used inside a | ||||
|   | ||||
							
								
								
									
										115
									
								
								include/ftxui/dom/flexbox_config.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								include/ftxui/dom/flexbox_config.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| #ifndef FTXUI_DOM_FLEXBOX_CONFIG_HPP | ||||
| #define FTXUI_DOM_FLEXBOX_CONFIG_HPP | ||||
|  | ||||
| /* | ||||
|   This replicate the CSS flexbox model. | ||||
|   See guide for documentation: | ||||
|   https://css-tricks.com/snippets/css/a-guide-to-flexbox/ | ||||
| */ | ||||
|  | ||||
| namespace ftxui { | ||||
|  | ||||
| struct FlexboxConfig { | ||||
|   /// This establishes the main-axis, thus defining the direction flex items are | ||||
|   /// placed in the flex container. Flexbox is (aside wrapping) single-direction | ||||
|   /// layout concept. Think of flex items as primarily laying out either in | ||||
|   /// horizontal rows or vertical columns. | ||||
|   enum class Direction { | ||||
|     Row,            ///< Flex items are laid out in a row. | ||||
|     RowInversed,    ///< Flex items are laid out in a row, but in reverse order. | ||||
|     Column,         ///< Flex items are laid out in a column. | ||||
|     ColumnInversed  ///< Flex items are laid out in a column, but in reverse | ||||
|                     ///< order. | ||||
|   }; | ||||
|   Direction direction = Direction::Row; | ||||
|  | ||||
|   /// By default, flex items will all try to fit onto one line. You can change | ||||
|   /// that and allow the items to wrap as needed with this property. | ||||
|   enum class Wrap { | ||||
|     NoWrap,        ///< Flex items will all try to fit onto one line. | ||||
|     Wrap,          ///< Flex items will wrap onto multiple lines. | ||||
|     WrapInversed,  ///< Flex items will wrap onto multiple lines, but in reverse | ||||
|                    ///< order. | ||||
|   }; | ||||
|   Wrap wrap = Wrap::Wrap; | ||||
|  | ||||
|   /// This defines the alignment along the main axis. It helps distribute extra | ||||
|   /// free space leftover when either all the flex items on a line are | ||||
|   /// inflexible, or are flexible but have reached their maximum size. It also | ||||
|   /// exerts some control over the alignment of items when they overflow the | ||||
|   /// line. | ||||
|   enum class JustifyContent { | ||||
|     /// Items are aligned to the start of flexbox's direction. | ||||
|     FlexStart, | ||||
|     /// Items are aligned to the end of flexbox's direction. | ||||
|     FlexEnd, | ||||
|     /// Items are centered along the line. | ||||
|     Center, | ||||
|     /// Items are stretched to fill the line. | ||||
|     Stretch, | ||||
|     /// Items are evenly distributed in the line; first item is on the start | ||||
|     // line, last item on the end line | ||||
|     SpaceBetween, | ||||
|     /// Items are evenly distributed in the line with equal space around them. | ||||
|     /// Note that visually the spaces aren’t equal, since all the items have | ||||
|     /// equal space on both sides. The first item will have one unit of space | ||||
|     /// against the container edge, but two units of space between the next item | ||||
|     /// because that next item has its own spacing that applies. | ||||
|     SpaceAround, | ||||
|     /// Items are distributed so that the spacing between any two items (and the | ||||
|     /// space to the edges) is equal. | ||||
|     SpaceEvenly, | ||||
|   }; | ||||
|   JustifyContent justify_content = JustifyContent::FlexStart; | ||||
|  | ||||
|   /// This defines the default behavior for how flex items are laid out along | ||||
|   /// the cross axis on the current line. Think of it as the justify-content | ||||
|   /// version for the cross-axis (perpendicular to the main-axis). | ||||
|   enum class AlignItems { | ||||
|     FlexStart,  ///< items are placed at the start of the cross axis. | ||||
|     FlexEnd,    ///< items are placed at the end of the cross axis. | ||||
|     Center,     ///< items are centered along the cross axis. | ||||
|     Stretch,    ///< items are stretched to fill the cross axis. | ||||
|   }; | ||||
|   AlignItems align_items = AlignItems::FlexStart; | ||||
|  | ||||
|   // This aligns a flex container’s lines within when there is extra space in | ||||
|   // the cross-axis, similar to how justify-content aligns individual items | ||||
|   // within the main-axis. | ||||
|   enum class AlignContent { | ||||
|     FlexStart,     ///< items are placed at the start of the cross axis. | ||||
|     FlexEnd,       ///< items are placed at the end of the cross axis. | ||||
|     Center,        ///< items are centered along the cross axis. | ||||
|     Stretch,       ///< items are stretched to fill the cross axis. | ||||
|     SpaceBetween,  ///< items are evenly distributed in the cross axis. | ||||
|     SpaceAround,   ///< tems evenly distributed with equal space around each | ||||
|                    ///< line. | ||||
|     SpaceEvenly,  ///< items are evenly distributed in the cross axis with equal | ||||
|                   ///< space around them. | ||||
|   }; | ||||
|   AlignContent align_content = AlignContent::FlexStart; | ||||
|  | ||||
|   int gap_x = 0; | ||||
|   int gap_y = 0; | ||||
|  | ||||
|   // Constructor pattern. For chained use like: | ||||
|   // ``` | ||||
|   // FlexboxConfig() | ||||
|   //    .Set(FlexboxConfig::Direction::Row) | ||||
|   //    .Set(FlexboxConfig::Wrap::Wrap); | ||||
|   // ``` | ||||
|   FlexboxConfig& Set(FlexboxConfig::Direction); | ||||
|   FlexboxConfig& Set(FlexboxConfig::Wrap); | ||||
|   FlexboxConfig& Set(FlexboxConfig::JustifyContent); | ||||
|   FlexboxConfig& Set(FlexboxConfig::AlignItems); | ||||
|   FlexboxConfig& Set(FlexboxConfig::AlignContent); | ||||
|   FlexboxConfig& SetGap(int gap_x, int gap_y); | ||||
| }; | ||||
|  | ||||
| }  // namespace ftxui | ||||
|  | ||||
| #endif /* end of include guard: FTXUI_DOM_FLEXBOX_CONFIG_HPP */ | ||||
|  | ||||
| // Copyright 2021 Arthur Sonzogni. All rights reserved. | ||||
| // Use of this source code is governed by the MIT license that can be found in | ||||
| // the LICENSE file. | ||||
| @@ -35,6 +35,15 @@ class Node { | ||||
|   // Step 3: Draw this element. | ||||
|   virtual void Render(Screen& screen); | ||||
|  | ||||
|   // Layout may not resolve within a single iteration for some elements. This | ||||
|   // allows them to request additionnal iterations. This signal must be | ||||
|   // forwarded to children at least once. | ||||
|   struct Status { | ||||
|     int iteration = 0; | ||||
|     bool need_iteration = false; | ||||
|   }; | ||||
|   virtual void Check(Status* status); | ||||
|  | ||||
|  protected: | ||||
|   Elements children_; | ||||
|   Requirement requirement_; | ||||
|   | ||||
| @@ -28,7 +28,7 @@ struct Requirement { | ||||
|  | ||||
| }  // namespace ftxui | ||||
|  | ||||
| #endif /* end of include guard: FTXUI_REQUIREMENT_HPP */ | ||||
| #endif /* end of include guard: FTXUI_DOM_REQUIREMENT_HPP */ | ||||
|  | ||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||
| // Use of this source code is governed by the MIT license that can be found in | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni