diff --git a/doc/classes/FlowContainer.xml b/doc/classes/FlowContainer.xml
index 784a0673569..9ceb2991d8c 100644
--- a/doc/classes/FlowContainer.xml
+++ b/doc/classes/FlowContainer.xml
@@ -17,6 +17,20 @@
+
+
+ The alignment of the container's children (must be one of [constant ALIGN_BEGIN], [constant ALIGN_CENTER] or [constant ALIGN_END]).
+
+
+
+ Aligns children with the beginning of the container.
+
+
+ Aligns children with the center of the container.
+
+
+ Aligns children with the end of the container.
+
diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp
index 21a107c2a3a..a708b05e7a8 100644
--- a/scene/gui/flow_container.cpp
+++ b/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");
}
diff --git a/scene/gui/flow_container.h b/scene/gui/flow_container.h
index 1a40d0f7f18..48f2f75203c 100644
--- a/scene/gui/flow_container.h
+++ b/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