[3.x] Allow ScrollBar params of a ScrollContainer to be modified from _ready()

Cherrypicks b8610dbd31
This commit is contained in:
Aaron Record 2022-05-23 21:43:09 -06:00
parent 5f9bc7ea5a
commit ae9e523025
2 changed files with 59 additions and 53 deletions

View file

@ -251,6 +251,62 @@ void ScrollContainer::ensure_control_visible(Control *p_control) {
set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y)); set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y));
} }
void ScrollContainer::_update_dimensions() {
child_max_size = Size2(0, 0);
Size2 size = get_size();
Point2 ofs;
Ref<StyleBox> sb = get_stylebox("bg");
size -= sb->get_minimum_size();
ofs += sb->get_offset();
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_toplevel()) {
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;
fit_child_in_rect(c, r);
}
update();
}
void ScrollContainer::_notification(int p_what) { void ScrollContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
call_deferred("_update_scrollbar_position"); call_deferred("_update_scrollbar_position");
@ -260,62 +316,11 @@ void ScrollContainer::_notification(int p_what) {
Viewport *viewport = get_viewport(); Viewport *viewport = get_viewport();
ERR_FAIL_COND(!viewport); ERR_FAIL_COND(!viewport);
viewport->connect("gui_focus_changed", this, "_gui_focus_changed"); viewport->connect("gui_focus_changed", this, "_gui_focus_changed");
_update_dimensions();
} }
if (p_what == NOTIFICATION_SORT_CHILDREN) { if (p_what == NOTIFICATION_SORT_CHILDREN) {
child_max_size = Size2(0, 0); _update_dimensions();
Size2 size = get_size();
Point2 ofs;
Ref<StyleBox> sb = get_stylebox("bg");
size -= sb->get_minimum_size();
ofs += sb->get_offset();
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_toplevel()) {
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;
fit_child_in_rect(c, r);
}
update();
}; };
if (p_what == NOTIFICATION_DRAW) { if (p_what == NOTIFICATION_DRAW) {

View file

@ -70,6 +70,7 @@ protected:
void _gui_input(const Ref<InputEvent> &p_gui_input); void _gui_input(const Ref<InputEvent> &p_gui_input);
void _gui_focus_changed(Control *p_control); void _gui_focus_changed(Control *p_control);
void _update_dimensions();
void _notification(int p_what); void _notification(int p_what);
void _scroll_moved(float); void _scroll_moved(float);