diff options
-rw-r--r-- | doc/classes/ScrollContainer.xml | 9 | ||||
-rw-r--r-- | editor/project_manager.cpp | 11 | ||||
-rw-r--r-- | scene/gui/scroll_container.cpp | 42 | ||||
-rw-r--r-- | scene/gui/scroll_container.h | 3 |
4 files changed, 30 insertions, 35 deletions
diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index 40e29ac74b..60f3106b4b 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -11,6 +11,15 @@ <tutorials> </tutorials> <methods> + <method name="ensure_control_visible"> + <return type="void"> + </return> + <argument index="0" name="control" type="Control"> + </argument> + <description> + Ensures the given [code]control[/code] is visible (must be a direct or indirect child of the ScrollContainer). Used by [member follow_focus]. + </description> + </method> <method name="get_h_scrollbar"> <return type="HScrollBar"> </return> diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 2b75144ac7..74eed8330d 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1470,16 +1470,7 @@ Vector<ProjectList::Item> ProjectList::get_selected_projects() const { void ProjectList::ensure_project_visible(int p_index) { const Item &item = _projects[p_index]; - - int item_top = item.control->get_position().y; - int item_bottom = item.control->get_position().y + item.control->get_size().y; - - if (item_top < get_v_scroll()) { - set_v_scroll(item_top); - - } else if (item_bottom > get_v_scroll() + get_size().y) { - set_v_scroll(item_bottom - get_size().y); - } + ensure_control_visible(item.control); } int ProjectList::get_single_selected_index() const { 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; |