Browse Source

Merge pull request #90988 from TheSofox/scrolling-signal-fix

Enable `Scrolling` signal when scrolling with middle mouse on `RichTextLabel` or `ScrollContainer`
Rémi Verschelde 1 year ago
parent
commit
7abe0c6014
4 changed files with 62 additions and 44 deletions
  1. 9 9
      scene/gui/rich_text_label.cpp
  2. 36 21
      scene/gui/scroll_bar.cpp
  3. 3 0
      scene/gui/scroll_bar.h
  4. 14 14
      scene/gui/scroll_container.cpp

+ 9 - 9
scene/gui/rich_text_label.cpp

@@ -2149,12 +2149,12 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &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<InputEvent> &p_event) {
 	Ref<InputEventPanGesture> 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<InputEvent> &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()) {

+ 36 - 21
scene/gui/scroll_bar.cpp

@@ -46,9 +46,6 @@ void ScrollBar::gui_input(const Ref<InputEvent> &p_event) {
 	ERR_FAIL_COND(p_event.is_null());
 
 	Ref<InputEventMouseMotion> m = p_event;
-	if (!m.is_valid() || drag.active) {
-		emit_signal(SNAME("scrolling"));
-	}
 
 	Ref<InputEventMouseButton> b = p_event;
 
@@ -57,13 +54,13 @@ void ScrollBar::gui_input(const Ref<InputEvent> &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<InputEvent> &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<InputEvent> &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<InputEvent> &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<InputEvent> &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<Texture2D> decr = theme_cache.decrement_icon;
@@ -192,32 +195,32 @@ void ScrollBar::gui_input(const Ref<InputEvent> &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<InputEvent> &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;

+ 3 - 0
scene/gui/scroll_bar.h

@@ -111,6 +111,9 @@ protected:
 	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;
 

+ 14 - 14
scene/gui/scroll_container.cpp

@@ -114,19 +114,19 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &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<InputEvent> &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<InputEvent> &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<InputEvent> &p_gui_input) {
 	Ref<InputEventPanGesture> 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;