summaryrefslogtreecommitdiff
path: root/scene/gui/scroll_container.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/scroll_container.cpp')
-rw-r--r--scene/gui/scroll_container.cpp88
1 files changed, 38 insertions, 50 deletions
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 67dcf458b0..7b2ea46e17 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -32,12 +32,8 @@
#include "core/os/os.h"
#include "scene/main/window.h"
-bool ScrollContainer::clips_input() const {
- return true;
-}
-
Size2 ScrollContainer::get_minimum_size() const {
- Ref<StyleBox> sb = get_theme_stylebox("bg");
+ Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
Size2 min_size;
for (int i = 0; i < get_child_count(); i++) {
@@ -81,13 +77,13 @@ void ScrollContainer::_cancel_drag() {
drag_from = Vector2();
if (beyond_deadzone) {
- emit_signal("scroll_ended");
+ emit_signal(SNAME("scroll_ended"));
propagate_notification(NOTIFICATION_SCROLL_END);
beyond_deadzone = false;
}
}
-void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
+void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) {
ERR_FAIL_COND(p_gui_input.is_null());
double prev_v_scroll = v_scroll->get_value();
@@ -96,31 +92,31 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseButton> mb = p_gui_input;
if (mb.is_valid()) {
- if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) {
+ if (mb->get_button_index() == MouseButton::WHEEL_UP && mb->is_pressed()) {
// only horizontal is enabled, scroll horizontally
- if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) {
+ if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->is_shift_pressed())) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() / 8 * mb->get_factor());
} else if (v_scroll->is_visible_in_tree()) {
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8 * mb->get_factor());
}
}
- if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) {
+ if (mb->get_button_index() == MouseButton::WHEEL_DOWN && mb->is_pressed()) {
// only horizontal is enabled, scroll horizontally
- if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) {
+ if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->is_shift_pressed())) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() / 8 * mb->get_factor());
} else if (v_scroll->is_visible()) {
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8 * mb->get_factor());
}
}
- if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT && mb->is_pressed()) {
+ if (mb->get_button_index() == MouseButton::WHEEL_LEFT && mb->is_pressed()) {
if (h_scroll->is_visible_in_tree()) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb->get_factor() / 8);
}
}
- if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT && mb->is_pressed()) {
+ if (mb->get_button_index() == MouseButton::WHEEL_RIGHT && mb->is_pressed()) {
if (h_scroll->is_visible_in_tree()) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * mb->get_factor() / 8);
}
@@ -134,7 +130,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- if (mb->get_button_index() != MOUSE_BUTTON_LEFT) {
+ if (mb->get_button_index() != MouseButton::LEFT) {
return;
}
@@ -171,13 +167,13 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (mm.is_valid()) {
if (drag_touching && !drag_touching_deaccel) {
- Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
+ Vector2 motion = mm->get_relative();
drag_accum -= motion;
if (beyond_deadzone || (scroll_h && Math::abs(drag_accum.x) > deadzone) || (scroll_v && Math::abs(drag_accum.y) > deadzone)) {
if (!beyond_deadzone) {
propagate_notification(NOTIFICATION_SCROLL_BEGIN);
- emit_signal("scroll_started");
+ emit_signal(SNAME("scroll_started"));
beyond_deadzone = true;
// resetting drag_accum here ensures smooth scrolling after reaching deadzone
@@ -232,38 +228,28 @@ void ScrollContainer::_update_scrollbar_position() {
v_scroll->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 0);
v_scroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0);
- h_scroll->raise();
- v_scroll->raise();
-
_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_ancestor_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_ancestor_of(p_control), "Must be an ancestor 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() {
@@ -271,7 +257,7 @@ void ScrollContainer::_update_dimensions() {
Size2 size = get_size();
Point2 ofs;
- Ref<StyleBox> sb = get_theme_stylebox("bg");
+ Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
size -= sb->get_minimum_size();
ofs += sb->get_offset();
bool rtl = is_layout_rtl();
@@ -330,11 +316,13 @@ void ScrollContainer::_update_dimensions() {
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;
- call_deferred("_update_scrollbar_position");
+ call_deferred(SNAME("_update_scrollbar_position"));
};
if (p_what == NOTIFICATION_READY) {
- get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible));
+ Viewport *viewport = get_viewport();
+ ERR_FAIL_COND(!viewport);
+ viewport->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_gui_focus_changed));
_update_dimensions();
}
@@ -343,7 +331,7 @@ void ScrollContainer::_notification(int p_what) {
};
if (p_what == NOTIFICATION_DRAW) {
- Ref<StyleBox> sb = get_theme_stylebox("bg");
+ Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
draw_style_box(sb, Rect2(Vector2(), get_size()));
update_scrollbars();
@@ -420,7 +408,7 @@ void ScrollContainer::_notification(int p_what) {
void ScrollContainer::update_scrollbars() {
Size2 size = get_size();
- Ref<StyleBox> sb = get_theme_stylebox("bg");
+ Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
size -= sb->get_minimum_size();
Size2 hmin;
@@ -579,7 +567,6 @@ VScrollBar *ScrollContainer::get_v_scrollbar() {
}
void ScrollContainer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position);
ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll);
@@ -608,6 +595,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"));
@@ -629,12 +617,12 @@ void ScrollContainer::_bind_methods() {
ScrollContainer::ScrollContainer() {
h_scroll = memnew(HScrollBar);
h_scroll->set_name("_h_scroll");
- add_child(h_scroll);
+ add_child(h_scroll, false, INTERNAL_MODE_BACK);
h_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved));
v_scroll = memnew(VScrollBar);
v_scroll->set_name("_v_scroll");
- add_child(v_scroll);
+ add_child(v_scroll, false, INTERNAL_MODE_BACK);
v_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved));
deadzone = GLOBAL_GET("gui/common/default_scroll_deadzone");