diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/scroll_container.cpp | 42 | ||||
-rw-r--r-- | scene/gui/scroll_container.h | 3 |
2 files changed, 20 insertions, 25 deletions
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 67dcf458b0..9a15ecb108 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -238,32 +238,25 @@ void ScrollContainer::_update_scrollbar_position() { _updating_scrollbars = false; } -void ScrollContainer::_ensure_focused_visible(Control *p_control) { - if (!follow_focus) { - return; +void ScrollContainer::_gui_focus_changed(Control *p_control) { + if (follow_focus && is_a_parent_of(p_control)) { + ensure_control_visible(p_control); } +} - if (is_a_parent_of(p_control)) { - Rect2 global_rect = get_global_rect(); - Rect2 other_rect = p_control->get_global_rect(); - float right_margin = 0.0; - if (v_scroll->is_visible()) { - right_margin += v_scroll->get_size().x; - } - float bottom_margin = 0.0; - if (h_scroll->is_visible()) { - bottom_margin += h_scroll->get_size().y; - } +void ScrollContainer::ensure_control_visible(Control *p_control) { + ERR_FAIL_COND_MSG(!is_a_parent_of(p_control), "Must be a parent of the control."); - float diff = MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin); - set_v_scroll(get_v_scroll() + (diff - global_rect.position.y)); - if (is_layout_rtl()) { - diff = MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x); - } else { - diff = MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + right_margin); - } - set_h_scroll(get_h_scroll() + (diff - global_rect.position.x)); - } + Rect2 global_rect = get_global_rect(); + Rect2 other_rect = p_control->get_global_rect(); + float right_margin = v_scroll->is_visible() ? v_scroll->get_size().x : 0.0f; + float bottom_margin = h_scroll->is_visible() ? h_scroll->get_size().y : 0.0f; + + Vector2 diff = Vector2(MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + (!is_layout_rtl() ? right_margin : 0.0f)), + MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin)); + + set_h_scroll(get_h_scroll() + (diff.x - global_rect.position.x)); + set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y)); } void ScrollContainer::_update_dimensions() { @@ -334,7 +327,7 @@ void ScrollContainer::_notification(int p_what) { }; if (p_what == NOTIFICATION_READY) { - get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible)); + get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_gui_focus_changed)); _update_dimensions(); } @@ -608,6 +601,7 @@ void ScrollContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_h_scrollbar"), &ScrollContainer::get_h_scrollbar); ClassDB::bind_method(D_METHOD("get_v_scrollbar"), &ScrollContainer::get_v_scrollbar); + ClassDB::bind_method(D_METHOD("ensure_control_visible", "control"), &ScrollContainer::ensure_control_visible); ADD_SIGNAL(MethodInfo("scroll_started")); ADD_SIGNAL(MethodInfo("scroll_ended")); diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index f61df70b85..c77a0d62f5 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -69,6 +69,7 @@ protected: Size2 get_minimum_size() const override; void _gui_input(const Ref<InputEvent> &p_gui_input); + void _gui_focus_changed(Control *p_control); void _update_dimensions(); void _notification(int p_what); @@ -77,7 +78,6 @@ protected: bool _updating_scrollbars = false; void _update_scrollbar_position(); - void _ensure_focused_visible(Control *p_node); public: void set_h_scroll(int p_pos); @@ -106,6 +106,7 @@ public: HScrollBar *get_h_scrollbar(); VScrollBar *get_v_scrollbar(); + void ensure_control_visible(Control *p_control); virtual bool clips_input() const override; |