Browse Source

Merge pull request #67607 from m4gr3d/input_event_screen_touch_double_tap_3x

[3.x] Add `double_tap` attribute to `InputEventScreenTouch`
Fredia Huya-Kouadio 2 years ago
parent
commit
33b80bd933

+ 14 - 1
core/os/input_event.cpp

@@ -934,6 +934,13 @@ bool InputEventScreenTouch::is_pressed() const {
 	return pressed;
 }
 
+void InputEventScreenTouch::set_double_tap(bool p_double_tap) {
+	double_tap = p_double_tap;
+}
+bool InputEventScreenTouch::is_double_tap() const {
+	return double_tap;
+}
+
 Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
 	Ref<InputEventScreenTouch> st;
 	st.instance();
@@ -941,12 +948,13 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co
 	st->set_index(index);
 	st->set_position(p_xform.xform(pos + p_local_ofs));
 	st->set_pressed(pressed);
+	st->set_double_tap(double_tap);
 
 	return st;
 }
 
 String InputEventScreenTouch::as_text() const {
-	return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")";
+	return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + "), double_tap=" + (double_tap ? "true" : "false");
 }
 
 void InputEventScreenTouch::_bind_methods() {
@@ -959,14 +967,19 @@ void InputEventScreenTouch::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventScreenTouch::set_pressed);
 	//ClassDB::bind_method(D_METHOD("is_pressed"),&InputEventScreenTouch::is_pressed);
 
+	ClassDB::bind_method(D_METHOD("set_double_tap", "double_tap"), &InputEventScreenTouch::set_double_tap);
+	ClassDB::bind_method(D_METHOD("is_double_tap"), &InputEventScreenTouch::is_double_tap);
+
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "double_tap"), "set_double_tap", "is_double_tap");
 }
 
 InputEventScreenTouch::InputEventScreenTouch() {
 	index = 0;
 	pressed = false;
+	double_tap = false;
 }
 
 /////////////////////////////

+ 4 - 0
core/os/input_event.h

@@ -475,6 +475,7 @@ class InputEventScreenTouch : public InputEvent {
 	int index;
 	Vector2 pos;
 	bool pressed;
+	bool double_tap;
 
 protected:
 	static void _bind_methods();
@@ -489,6 +490,9 @@ public:
 	void set_pressed(bool p_pressed);
 	virtual bool is_pressed() const;
 
+	void set_double_tap(bool p_double_tap);
+	bool is_double_tap() const;
+
 	virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
 	virtual String as_text() const;
 

+ 3 - 0
doc/classes/InputEventScreenTouch.xml

@@ -13,6 +13,9 @@
 	<methods>
 	</methods>
 	<members>
+		<member name="double_tap" type="bool" setter="set_double_tap" getter="is_double_tap" default="false">
+			If [code]true[/code], the touch's state is a double tap.
+		</member>
 		<member name="index" type="int" setter="set_index" getter="get_index" default="0">
 			The touch index in the case of a multi-touch event. One index = one finger.
 		</member>

+ 2 - 0
main/input_default.cpp

@@ -353,6 +353,7 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
 			touch_event.instance();
 			touch_event->set_pressed(mb->is_pressed());
 			touch_event->set_position(mb->get_position());
+			touch_event->set_double_tap(mb->is_doubleclick());
 			main_loop->input_event(touch_event);
 		}
 	}
@@ -414,6 +415,7 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool
 				button_event->set_global_position(st->get_position());
 				button_event->set_pressed(st->is_pressed());
 				button_event->set_button_index(BUTTON_LEFT);
