From a3f2631d593bdc46679e547019a68abc9660b42a Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 13 Nov 2022 01:29:17 +0100 Subject: [PATCH] Ported: Add double_tap attribute to InputEventScreenTouch This provides parity with the `InputEventMouseButton` allowing for proper conversion between the two events. - m4gr3d https://github.com/godotengine/godot/commit/be4b07c3e4720e3cf1dabac1718eabf7846deae5 --- core/input/input_event.cpp | 15 ++++++++++- core/input/input_event.h | 4 +++ doc/classes/InputEventScreenTouch.xml | 3 +++ main/input_default.cpp | 3 +++ platform/android/android_input_handler.cpp | 9 ++++--- platform/android/android_input_handler.h | 4 +-- .../pandemonium/PandemoniumLib.java | 2 +- .../input/PandemoniumGestureHandler.kt | 27 +++++-------------- .../input/PandemoniumInputHandler.java | 27 +++++++++---------- platform/android/java_pandemonium_lib_jni.cpp | 4 +-- platform/android/java_pandemonium_lib_jni.h | 2 +- platform/iphone/os_iphone.mm | 1 + 12 files changed, 56 insertions(+), 45 deletions(-) diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index d0202c44e..04fec5dd0 100644 --- a/core/input/input_event.cpp +++ b/core/input/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/input/input_event.h b/core/input/input_event.h index 2ea6a1204..a264a12dd 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -474,6 +474,7 @@ class InputEventScreenTouch : public InputEvent { int index; Vector2 pos; bool pressed; + bool double_tap; protected: static void _bind_methods(); @@ -488,6 +489,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 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 ef8bcb242..451f82b11 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 e2ea4f914..bab7ba81e 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,8 @@ 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 5a3bd951b..2b8e8d9bc 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -104,7 +104,7 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_scancode, int p 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++) { @@ -113,17 +113,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 @@ -137,7 +138,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 21cd1ef86..acc04a835 100644 --- a/platform/android/android_input_handler.h +++ b/platform/android/android_input_handler.h @@ -89,7 +89,7 @@ private: void _release_mouse_event_info(bool p_source_mouse_relative = false); - void _parse_all_touch(bool p_pressed); + void _parse_all_touch(bool p_pressed, bool p_double_tap); void _release_all_touch(); @@ -97,7 +97,7 @@ public: void process_joy_event(const JoypadEvent &p_event); void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, 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, bool p_source_mouse_relative); - 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/net/relintai/pandemonium/pandemonium/PandemoniumLib.java b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumLib.java index 06ba9fdba..96a741c13 100644 --- a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumLib.java +++ b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumLib.java @@ -93,7 +93,7 @@ public class PandemoniumLib { /** * 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/net/relintai/pandemonium/pandemonium/input/PandemoniumGestureHandler.kt b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumGestureHandler.kt index f3ec378e7..059cc2037 100644 --- a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumGestureHandler.kt +++ b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumGestureHandler.kt @@ -55,18 +55,15 @@ internal class PandemoniumGestureHandler : SimpleOnGestureListener(), OnScaleGes */ var panningAndScalingEnabled = false - private var doubleTapInProgress = false + private var nextDownIsDoubleTap = false private var dragInProgress = false private var scaleInProgress = false private var contextClickInProgress = false private var pointerCaptureInProgress = 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 - PandemoniumInputHandler.handleMotionEvent(event) - } + PandemoniumInputHandler.handleMotionEvent(event.source, MotionEvent.ACTION_DOWN, event.buttonState, event.x, event.y, nextDownIsDoubleTap) + nextDownIsDoubleTap = false return true } @@ -200,25 +197,15 @@ internal class PandemoniumGestureHandler : SimpleOnGestureListener(), OnScaleGes override fun onDoubleTapEvent(event: MotionEvent): Boolean { if (event.actionMasked == MotionEvent.ACTION_UP) { - doubleTapInProgress = false + nextDownIsDoubleTap = false + PandemoniumInputHandler.handleMotionEvent(event) } + return true } override fun onDoubleTap(event: MotionEvent): Boolean { - doubleTapInProgress = true - val x = event.x - val y = event.y - val buttonMask = - if (PandemoniumInputHandler.isMouseEvent(event)) { - event.buttonState - } else { - MotionEvent.BUTTON_PRIMARY - } - - PandemoniumInputHandler.handleMouseEvent(MotionEvent.ACTION_DOWN, buttonMask, x, y, true) - PandemoniumInputHandler.handleMouseEvent(MotionEvent.ACTION_UP, 0, x, y, false) - + nextDownIsDoubleTap = true return true } diff --git a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumInputHandler.java b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumInputHandler.java index 1191fa248..df650596f 100644 --- a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumInputHandler.java +++ b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/input/PandemoniumInputHandler.java @@ -434,16 +434,19 @@ public class PandemoniumInputHandler 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, false); + return handleMouseEvent(eventAction, buttonsMask, x, y, deltaX, deltaY, doubleTap, false); } - return handleTouchEvent(eventAction, x, y); + return handleTouchEvent(eventAction, x, y, doubleTap); } static boolean handleMouseEvent(final MotionEvent event) { @@ -470,10 +473,6 @@ public class PandemoniumInputHandler implements InputManager.InputDeviceListener return handleMouseEvent(eventAction, buttonsMask, x, y, 0, 0, doubleClick, 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, boolean sourceMouseRelative) { // We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically // follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate @@ -513,14 +512,14 @@ public class PandemoniumInputHandler 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: @@ -528,7 +527,7 @@ public class PandemoniumInputHandler implements InputManager.InputDeviceListener case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_DOWN: { - PandemoniumLib.dispatchTouchEvent(eventAction, actionPointerId, pointerCount, positions); + PandemoniumLib.dispatchTouchEvent(eventAction, actionPointerId, pointerCount, positions, doubleTap); return true; } } diff --git a/platform/android/java_pandemonium_lib_jni.cpp b/platform/android/java_pandemonium_lib_jni.cpp index 3ca587741..cfb260ede 100644 --- a/platform/android/java_pandemonium_lib_jni.cpp +++ b/platform/android/java_pandemonium_lib_jni.cpp @@ -287,7 +287,7 @@ JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_ } // Called on the UI thread -JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray position) { +JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray position, jboolean p_double_tap) { if (step.get() <= 0) return; @@ -301,7 +301,7 @@ JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_ 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_pandemonium_lib_jni.h b/platform/android/java_pandemonium_lib_jni.h index 414e6e0b6..50a5d21fd 100644 --- a/platform/android/java_pandemonium_lib_jni.h +++ b/platform/android/java_pandemonium_lib_jni.h @@ -45,7 +45,7 @@ JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_ JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_step(JNIEnv *env, jclass clazz); JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_back(JNIEnv *env, jclass clazz); JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_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, jboolean p_source_mouse_relative); -JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions); +JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_dispatchTouchEvent(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jboolean p_double_tap); JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_magnify(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_factor); JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_pan(JNIEnv *env, jclass clazz, jfloat p_x, jfloat p_y, jfloat p_delta_x, jfloat p_delta_y); JNIEXPORT void JNICALL Java_net_relintai_pandemonium_pandemonium_PandemoniumLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed); diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index b099a16f3..d53f34f9d 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -240,6 +240,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); };