Merge pull request #48771 from LightningAA/scrollcontainer-ensure-item-visible-3.x

[3.x] ScrollContainer: Expose `_ensure_focused_visible` to the scripting API and rename it to `ensure_control_visible`
This commit is contained in:
Rémi Verschelde 2021-06-01 12:58:56 +02:00 committed by GitHub
commit fb294606b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 32 deletions

View file

@ -9,6 +9,15 @@
<tutorials> <tutorials>
</tutorials> </tutorials>
<methods> <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"> <method name="get_h_scrollbar">
<return type="HScrollBar"> <return type="HScrollBar">
</return> </return>

View file

@ -1442,16 +1442,7 @@ Vector<ProjectList::Item> ProjectList::get_selected_projects() const {
void ProjectList::ensure_project_visible(int p_index) { void ProjectList::ensure_project_visible(int p_index) {
const Item &item = _projects[p_index]; const Item &item = _projects[p_index];
ensure_control_visible(item.control);
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);
}
} }
int ProjectList::get_single_selected_index() const { int ProjectList::get_single_selected_index() const {

View file

@ -230,28 +230,25 @@ void ScrollContainer::_update_scrollbar_position() {
v_scroll->raise(); v_scroll->raise();
} }
void ScrollContainer::_ensure_focused_visible(Control *p_control) { void ScrollContainer::_gui_focus_changed(Control *p_control) {
if (!follow_focus) { if (follow_focus && is_a_parent_of(p_control)) {
return; ensure_control_visible(p_control);
} }
}
if (is_a_parent_of(p_control)) { void ScrollContainer::ensure_control_visible(Control *p_control) {
Rect2 global_rect = get_global_rect(); ERR_FAIL_COND_MSG(!is_a_parent_of(p_control), "Must be a parent of the control.");
Rect2 other_rect = p_control->get_global_rect();
float right_margin = 0;
if (v_scroll->is_visible()) {
right_margin += v_scroll->get_size().x;
}
float bottom_margin = 0;
if (h_scroll->is_visible()) {
bottom_margin += h_scroll->get_size().y;
}
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); Rect2 global_rect = get_global_rect();
set_v_scroll(get_v_scroll() + (diff - global_rect.position.y)); Rect2 other_rect = p_control->get_global_rect();
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); float right_margin = v_scroll->is_visible() ? v_scroll->get_size().x : 0.0f;
set_h_scroll(get_h_scroll() + (diff - global_rect.position.x)); 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 + right_margin),
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::_notification(int p_what) { void ScrollContainer::_notification(int p_what) {
@ -260,7 +257,7 @@ void ScrollContainer::_notification(int p_what) {
}; };
if (p_what == NOTIFICATION_READY) { if (p_what == NOTIFICATION_READY) {
get_viewport()->connect("gui_focus_changed", this, "_ensure_focused_visible"); get_viewport()->connect("gui_focus_changed", this, "_gui_focus_changed");
} }
if (p_what == NOTIFICATION_SORT_CHILDREN) { if (p_what == NOTIFICATION_SORT_CHILDREN) {
@ -560,12 +557,12 @@ VScrollBar *ScrollContainer::get_v_scrollbar() {
void ScrollContainer::_bind_methods() { void ScrollContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_scroll_moved"), &ScrollContainer::_scroll_moved); ClassDB::bind_method(D_METHOD("_scroll_moved"), &ScrollContainer::_scroll_moved);
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input); ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
ClassDB::bind_method(D_METHOD("_gui_focus_changed"), &ScrollContainer::_gui_focus_changed);
ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll); ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled); ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll); ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled); ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position); ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position);
ClassDB::bind_method(D_METHOD("_ensure_focused_visible"), &ScrollContainer::_ensure_focused_visible);
ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll); ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll);
ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll); ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll);
ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll); ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll);
@ -577,6 +574,7 @@ void ScrollContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_h_scrollbar"), &ScrollContainer::get_h_scrollbar); 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("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_started"));
ADD_SIGNAL(MethodInfo("scroll_ended")); ADD_SIGNAL(MethodInfo("scroll_ended"));

View file

@ -69,13 +69,13 @@ protected:
Size2 get_minimum_size() const; Size2 get_minimum_size() const;
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 _notification(int p_what); void _notification(int p_what);
void _scroll_moved(float); void _scroll_moved(float);
static void _bind_methods(); static void _bind_methods();
void _update_scrollbar_position(); void _update_scrollbar_position();
void _ensure_focused_visible(Control *p_node);
public: public:
int get_v_scroll() const; int get_v_scroll() const;
@ -98,6 +98,7 @@ public:
HScrollBar *get_h_scrollbar(); HScrollBar *get_h_scrollbar();
VScrollBar *get_v_scrollbar(); VScrollBar *get_v_scrollbar();
void ensure_control_visible(Control *p_control);
virtual bool clips_input() const; virtual bool clips_input() const;