From be4b07c3e4720e3cf1dabac1718eabf7846deae5 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Tue, 18 Oct 2022 20:03:31 -0700 Subject: [PATCH] Add `double_tap` attribute to `InputEventScreenTouch` This provides parity with the `InputEventMouseButton` allowing for proper conversion between the two events. --- core/os/input_event.cpp | 15 ++++++++++- core/os/input_event.h | 4 +++ doc/classes/InputEventScreenTouch.xml | 3 +++ main/input_default.cpp | 2 ++ platform/android/android_input_handler.cpp | 9 ++++--- platform/android/android_input_handler.h | 4 +-- .../src/org/godotengine/godot/GodotLib.java | 2 +- .../godot/input/GodotGestureHandler.kt | 25 +++++------------- .../godot/input/GodotInputHandler.java | 26 +++++++++---------- platform/android/java_godot_lib_jni.cpp | 4 +-- platform/android/java_godot_lib_jni.h | 2 +- platform/iphone/os_iphone.mm | 1 + 12 files changed, 54 insertions(+), 43 deletions(-) diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 740366db538a6..01287dce7b9ef 100644 --- a/core/os/input_event.cpp +++ b/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 InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { Ref st; st.instance(); @@ -941,12 +948,13 @@ Ref 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; } ///////////////////////////// diff --git a/core/os/input_event.h b/core/os/input_event.h index 1dd0c46f3d850..18ca447e9b6df 100644 --- a/core/os/input_event.h +++ b/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 @@ class InputEventScreenTouch : public InputEvent { 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 xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; virtual String as_text() const; diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml index d96b6c9fe5350..fc1256acc75db 100644 --- a/doc/classes/InputEventScreenTouch.xml +++ b/doc/classes/InputEventScreenTouch.xml @@ -13,6 +13,9 @@ + + If [code]true[/code], the touch's state is a double tap. + The touch index in the case of a multi-touch event. One index = one finger. diff --git a/main/input_default.cpp b/main/input_default.cpp index 3edfcbd927fcc..16f5fdfbfcfd5 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -353,6 +353,7 @@ void InputDefault::_parse_input_event_impl(const Ref &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 &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 { diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index d61cb1a116d36..4506d4ca68b45 100644 --- a/platform/android/android_input_handler.cpp +++ b/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 &p_points) { +void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const Vector &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 diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h index a1e0561075486..ac4d6927dc54a 100644 --- a/platform/android/android_input_handler.h +++ b/platform/android/android_input_handler.h @@ -90,7 +90,7 @@ class AndroidInputHandler { 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 @@ class AndroidInputHandler { 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 &p_points); + void process_touch_event(int p_event, int p_pointer, const Vector &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); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index b4515554a3e2d..f1e054050fe32 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/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 diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt index 3231877c751ec..82df9264b6be6 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt +++ b/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 } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index 5361d157464da..3fbf8667ae69a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -426,15 +426,19 @@ static boolean handleMotionEvent(final MotionEvent event) { } 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 @@ static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float 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 @@ static boolean handleTouchEvent(final MotionEvent event) { 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 @@ static boolean handleTouchEvent(int eventAction, int actionPointerId, int pointe 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; } } diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index bde70d323b3bd..7a2d34d79f530 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/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 diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index d22189b2005b9..89f3fd5e86a33 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/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); diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index 3b6cb0f5b79c0..7fb2d2278c9f6 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -295,6 +295,7 @@ 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); };