@@ -341,6 +341,12 @@ void ScrollContainer::ensure_control_visible(Control *p_control) {
341341void ScrollContainer::_reposition_children () {
342342 _update_scrollbars ();
343343 _update_scroll_hints ();
344+ Size2 size = get_size ();
345+ Point2 ofs;
346+ bool h_scroll_is_visible = false ;
347+ bool v_scroll_is_visible = false ;
348+ bool is_resizing = previous_size != size;
349+ previous_size = size;
344350
345351 Rect2 margins = _get_margins ();
346352 Size2 size = get_size ();
@@ -352,23 +358,30 @@ void ScrollContainer::_reposition_children() {
352358
353359 if (_is_h_scroll_visible () || horizontal_scroll_mode == SCROLL_MODE_RESERVE ) {
354360 size.y -= h_scroll->get_minimum_size ().y + theme_cache.scrollbar_v_separation ;
361+ h_scroll_is_visible = true ;
362+ }
363+ if (hold_when_max_horizontal && child_previous_min_size == Size2 ()) {
364+ previous_h_scroll_was_max = true ;
355365 }
356366
357367 if (reserve_vscroll) {
358- int width = v_scroll->get_minimum_size ().x + theme_cache.scrollbar_h_separation ;
359- size. x -= width ;
360- if (rtl) {
361- ofs. x += width;
362- }
368+ size. x - = v_scroll->get_minimum_size ().x + theme_cache.scrollbar_h_separation ;
369+ v_scroll_is_visible = true ;
370+ }
371+ if (hold_when_max_vertical && child_previous_min_size == Size2 ()) {
372+ previous_v_scroll_was_max = true ;
363373 }
364374
365375 for (int i = 0 ; i < get_child_count (); i++) {
366376 Control *c = as_sortable_control (get_child (i));
367377 if (!c || c == h_scroll || c == v_scroll || c == focus_panel || c == scroll_hint_top_left || c == scroll_hint_bottom_right) {
368378 continue ;
369379 }
370-
371380 Size2 minsize = c->get_combined_minimum_size ();
381+ if (child_previous_min_size != minsize) {
382+ is_resizing = true ;
383+ }
384+ child_previous_min_size = minsize;
372385 Rect2 r = Rect2 (-Size2 (get_h_scroll (), get_v_scroll ()), minsize);
373386
374387 if (c->get_h_size_flags ().has_flag (SIZE_EXPAND )) {
@@ -381,6 +394,26 @@ void ScrollContainer::_reposition_children() {
381394 r.position += ofs;
382395 r.position = r.position .floor ();
383396 fit_child_in_rect (c, r);
397+ if (hold_when_max_horizontal && is_resizing && h_scroll_is_visible && previous_h_scroll_was_max) {
398+ c->set_position (Point2 (size.x - c->get_size ().x , c->get_position ().y ));
399+ }
400+ if (hold_when_max_vertical && is_resizing && v_scroll_is_visible && previous_v_scroll_was_max) {
401+ c->set_position (Point2 (c->get_position ().x , size.y - c->get_size ().y ));
402+ }
403+ }
404+ if (h_scroll_is_visible) {
405+ if (hold_when_max_horizontal && is_resizing && previous_h_scroll_was_max) {
406+ h_scroll->set_value_no_signal (h_scroll->get_max () - h_scroll->get_page ());
407+ _cancel_drag ();
408+ }
409+ previous_h_scroll_was_max = h_scroll->get_max () - h_scroll->get_page () - h_scroll->get_value () <= max_value_snap;
410+ }
411+ if (v_scroll_is_visible) {
412+ if (hold_when_max_vertical && is_resizing && previous_v_scroll_was_max) {
413+ v_scroll->set_value_no_signal (v_scroll->get_max () - v_scroll->get_page ());
414+ _cancel_drag ();
415+ }
416+ previous_v_scroll_was_max = v_scroll->get_max () - v_scroll->get_page () - v_scroll->get_value () <= max_value_snap;
384417 }
385418
386419 if (draw_focus_border) {
@@ -803,6 +836,22 @@ VScrollBar *ScrollContainer::get_v_scroll_bar() {
803836 return v_scroll;
804837}
805838
839+ bool ScrollContainer::is_hold_when_max_horizontal () const {
840+ return hold_when_max_horizontal;
841+ }
842+
843+ void ScrollContainer::set_hold_when_max_horizontal (bool p_keep_max) {
844+ hold_when_max_horizontal = p_keep_max;
845+ }
846+
847+ bool ScrollContainer::is_hold_when_max_vertical () const {
848+ return hold_when_max_vertical;
849+ }
850+
851+ void ScrollContainer::set_hold_when_max_vertical (bool p_keep_max) {
852+ hold_when_max_vertical = p_keep_max;
853+ }
854+
806855void ScrollContainer::_bind_methods () {
807856 ClassDB::bind_method (D_METHOD (" set_h_scroll" , " value" ), &ScrollContainer::set_h_scroll);
808857 ClassDB::bind_method (D_METHOD (" get_h_scroll" ), &ScrollContainer::get_h_scroll);
@@ -834,6 +883,12 @@ void ScrollContainer::_bind_methods() {
834883 ClassDB::bind_method (D_METHOD (" set_follow_focus" , " enabled" ), &ScrollContainer::set_follow_focus);
835884 ClassDB::bind_method (D_METHOD (" is_following_focus" ), &ScrollContainer::is_following_focus);
836885
886+ ClassDB::bind_method (D_METHOD (" set_hold_when_max_horizontal" , " enabled" ), &ScrollContainer::set_hold_when_max_horizontal);
887+ ClassDB::bind_method (D_METHOD (" is_hold_when_max_horizontal" ), &ScrollContainer::is_hold_when_max_horizontal);
888+
889+ ClassDB::bind_method (D_METHOD (" set_hold_when_max_vertical" , " enabled" ), &ScrollContainer::set_hold_when_max_vertical);
890+ ClassDB::bind_method (D_METHOD (" is_hold_when_max_vertical" ), &ScrollContainer::is_hold_when_max_vertical);
891+
837892 ClassDB::bind_method (D_METHOD (" get_h_scroll_bar" ), &ScrollContainer::get_h_scroll_bar);
838893 ClassDB::bind_method (D_METHOD (" get_v_scroll_bar" ), &ScrollContainer::get_v_scroll_bar);
839894 ClassDB::bind_method (D_METHOD (" ensure_control_visible" , " control" ), &ScrollContainer::ensure_control_visible);
@@ -848,6 +903,11 @@ void ScrollContainer::_bind_methods() {
848903 ADD_PROPERTY (PropertyInfo (Variant::BOOL , " draw_focus_border" ), " set_draw_focus_border" , " get_draw_focus_border" );
849904
850905 ADD_GROUP (" Scrollbar" , " " );
906+ ADD_GROUP (" Resize Behavior" , " " );
907+ ADD_PROPERTY (PropertyInfo (Variant::BOOL , " hold_when_max_horizontal" ), " set_hold_when_max_horizontal" , " is_hold_when_max_horizontal" );
908+ ADD_PROPERTY (PropertyInfo (Variant::BOOL , " hold_when_max_vertical" ), " set_hold_when_max_vertical" , " is_hold_when_max_vertical" );
909+
910+ ADD_GROUP (" Scroll" , " scroll_" );
851911 ADD_PROPERTY (PropertyInfo (Variant::INT , " scroll_horizontal" , PROPERTY_HINT_NONE , " suffix:px" ), " set_h_scroll" , " get_h_scroll" );
852912 ADD_PROPERTY (PropertyInfo (Variant::INT , " scroll_vertical" , PROPERTY_HINT_NONE , " suffix:px" ), " set_v_scroll" , " get_v_scroll" );
853913 ADD_PROPERTY (PropertyInfo (Variant::FLOAT , " scroll_horizontal_custom_step" , PROPERTY_HINT_RANGE , " -1,4096,suffix:px" ), " set_horizontal_custom_step" , " get_horizontal_custom_step" );
0 commit comments