Răsfoiți Sursa

Merge pull request #99890 from Sauermann/fix-vp-mouse-notifications

Introduce `Viewport` functions for keeping the mouse over state consistent
Thaddeus Crews 7 luni în urmă
părinte
comite
654b5993e2
3 a modificat fișierele cu 34 adăugiri și 0 ștergeri
  1. 14 0
      doc/classes/Viewport.xml
  2. 18 0
      scene/main/viewport.cpp
  3. 2 0
      scene/main/viewport.h

+ 14 - 0
doc/classes/Viewport.xml

@@ -188,6 +188,20 @@
 				If [member handle_input_locally] is set to [code]false[/code], this method will try finding the first parent viewport that is set to handle input locally, and return its value for [method is_input_handled] instead.
 				If [member handle_input_locally] is set to [code]false[/code], this method will try finding the first parent viewport that is set to handle input locally, and return its value for [method is_input_handled] instead.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="notify_mouse_entered">
+			<return type="void" />
+			<description>
+				Inform the Viewport that the mouse has entered its area. Use this function before sending an [InputEventMouseButton] or [InputEventMouseMotion] to the [Viewport] with [method Viewport.push_input]. See also [method notify_mouse_exited].
+				[b]Note:[/b] In most cases, it is not necessary to call this function because [SubViewport] nodes that are children of [SubViewportContainer] are notified automatically. This is only necessary when interacting with viewports in non-default ways, for example as textures in [TextureRect] or with an [Area3D] that forwards input events.
+			</description>
+		</method>
+		<method name="notify_mouse_exited">
+			<return type="void" />
+			<description>
+				Inform the Viewport that the mouse has left its area. Use this function when the node that displays the viewport notices the mouse has left the area of the displayed viewport. See also [method notify_mouse_entered].
+				[b]Note:[/b] In most cases, it is not necessary to call this function because [SubViewport] nodes that are children of [SubViewportContainer] are notified automatically. This is only necessary when interacting with viewports in non-default ways, for example as textures in [TextureRect] or with an [Area3D] that forwards input events.
+			</description>
+		</method>
 		<method name="push_input">
 		<method name="push_input">
 			<return type="void" />
 			<return type="void" />
 			<param index="0" name="event" type="InputEvent" />
 			<param index="0" name="event" type="InputEvent" />

+ 18 - 0
scene/main/viewport.cpp

@@ -3352,6 +3352,22 @@ void Viewport::_push_unhandled_input_internal(const Ref<InputEvent> &p_event) {
 	}
 	}
 }
 }
 
 
+void Viewport::notify_mouse_entered() {
+	if (gui.mouse_in_viewport) {
+		WARN_PRINT_ED("The Viewport was previously notified that the mouse is in its area. There is no need to notify it at this time.");
+		return;
+	}
+	notification(NOTIFICATION_VP_MOUSE_ENTER);
+}
+
+void Viewport::notify_mouse_exited() {
+	if (!gui.mouse_in_viewport) {
+		WARN_PRINT_ED("The Viewport was previously notified that the mouse has left its area. There is no need to notify it at this time.");
+		return;
+	}
+	_mouse_leave_viewport();
+}
+
 void Viewport::set_physics_object_picking(bool p_enable) {
 void Viewport::set_physics_object_picking(bool p_enable) {
 	ERR_MAIN_THREAD_GUARD;
 	ERR_MAIN_THREAD_GUARD;
 	physics_object_picking = p_enable;
 	physics_object_picking = p_enable;
@@ -4799,6 +4815,8 @@ void Viewport::_bind_methods() {
 #ifndef DISABLE_DEPRECATED
 #ifndef DISABLE_DEPRECATED
 	ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false));
 #endif // DISABLE_DEPRECATED
 #endif // DISABLE_DEPRECATED
+	ClassDB::bind_method(D_METHOD("notify_mouse_entered"), &Viewport::notify_mouse_entered);
+	ClassDB::bind_method(D_METHOD("notify_mouse_exited"), &Viewport::notify_mouse_exited);
 
 
 	ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position);
 	ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position);
 	ClassDB::bind_method(D_METHOD("warp_mouse", "position"), &Viewport::warp_mouse);
 	ClassDB::bind_method(D_METHOD("warp_mouse", "position"), &Viewport::warp_mouse);

+ 2 - 0
scene/main/viewport.h

@@ -596,6 +596,8 @@ public:
 #ifndef DISABLE_DEPRECATED
 #ifndef DISABLE_DEPRECATED
 	void push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
 	void push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
 #endif // DISABLE_DEPRECATED
 #endif // DISABLE_DEPRECATED
+	void notify_mouse_entered();
+	void notify_mouse_exited();
 
 
 	void set_disable_input(bool p_disable);
 	void set_disable_input(bool p_disable);
 	bool is_input_disabled() const;
 	bool is_input_disabled() const;