+				button_event->set_doubleclick(st->is_double_tap());
 				if (st->is_pressed()) {
 					button_event->set_button_mask(mouse_button_mask | (1 << (BUTTON_LEFT - 1)));
 				} else {

+ 5 - 4
platform/android/android_input_handler.cpp

@@ -100,7 +100,7 @@ void AndroidInputHandler::process_key_event(int p_scancode, int p_physical_scanc
 	input->parse_input_event(ev);
 }
 
-void AndroidInputHandler::_parse_all_touch(bool p_pressed) {
+void AndroidInputHandler::_parse_all_touch(bool p_pressed, bool p_double_tap) {
 	if (touch.size()) {
 		//end all if exist
 		for (int i = 0; i < touch.size(); i++) {
@@ -109,17 +109,18 @@ void AndroidInputHandler::_parse_all_touch(bool p_pressed) {
 			ev->set_index(touch[i].id);
 			ev->set_pressed(p_pressed);
 			ev->set_position(touch[i].pos);
+			ev->set_double_tap(p_double_tap);
 			input->parse_input_event(ev);
 		}
 	}
 }
 
 void AndroidInputHandler::_release_all_touch() {
-	_parse_all_touch(false);
+	_parse_all_touch(false, false);
 	touch.clear();
 }
 
-void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points) {
+void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points, bool p_double_tap) {
 	switch (p_event) {
 		case AMOTION_EVENT_ACTION_DOWN: { //gesture begin
 			// Release any remaining touches or mouse event
@@ -133,7 +134,7 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const
 			}
 
 			//send touch
-			_parse_all_touch(true);
+			_parse_all_touch(true, p_double_tap);
 
 		} break;
 		case AMOTION_EVENT_ACTION_MOVE: { //motion

+ 2 - 2
platform/android/android_input_handler.h

@@ -90,7 +90,7 @@ private:
 
 	void _release_mouse_event_info();
 
-	void _parse_all_touch(bool p_pressed);
+	void _parse_all_touch(bool p_pressed, bool p_double_tap);
 
 	void _release_all_touch();
 
@@ -98,7 +98,7 @@ public:
 	void process_joy_event(const JoypadEvent &p_event);
 	void process_key_event(int p_scancode, int p_physical_scancode, int p_unicode, bool p_pressed);
 	void process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click);
-	void process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
+	void process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points, bool p_double_tap);
 	void process_magnify(Point2 p_pos, float p_factor);
 	void process_pan(Point2 p_pos, Vector2 p_delta);
 	void joy_connection_changed(int p_device, bool p_connected, String p_name);

+ 1 - 1
platform/android/java/lib/src/org/godotengine/godot/GodotLib.java

@@ -100,7 +100,7 @@ public class GodotLib {
 	/**
 	 * Forward touch events.
 	 */
-	public static native void dispatchTouchEvent(int event, int pointer, int pointerCount, float[] positions);
+	public static native void dispatchTouchEvent(int event, int pointer, int pointerCount, float[] positions, boolean doubleTap);
 
 	/**
 	 * Dispatch mouse events

+ 6 - 19
platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt

@@ -53,17 +53,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
 	 */
 	var panningAndScalingEnabled = false
 
-	private var doubleTapInProgress = false
+	private var nextDownIsDoubleTap = false
 	private var dragInProgress = false
 	private var scaleInProgress = false
 	private var contextClickInProgress = false
 
 	override fun onDown(event: MotionEvent): Boolean {
-		// Don't send / register a down event while we're in the middle of a double-tap
-		if (!doubleTapInProgress) {
-			// Send the down event
-			GodotInputHandler.handleMotionEvent(event)
-		}
+		GodotInputHandler.handleMotionEvent(event.source, MotionEvent.ACTION_DOWN, event.buttonState, event.x, event.y, nextDownIsDoubleTap)
+		nextDownIsDoubleTap = false
 		return true
 	}
 
@@ -145,24 +142,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
 
 	override fun onDoubleTapEvent(event: MotionEvent): Boolean {
 		if (event.actionMasked == MotionEvent.ACTION_UP) {
-			doubleTapInProgress = false
+			nextDownIsDoubleTap = false
+			GodotInputHandler.handleMotionEvent(event)
 		}
 		return true
 	}
 
 	override fun onDoubleTap(event: MotionEvent): Boolean {
-		doubleTapInProgress = true
-		val x = event.x
-		val y = event.y
-		val buttonMask =
-			if (GodotInputHandler.isMouseEvent(event)) {
-				event.buttonState
-			} else {
-				MotionEvent.BUTTON_PRIMARY
-			}
-		GodotInputHandler.handleMouseEvent(MotionEvent.ACTION_DOWN, buttonMask, x, y, true)
-		GodotInputHandler.handleMouseEvent(MotionEvent.ACTION_UP, 0, x, y, false)
-
+		nextDownIsDoubleTap = true
 		return true
 	}
 

+ 13 - 13
platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java

@@ -426,15 +426,19 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
 	}
 
 	static boolean handleMotionEvent(int eventSource, int eventAction, int buttonsMask, float x, float y) {
-		return handleMotionEvent(eventSource, eventAction, buttonsMask, x, y, 0, 0);
+		return handleMotionEvent(eventSource, eventAction, buttonsMask, x, y, false);
 	}
 
-	static boolean handleMotionEvent(int eventSource, int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY) {
+	static boolean handleMotionEvent(int eventSource, int eventAction, int buttonsMask, float x, float y, boolean doubleTap) {
+		return handleMotionEvent(eventSource, eventAction, buttonsMask, x, y, 0, 0, doubleTap);
+	}
+
+	static boolean handleMotionEvent(int eventSource, int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleTap) {
 		if (isMouseEvent(eventSource)) {
-			return handleMouseEvent(eventAction, buttonsMask, x, y, deltaX, deltaY, false);
+			return handleMouseEvent(eventAction, buttonsMask, x, y, deltaX, deltaY, doubleTap);
 		}
 
-		return handleTouchEvent(eventAction, x, y);
+		return handleTouchEvent(eventAction, x, y, doubleTap);
 	}
 
 	static boolean handleMouseEvent(final MotionEvent event) {
@@ -452,10 +456,6 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
 		return handleMouseEvent(eventAction, buttonsMask, x, y, 0, 0, false);
 	}
 
-	static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, boolean doubleClick) {
-		return handleMouseEvent(eventAction, buttonsMask, x, y, 0, 0, doubleClick);
-	}
-
 	static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick) {
 		switch (eventAction) {
 			case MotionEvent.ACTION_CANCEL:
@@ -492,14 +492,14 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
 		final int action = event.getActionMasked();
 		final int actionPointerId = event.getPointerId(event.getActionIndex());
 
-		return handleTouchEvent(action, actionPointerId, pointerCount, positions);
+		return handleTouchEvent(action, actionPointerId, pointerCount, positions, false);
 	}
 
-	static boolean handleTouchEvent(int eventAction, float x, float y) {
-		return handleTouchEvent(eventAction, 0, 1, new float[] { 0, x, y });
+	static boolean handleTouchEvent(int eventAction, float x, float y, boolean doubleTap) {
+		return handleTouchEvent(eventAction, 0, 1, new float[] { 0, x, y }, doubleTap);
 	}
 
-	static boolean handleTouchEvent(int eventAction, int actionPointerId, int pointerCount, float[] positions) {
+	static boolean handleTouchEvent(int eventAction, int actionPointerId, int pointerCount, float[] positions, boolean doubleTap) {
 		switch (eventAction) {
 			case MotionEvent.ACTION_DOWN:
 			case MotionEvent.ACTION_CANCEL:
@@ -507,7 +507,7 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
 			case MotionEvent.ACTION_MOVE:
 			case MotionEvent.ACTION_POINTER_UP:
 			case MotionEvent.ACTION_POINTER_DOWN: {
-				GodotLib.dispatchTouchEvent(eventAction, actionPointerId, pointerCount, positions);
+				GodotLib.dispatchTouchEvent(eventAction, actionPointerId, pointerCount, positions, doubleTap);
 				return true;
 			}
 		}

+ 2 - 2
platform/android/java_godot_lib_jni.cpp

@@ -292,7 +292,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchMouseEvent(JN
 }
 
 // Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray position) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray position, jboolean p_double_tap) {
 	if (step.get() <= 0) {
 		return;
 	}
@@ -306,7 +306,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JN
 		points.push_back(tp);
 	}
 
-	input_handler->process_touch_event(ev, pointer, points);
+	input_handler->process_touch_event(ev, pointer, points, p_double_tap);
 }
 
 // Called on the UI thread

+ 1 - 1
platform/android/java_godot_lib_jni.h

@@ -46,7 +46,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ttsCallback(JNIEnv *e
 JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
 JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
 JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchMouseEvent(JNIEnv *env, jclass clazz, jint p_event_type, jint p_button_mask, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y, jboolean p_double_click);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jboolean p_double_tap);
 JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnify(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_factor);
 JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_pan(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y);
 JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_scancode, jint p_physical_scancode, jint p_unicode, jboolean p_pressed);

+ 1 - 0
platform/iphone/os_iphone.mm

@@ -295,6 +295,7 @@ void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_d
 	ev->set_index(p_idx);
 	ev->set_pressed(p_pressed);
 	ev->set_position(Vector2(p_x, p_y));
+	ev->set_double_tap(p_doubleclick);
 	perform_event(ev);
 };