Skip to content

Commit

Permalink
Merge pull request godotengine#44781 from mrushyendra/scroll_containe…
Browse files Browse the repository at this point in the history
…r_ready_fix

Allow ScrollBar params of a ScrollContainer to be modified from _ready()
  • Loading branch information
akien-mga authored Dec 29, 2020
2 parents 652bdd5 + b8610db commit c6e9d91
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 58 deletions.
121 changes: 63 additions & 58 deletions scene/gui/scroll_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions scene/gui/scroll_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ScrollContainer : public Container {
Size2 get_minimum_size() const override;

void _gui_input(const Ref<InputEvent> &p_gui_input);
void _update_dimensions();
void _notification(int p_what);

void _scroll_moved(float);
Expand Down

0 comments on commit c6e9d91

Please sign in to comment.