Browse Source

Add alignment options to flow container

Teggy 2 years ago
parent
commit
5d0c29460a
3 changed files with 70 additions and 0 deletions
  1. 14 0
      doc/classes/FlowContainer.xml
  2. 43 0
      scene/gui/flow_container.cpp
  3. 13 0
      scene/gui/flow_container.h

+ 14 - 0
doc/classes/FlowContainer.xml

@@ -17,6 +17,20 @@
 			</description>
 		</method>
 	</methods>
+	<members>
+		<member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="FlowContainer.AlignMode" default="0">
+			The alignment of the container's children (must be one of [constant ALIGN_BEGIN], [constant ALIGN_CENTER] or [constant ALIGN_END]).
+		</member>
+	</members>
 	<constants>
+		<constant name="ALIGN_BEGIN" value="0" enum="AlignMode">
+			Aligns children with the beginning of the container.
+		</constant>
+		<constant name="ALIGN_CENTER" value="1" enum="AlignMode">
+			Aligns children with the center of the container.
+		</constant>
+		<constant name="ALIGN_END" value="2" enum="AlignMode">
+			Aligns children with the end of the container.
+		</constant>
 	</constants>
 </class>

+ 43 - 0
scene/gui/flow_container.cpp

@@ -155,6 +155,28 @@ void FlowContainer::_resort() {
 			line_data = lines_data[current_line_idx];
 		}
 
+		// The first child of each line adds the offset caused by the alignment,
+		// but only if the line doesn't contain a child that expands.
+		if (child_idx_in_line == 0 && Math::is_equal_approx(line_data.stretch_ratio_total, 0)) {
+			int align_ofs = 0;
+			switch (align) {
+				case ALIGN_BEGIN:
+					break;
+				case ALIGN_CENTER:
+					align_ofs = line_data.stretch_avail / 2;
+					break;
+				case ALIGN_END:
+					align_ofs = line_data.stretch_avail;
+					break;
+			}
+
+			if (vertical) { /* VERTICAL */
+				ofs.y += align_ofs;
+			} else { /* HORIZONTAL */
+				ofs.x += align_ofs;
+			}
+		}
+
 		if (vertical) { /* VERTICAL */
 			if (child->get_h_size_flags() & (SIZE_FILL | SIZE_SHRINK_CENTER | SIZE_SHRINK_END)) {
 				child_size.width = line_data.min_line_height;
@@ -241,12 +263,33 @@ int FlowContainer::get_line_count() const {
 	return cached_line_count;
 }
 
+void FlowContainer::set_alignment(AlignMode p_align) {
+	if (align == p_align) {
+		return;
+	}
+	align = p_align;
+	_resort();
+}
+
+FlowContainer::AlignMode FlowContainer::get_alignment() const {
+	return align;
+}
+
 FlowContainer::FlowContainer(bool p_vertical) {
 	vertical = p_vertical;
+	align = ALIGN_BEGIN;
 	cached_size = 0;
 	cached_line_count = 0;
 }
 
 void FlowContainer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_line_count"), &FlowContainer::get_line_count);
+	ClassDB::bind_method(D_METHOD("get_alignment"), &FlowContainer::get_alignment);
+	ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &FlowContainer::set_alignment);
+
+	BIND_ENUM_CONSTANT(ALIGN_BEGIN);
+	BIND_ENUM_CONSTANT(ALIGN_CENTER);
+	BIND_ENUM_CONSTANT(ALIGN_END);
+
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment", "get_alignment");
 }

+ 13 - 0
scene/gui/flow_container.h

@@ -36,11 +36,19 @@
 class FlowContainer : public Container {
 	GDCLASS(FlowContainer, Container);
 
+public:
+	enum AlignMode {
+		ALIGN_BEGIN,
+		ALIGN_CENTER,
+		ALIGN_END
+	};
+
 private:
 	int cached_size;
 	int cached_line_count;
 
 	bool vertical;
+	AlignMode align;
 
 	void _resort();
 
@@ -55,6 +63,9 @@ public:
 	virtual Size2 get_minimum_size() const;
 
 	FlowContainer(bool p_vertical = false);
+
+	void set_alignment(AlignMode p_align);
+	AlignMode get_alignment() const;
 };
 
 class HFlowContainer : public FlowContainer {
@@ -73,4 +84,6 @@ public:
 			FlowContainer(true) {}
 };
 
+VARIANT_ENUM_CAST(FlowContainer::AlignMode);
+
 #endif // FLOW_CONTAINER_H