summaryrefslogtreecommitdiff
path: root/scene/gui/scroll_container.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/scroll_container.cpp')
-rw-r--r--scene/gui/scroll_container.cpp123
1 files changed, 64 insertions, 59 deletions
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 942593df27..af9c5cb0c5 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -264,6 +264,67 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) {
}
}
+void ScrollContainer::_update_dimensions() {
+ child_max_size = Size2(0, 0);
+ Size2 size = get_size();
+ Point2 ofs;
+
+ Ref<StyleBox> sb = get_theme_stylebox("bg");
+ size -= sb->get_minimum_size();
+ ofs += sb->get_offset();
+ bool rtl = is_layout_rtl();
+
+ if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ size.y -= h_scroll->get_minimum_size().y;
+ }
+
+ if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ size.x -= v_scroll->get_minimum_size().x;
+ }
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c) {
+ continue;
+ }
+ if (c->is_set_as_top_level()) {
+ continue;
+ }
+ if (c == h_scroll || c == v_scroll) {
+ continue;
+ }
+ Size2 minsize = c->get_combined_minimum_size();
+ child_max_size.x = MAX(child_max_size.x, minsize.x);
+ child_max_size.y = MAX(child_max_size.y, minsize.y);
+
+ Rect2 r = Rect2(-scroll, minsize);
+ if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
+ r.position.x = 0;
+ if (c->get_h_size_flags() & SIZE_EXPAND) {
+ r.size.width = MAX(size.width, minsize.width);
+ } else {
+ r.size.width = minsize.width;
+ }
+ }
+ if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
+ r.position.y = 0;
+ if (c->get_v_size_flags() & SIZE_EXPAND) {
+ r.size.height = MAX(size.height, minsize.height);
+ } else {
+ r.size.height = minsize.height;
+ }
+ }
+ r.position += ofs;
+ if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
+ r.position.x += v_scroll->get_minimum_size().x;
+ }
+ r.position = r.position.floor();
+ fit_child_in_rect(c, r);
+ }
+
+ update();
+}
+
void ScrollContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_updating_scrollbars = true;
@@ -272,67 +333,11 @@ void ScrollContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible));
+ _update_dimensions();
}
if (p_what == NOTIFICATION_SORT_CHILDREN) {
- child_max_size = Size2(0, 0);
- Size2 size = get_size();
- Point2 ofs;
-
- Ref<StyleBox> sb = get_theme_stylebox("bg");
- size -= sb->get_minimum_size();
- ofs += sb->get_offset();
- bool rtl = is_layout_rtl();
-
- if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
- size.y -= h_scroll->get_minimum_size().y;
- }
-
- if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
- size.x -= v_scroll->get_minimum_size().x;
- }
-
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
- continue;
- }
- if (c->is_set_as_top_level()) {
- continue;
- }
- if (c == h_scroll || c == v_scroll) {
- continue;
- }
- Size2 minsize = c->get_combined_minimum_size();
- child_max_size.x = MAX(child_max_size.x, minsize.x);
- child_max_size.y = MAX(child_max_size.y, minsize.y);
-
- Rect2 r = Rect2(-scroll, minsize);
- if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
- r.position.x = 0;
- if (c->get_h_size_flags() & SIZE_EXPAND) {
- r.size.width = MAX(size.width, minsize.width);
- } else {
- r.size.width = minsize.width;
- }
- }
- if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
- r.position.y = 0;
- if (c->get_v_size_flags() & SIZE_EXPAND) {
- r.size.height = MAX(size.height, minsize.height);
- } else {
- r.size.height = minsize.height;
- }
- }
- r.position += ofs;
- if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
- r.position.x += v_scroll->get_minimum_size().x;
- }
- r.position = r.position.floor();
- fit_child_in_rect(c, r);
- }
-
- update();
+ _update_dimensions();
};
if (p_what == NOTIFICATION_DRAW) {
@@ -558,7 +563,7 @@ String ScrollContainer::get_configuration_warning() const {
}
if (found != 1) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually.");