Browse Source

Add option to reverse FlowContainer fill direction (HFlow bottom-to-top, VFlow right-to-left)

TheSecondReal0 2 years ago
parent
commit
b8a7270567
3 changed files with 27 additions and 1 deletions
  1. 4 0
      doc/classes/FlowContainer.xml
  2. 19 1
      scene/gui/flow_container.cpp
  3. 4 0
      scene/gui/flow_container.h

+ 4 - 0
doc/classes/FlowContainer.xml

@@ -21,6 +21,10 @@
 		<member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="FlowContainer.AlignmentMode" default="0">
 			The alignment of the container's children (must be one of [constant ALIGNMENT_BEGIN], [constant ALIGNMENT_CENTER], or [constant ALIGNMENT_END]).
 		</member>
+		<member name="reverse_fill" type="bool" setter="set_reverse_fill" getter="is_reverse_fill" default="false">
+			If [code]true[/code], reverses fill direction. Horizontal [FlowContainer]s will fill rows bottom to top, vertical [FlowContainer]s will fill columns right to left.
+			When using a vertical [FlowContainer] with a right to left [member Control.layout_direction], columns will fill left to right instead.
+		</member>
 		<member name="vertical" type="bool" setter="set_vertical" getter="is_vertical" default="false">
 			If [code]true[/code], the [FlowContainer] will arrange its children vertically, rather than horizontally.
 			Can't be changed when using [HFlowContainer] and [VFlowContainer].

+ 19 - 1
scene/gui/flow_container.cpp

@@ -198,7 +198,10 @@ void FlowContainer::_resort() {
 		}
 
 		Rect2 child_rect = Rect2(ofs, child_size);
-		if (rtl) {
+		if (reverse_fill && !vertical) {
+			child_rect.position.y = get_rect().size.y - child_rect.position.y - child_rect.size.height;
+		}
+		if ((rtl && !vertical) || ((rtl != reverse_fill) && vertical)) {
 			child_rect.position.x = get_rect().size.x - child_rect.position.x - child_rect.size.width;
 		}
 
@@ -322,6 +325,18 @@ bool FlowContainer::is_vertical() const {
 	return vertical;
 }
 
+void FlowContainer::set_reverse_fill(bool p_reverse_fill) {
+	if (reverse_fill == p_reverse_fill) {
+		return;
+	}
+	reverse_fill = p_reverse_fill;
+	_resort();
+}
+
+bool FlowContainer::is_reverse_fill() const {
+	return reverse_fill;
+}
+
 FlowContainer::FlowContainer(bool p_vertical) {
 	vertical = p_vertical;
 }
@@ -333,6 +348,8 @@ void FlowContainer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_alignment"), &FlowContainer::get_alignment);
 	ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &FlowContainer::set_vertical);
 	ClassDB::bind_method(D_METHOD("is_vertical"), &FlowContainer::is_vertical);
+	ClassDB::bind_method(D_METHOD("set_reverse_fill", "reverse_fill"), &FlowContainer::set_reverse_fill);
+	ClassDB::bind_method(D_METHOD("is_reverse_fill"), &FlowContainer::is_reverse_fill);
 
 	BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN);
 	BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
@@ -340,6 +357,7 @@ void FlowContainer::_bind_methods() {
 
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment", "get_alignment");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "reverse_fill"), "set_reverse_fill", "is_reverse_fill");
 
 	BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, FlowContainer, h_separation);
 	BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, FlowContainer, v_separation);

+ 4 - 0
scene/gui/flow_container.h

@@ -48,6 +48,7 @@ private:
 	int cached_line_count = 0;
 
 	bool vertical = false;
+	bool reverse_fill = false;
 	AlignmentMode alignment = ALIGNMENT_BEGIN;
 
 	struct ThemeCache {
@@ -73,6 +74,9 @@ public:
 	void set_vertical(bool p_vertical);
 	bool is_vertical() const;
 
+	void set_reverse_fill(bool p_reverse_fill);
+	bool is_reverse_fill() const;
+
 	virtual Size2 get_minimum_size() const override;
 
 	virtual Vector<int> get_allowed_size_flags_horizontal() const override;