diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-11-02 18:52:53 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-11-02 18:52:53 +0100 |
commit | 7488b4724e7c6a39ff46c6dfd3b670bdbe38c159 (patch) | |
tree | 97d6c6c099a44291842c1965e4090049703adf0b | |
parent | 17497b1eb977b0b717066d5ee2f1534e2b7215b5 (diff) | |
parent | 2b08675f37d025ac842460670f1cff831ba31d92 (diff) |
Merge pull request #67788 from 98teg/flow-container-alignment
Add alignment options to flow container
-rw-r--r-- | doc/classes/FlowContainer.xml | 14 | ||||
-rw-r--r-- | scene/gui/flow_container.cpp | 41 | ||||
-rw-r--r-- | scene/gui/flow_container.h | 13 |
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 |