diff options
Diffstat (limited to 'scene/gui/flow_container.cpp')
-rw-r--r-- | scene/gui/flow_container.cpp | 93 |
1 files changed, 80 insertions, 13 deletions
diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp index 30b694da76..44c5ec62f8 100644 --- a/scene/gui/flow_container.cpp +++ b/scene/gui/flow_container.cpp @@ -44,9 +44,6 @@ void FlowContainer::_resort() { return; } - int separation_horizontal = get_theme_constant(SNAME("h_separation")); - int separation_vertical = get_theme_constant(SNAME("v_separation")); - bool rtl = is_layout_rtl(); HashMap<Control *, Size2i> children_minsize_cache; @@ -74,14 +71,14 @@ void FlowContainer::_resort() { if (vertical) { /* VERTICAL */ if (children_in_current_line > 0) { - ofs.y += separation_vertical; + ofs.y += theme_cache.v_separation; } if (ofs.y + child_msc.y > current_container_size) { - line_length = ofs.y - separation_vertical; + line_length = ofs.y - theme_cache.v_separation; lines_data.push_back(_LineData{ children_in_current_line, line_height, line_length, current_container_size - line_length, line_stretch_ratio_total }); // Move in new column (vertical line). - ofs.x += line_height + separation_horizontal; + ofs.x += line_height + theme_cache.h_separation; ofs.y = 0; line_height = 0; line_stretch_ratio_total = 0; @@ -96,14 +93,14 @@ void FlowContainer::_resort() { } else { /* HORIZONTAL */ if (children_in_current_line > 0) { - ofs.x += separation_horizontal; + ofs.x += theme_cache.h_separation; } if (ofs.x + child_msc.x > current_container_size) { - line_length = ofs.x - separation_horizontal; + line_length = ofs.x - theme_cache.h_separation; lines_data.push_back(_LineData{ children_in_current_line, line_height, line_length, current_container_size - line_length, line_stretch_ratio_total }); // Move in new line. - ofs.y += line_height + separation_vertical; + ofs.y += line_height + theme_cache.v_separation; ofs.x = 0; line_height = 0; line_stretch_ratio_total = 0; @@ -146,15 +143,37 @@ void FlowContainer::_resort() { current_line_idx++; child_idx_in_line = 0; if (vertical) { - ofs.x += line_data.min_line_height + separation_horizontal; + ofs.x += line_data.min_line_height + theme_cache.h_separation; ofs.y = 0; } else { ofs.x = 0; - ofs.y += line_data.min_line_height + separation_vertical; + ofs.y += line_data.min_line_height + theme_cache.v_separation; } 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; @@ -184,9 +203,9 @@ void FlowContainer::_resort() { fit_child_in_rect(child, child_rect); if (vertical) { /* VERTICAL */ - ofs.y += child_size.height + separation_vertical; + ofs.y += child_size.height + theme_cache.v_separation; } else { /* HORIZONTAL */ - ofs.x += child_size.width + separation_horizontal; + ofs.x += child_size.width + theme_cache.h_separation; } child_idx_in_line++; @@ -250,6 +269,13 @@ Vector<int> FlowContainer::get_allowed_size_flags_vertical() const { return flags; } +void FlowContainer::_update_theme_item_cache() { + Container::_update_theme_item_cache(); + + theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); + theme_cache.v_separation = get_theme_constant(SNAME("v_separation")); +} + void FlowContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { @@ -268,14 +294,55 @@ void FlowContainer::_notification(int p_what) { } } +void FlowContainer::_validate_property(PropertyInfo &p_property) const { + if (is_fixed && p_property.name == "vertical") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + 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; + update_minimum_size(); + _resort(); +} + +bool FlowContainer::is_vertical() const { + return vertical; +} + FlowContainer::FlowContainer(bool p_vertical) { vertical = 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"); } |