summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-11-02 18:52:53 +0100
committerRémi Verschelde <rverschelde@gmail.com>2022-11-02 18:52:53 +0100
commit7488b4724e7c6a39ff46c6dfd3b670bdbe38c159 (patch)
tree97d6c6c099a44291842c1965e4090049703adf0b
parent17497b1eb977b0b717066d5ee2f1534e2b7215b5 (diff)
parent2b08675f37d025ac842460670f1cff831ba31d92 (diff)
Merge pull request #67788 from 98teg/flow-container-alignment
Add alignment options to flow container
-rw-r--r--doc/classes/FlowContainer.xml14
-rw-r--r--scene/gui/flow_container.cpp41
-rw-r--r--scene/gui/flow_container.h13
3 files changed, 68 insertions, 0 deletions
diff --git a/doc/classes/FlowContainer.xml b/doc/classes/FlowContainer.xml
index d449049ef1..7a324160c9 100644
--- a/doc/classes/FlowContainer.xml
+++ b/doc/classes/FlowContainer.xml
@@ -18,11 +18,25 @@
</method>
</methods>
<members>
+ <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="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].
</member>
</members>
+ <constants>
+ <constant name="ALIGNMENT_BEGIN" value="0" enum="AlignmentMode">
+ The child controls will be arranged at the beginning of the container, i.e. top if orientation is vertical, left if orientation is horizontal (right for RTL layout).
+ </constant>
+ <constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
+ The child controls will be centered in the container.
+ </constant>
+ <constant name="ALIGNMENT_END" value="2" enum="AlignmentMode">
+ The child controls will be arranged at the end of the container, i.e. bottom if orientation is vertical, right if orientation is horizontal (left for RTL layout).
+ </constant>
+ </constants>
<theme_items>
<theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal separation of children nodes.
diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp
index b0d15aa7f4..44c5ec62f8 100644
--- a/scene/gui/flow_container.cpp
+++ b/scene/gui/flow_container.cpp
@@ -152,6 +152,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 alignment_ofs = 0;
+ switch (alignment) {
+ case ALIGNMENT_CENTER:
+ alignment_ofs = line_data.stretch_avail / 2;
+ break;
+ case ALIGNMENT_END:
+ alignment_ofs = line_data.stretch_avail;
+ break;
+ default:
+ break;
+ }
+
+ if (vertical) { /* VERTICAL */
+ ofs.y += alignment_ofs;
+ } else { /* HORIZONTAL */
+ ofs.x += alignment_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;
@@ -282,6 +304,18 @@ int FlowContainer::get_line_count() const {
return cached_line_count;
}
+void FlowContainer::set_alignment(AlignmentMode p_alignment) {
+ if (alignment == p_alignment) {
+ return;
+ }
+ alignment = p_alignment;
+ _resort();
+}
+
+FlowContainer::AlignmentMode FlowContainer::get_alignment() const {
+ return alignment;
+}
+
void FlowContainer::set_vertical(bool p_vertical) {
ERR_FAIL_COND_MSG(is_fixed, "Can't change orientation of " + get_class() + ".");
vertical = p_vertical;
@@ -300,8 +334,15 @@ FlowContainer::FlowContainer(bool p_vertical) {
void FlowContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_count"), &FlowContainer::get_line_count);
+ ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &FlowContainer::set_alignment);
+ 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);
+ BIND_ENUM_CONSTANT(ALIGNMENT_BEGIN);
+ BIND_ENUM_CONSTANT(ALIGNMENT_CENTER);
+ BIND_ENUM_CONSTANT(ALIGNMENT_END);
+
+ 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");
}
diff --git a/scene/gui/flow_container.h b/scene/gui/flow_container.h
index 536df27ad6..6a61e9b904 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 AlignmentMode {
+ ALIGNMENT_BEGIN,
+ ALIGNMENT_CENTER,
+ ALIGNMENT_END
+ };
+
private:
int cached_size = 0;
int cached_line_count = 0;
bool vertical = false;
+ AlignmentMode alignment = ALIGNMENT_BEGIN;
struct ThemeCache {
int h_separation = 0;
@@ -61,6 +69,9 @@ protected:
public:
int get_line_count() const;
+ void set_alignment(AlignmentMode p_alignment);
+ AlignmentMode get_alignment() const;
+
void set_vertical(bool p_vertical);
bool is_vertical() const;
@@ -88,4 +99,6 @@ public:
FlowContainer(true) { is_fixed = true; }
};
+VARIANT_ENUM_CAST(FlowContainer::AlignmentMode);
+
#endif // FLOW_CONTAINER_H