From 30356a488fab1af657c238f9b6a3b0803e243b38 Mon Sep 17 00:00:00 2001 From: Sofox Date: Sun, 21 Apr 2024 19:10:28 +0100 Subject: [PATCH] Enabled 'Scrolling' signal when scrolling with middle mouse on RichTextLabel/ScrollContainer --- scene/gui/rich_text_label.cpp | 18 +++++------ scene/gui/scroll_bar.cpp | 57 +++++++++++++++++++++------------- scene/gui/scroll_bar.h | 3 ++ scene/gui/scroll_container.cpp | 28 ++++++++--------- 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4a838fc7f63b..943c70eb553f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2149,12 +2149,12 @@ void RichTextLabel::gui_input(const Ref &p_event) { if (b->get_button_index() == MouseButton::WHEEL_UP) { if (scroll_active) { - vscroll->set_value(vscroll->get_value() - vscroll->get_page() * b->get_factor() * 0.5 / 8); + vscroll->scroll(-vscroll->get_page() * b->get_factor() * 0.5 / 8); } } if (b->get_button_index() == MouseButton::WHEEL_DOWN) { if (scroll_active) { - vscroll->set_value(vscroll->get_value() + vscroll->get_page() * b->get_factor() * 0.5 / 8); + vscroll->scroll(vscroll->get_page() * b->get_factor() * 0.5 / 8); } } if (b->get_button_index() == MouseButton::RIGHT && context_menu_enabled) { @@ -2169,7 +2169,7 @@ void RichTextLabel::gui_input(const Ref &p_event) { Ref pan_gesture = p_event; if (pan_gesture.is_valid()) { if (scroll_active) { - vscroll->set_value(vscroll->get_value() + vscroll->get_page() * pan_gesture->get_delta().y * 0.5 / 8); + vscroll->scroll(vscroll->get_page() * pan_gesture->get_delta().y * 0.5 / 8); } return; @@ -2182,27 +2182,27 @@ void RichTextLabel::gui_input(const Ref &p_event) { bool handled = false; if (k->is_action("ui_page_up", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - vscroll->get_page()); + vscroll->scroll(-vscroll->get_page()); handled = true; } if (k->is_action("ui_page_down", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + vscroll->get_page()); + vscroll->scroll(vscroll->get_page()); handled = true; } if (k->is_action("ui_up", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() - theme_cache.normal_font->get_height(theme_cache.normal_font_size)); + vscroll->scroll(-theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_down", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_value() + theme_cache.normal_font->get_height(theme_cache.normal_font_size)); + vscroll->scroll(vscroll->get_value() + theme_cache.normal_font->get_height(theme_cache.normal_font_size)); handled = true; } if (k->is_action("ui_home", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(0); + vscroll->scroll_to(0); handled = true; } if (k->is_action("ui_end", true) && vscroll->is_visible_in_tree()) { - vscroll->set_value(vscroll->get_max()); + vscroll->scroll_to(vscroll->get_max()); handled = true; } if (is_shortcut_keys_enabled()) { diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 1310cac2c79d..b35c4e930846 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -46,9 +46,6 @@ void ScrollBar::gui_input(const Ref &p_event) { ERR_FAIL_COND(p_event.is_null()); Ref m = p_event; - if (!m.is_valid() || drag.active) { - emit_signal(SNAME("scrolling")); - } Ref b = p_event; @@ -57,13 +54,13 @@ void ScrollBar::gui_input(const Ref &p_event) { if (b->get_button_index() == MouseButton::WHEEL_DOWN && b->is_pressed()) { double change = get_page() != 0.0 ? get_page() / 4.0 : (get_max() - get_min()) / 16.0; - set_value(get_value() + MAX(change, get_step())); + scroll(MAX(change, get_step())); accept_event(); } if (b->get_button_index() == MouseButton::WHEEL_UP && b->is_pressed()) { double change = get_page() != 0.0 ? get_page() / 4.0 : (get_max() - get_min()) / 16.0; - set_value(get_value() - MAX(change, get_step())); + scroll(-MAX(change, get_step())); accept_event(); } @@ -84,14 +81,14 @@ void ScrollBar::gui_input(const Ref &p_event) { if (ofs < decr_size) { decr_active = true; - set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); + scroll(-(custom_step >= 0 ? custom_step : get_step())); queue_redraw(); return; } if (ofs > total - incr_size) { incr_active = true; - set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); + scroll(custom_step >= 0 ? custom_step : get_step()); queue_redraw(); return; } @@ -110,7 +107,7 @@ void ScrollBar::gui_input(const Ref &p_event) { scrolling = true; set_physics_process_internal(true); } else { - set_value(target_scroll); + scroll_to(target_scroll); } return; } @@ -134,7 +131,7 @@ void ScrollBar::gui_input(const Ref &p_event) { scrolling = true; set_physics_process_internal(true); } else { - set_value(target_scroll); + scroll_to(target_scroll); } } @@ -158,7 +155,13 @@ void ScrollBar::gui_input(const Ref &p_event) { double diff = (ofs - drag.pos_at_click) / get_area_size(); + double prev_scroll = get_value(); + set_as_ratio(drag.value_at_click + diff); + + if (!Math::is_equal_approx(prev_scroll, get_value())) { + emit_signal(SNAME("scrolling")); + } } else { double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x; Ref decr = theme_cache.decrement_icon; @@ -192,32 +195,32 @@ void ScrollBar::gui_input(const Ref &p_event) { if (orientation != HORIZONTAL) { return; } - set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); + scroll(-(custom_step >= 0 ? custom_step : get_step())); } else if (p_event->is_action("ui_right", true)) { if (orientation != HORIZONTAL) { return; } - set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); + scroll(custom_step >= 0 ? custom_step : get_step()); } else if (p_event->is_action("ui_up", true)) { if (orientation != VERTICAL) { return; } - set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); + scroll(-(custom_step >= 0 ? custom_step : get_step())); } else if (p_event->is_action("ui_down", true)) { if (orientation != VERTICAL) { return; } - set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); + scroll(custom_step >= 0 ? custom_step : get_step()); } else if (p_event->is_action("ui_home", true)) { - set_value(get_min()); + scroll_to(get_min()); } else if (p_event->is_action("ui_end", true)) { - set_value(get_max()); + scroll_to(get_max()); } } } @@ -329,11 +332,11 @@ void ScrollBar::_notification(int p_what) { double vel = ((target / dist) * 500) * get_physics_process_delta_time(); if (Math::abs(vel) >= dist) { - set_value(target_scroll); + scroll_to(target_scroll); scrolling = false; set_physics_process_internal(false); } else { - set_value(get_value() + vel); + scroll(vel); } } else { scrolling = false; @@ -358,7 +361,7 @@ void ScrollBar::_notification(int p_what) { turnoff = true; } - set_value(pos.x); + scroll_to(pos.x); float sgn_x = drag_node_speed.x < 0 ? -1 : 1; float val_x = Math::abs(drag_node_speed.x); @@ -381,7 +384,7 @@ void ScrollBar::_notification(int p_what) { turnoff = true; } - set_value(pos.y); + scroll_to(pos.y); float sgn_y = drag_node_speed.y < 0 ? -1 : 1; float val_y = Math::abs(drag_node_speed.y); @@ -497,6 +500,18 @@ Size2 ScrollBar::get_minimum_size() const { return minsize; } +void ScrollBar::scroll(double p_amount) { + scroll_to(get_value() + p_amount); +} + +void ScrollBar::scroll_to(double p_position) { + double prev_scroll = get_value(); + set_value(p_position); + if (!Math::is_equal_approx(prev_scroll, get_value())) { + emit_signal(SNAME("scrolling")); + } +} + void ScrollBar::set_custom_step(float p_custom_step) { custom_step = p_custom_step; } @@ -561,11 +576,11 @@ void ScrollBar::_drag_node_input(const Ref &p_input) { Vector2 diff = drag_node_from + drag_node_accum; if (orientation == HORIZONTAL) { - set_value(diff.x); + scroll_to(diff.x); } if (orientation == VERTICAL) { - set_value(diff.y); + scroll_to(diff.y); } time_since_motion = 0; diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index deadbb53d6ac..ad88d826a28c 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -111,6 +111,9 @@ class ScrollBar : public Range { static void _bind_methods(); public: + void scroll(double p_amount); + void scroll_to(double p_position); + void set_custom_step(float p_custom_step); float get_custom_step() const; diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 1447d2f00235..4f49f60d7003 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -114,19 +114,19 @@ void ScrollContainer::gui_input(const Ref &p_gui_input) { if (mb->get_button_index() == MouseButton::WHEEL_UP) { // By default, the vertical orientation takes precedence. This is an exception. if ((h_scroll_enabled && mb->is_shift_pressed()) || v_scroll_hidden) { - h_scroll->set_value(prev_h_scroll - h_scroll->get_page() / 8 * mb->get_factor()); + h_scroll->scroll(-h_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } else if (v_scroll_enabled) { - v_scroll->set_value(prev_v_scroll - v_scroll->get_page() / 8 * mb->get_factor()); + v_scroll->scroll(-v_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } } if (mb->get_button_index() == MouseButton::WHEEL_DOWN) { if ((h_scroll_enabled && mb->is_shift_pressed()) || v_scroll_hidden) { - h_scroll->set_value(prev_h_scroll + h_scroll->get_page() / 8 * mb->get_factor()); + h_scroll->scroll(h_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } else if (v_scroll_enabled) { - v_scroll->set_value(prev_v_scroll + v_scroll->get_page() / 8 * mb->get_factor()); + v_scroll->scroll(v_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } } @@ -135,19 +135,19 @@ void ScrollContainer::gui_input(const Ref &p_gui_input) { if (mb->get_button_index() == MouseButton::WHEEL_LEFT) { // By default, the horizontal orientation takes precedence. This is an exception. if ((v_scroll_enabled && mb->is_shift_pressed()) || h_scroll_hidden) { - v_scroll->set_value(prev_v_scroll - v_scroll->get_page() / 8 * mb->get_factor()); + v_scroll->scroll(-v_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } else if (h_scroll_enabled) { - h_scroll->set_value(prev_h_scroll - h_scroll->get_page() / 8 * mb->get_factor()); + h_scroll->scroll(-h_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } } if (mb->get_button_index() == MouseButton::WHEEL_RIGHT) { if ((v_scroll_enabled && mb->is_shift_pressed()) || h_scroll_hidden) { - v_scroll->set_value(prev_v_scroll + v_scroll->get_page() / 8 * mb->get_factor()); + v_scroll->scroll(v_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } else if (h_scroll_enabled) { - h_scroll->set_value(prev_h_scroll + h_scroll->get_page() / 8 * mb->get_factor()); + h_scroll->scroll(h_scroll->get_page() / 8 * mb->get_factor()); scroll_value_modified = true; } } @@ -213,12 +213,12 @@ void ScrollContainer::gui_input(const Ref &p_gui_input) { } Vector2 diff = drag_from + drag_accum; if (h_scroll_enabled) { - h_scroll->set_value(diff.x); + h_scroll->scroll_to(diff.x); } else { drag_accum.x = 0; } if (v_scroll_enabled) { - v_scroll->set_value(diff.y); + v_scroll->scroll_to(diff.y); } else { drag_accum.y = 0; } @@ -235,10 +235,10 @@ void ScrollContainer::gui_input(const Ref &p_gui_input) { Ref pan_gesture = p_gui_input; if (pan_gesture.is_valid()) { if (h_scroll_enabled) { - h_scroll->set_value(prev_h_scroll + h_scroll->get_page() * pan_gesture->get_delta().x / 8); + h_scroll->scroll(h_scroll->get_page() * pan_gesture->get_delta().x / 8); } if (v_scroll_enabled) { - v_scroll->set_value(prev_v_scroll + v_scroll->get_page() * pan_gesture->get_delta().y / 8); + v_scroll->scroll(v_scroll->get_page() * pan_gesture->get_delta().y / 8); } if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll) { @@ -391,10 +391,10 @@ void ScrollContainer::_notification(int p_what) { } if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) { - h_scroll->set_value(pos.x); + h_scroll->scroll_to(pos.x); } if (vertical_scroll_mode != SCROLL_MODE_DISABLED) { - v_scroll->set_value(pos.y); + v_scroll->scroll_to(pos.y); } float sgn_x = drag_speed.x < 0 ? -1 : 1;