Add alignment options to flow container

This commit is contained in:
Teggy 2022-11-12 12:11:16 +01:00
parent 92aedd5063
commit 5d0c29460a
3 changed files with 70 additions and 0 deletions

View file

@ -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>

View file

@ -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");
}

View file

@ -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