Merge pull request #42360 from thebestnom/android-click-support-3.2
[3.2] Support mouse events on Android
This commit is contained in:
commit
61ad669892
10 changed files with 280 additions and 235 deletions
|
@ -31,128 +31,9 @@
|
|||
#ifndef ANDROID_KEYS_UTILS_H
|
||||
#define ANDROID_KEYS_UTILS_H
|
||||
|
||||
#include <android/input.h>
|
||||
#include <core/os/keyboard.h>
|
||||
|
||||
/*
|
||||
* Android Key codes.
|
||||
*/
|
||||
enum {
|
||||
AKEYCODE_UNKNOWN = 0,
|
||||
AKEYCODE_SOFT_LEFT = 1,
|
||||
AKEYCODE_SOFT_RIGHT = 2,
|
||||
AKEYCODE_HOME = 3,
|
||||
AKEYCODE_BACK = 4,
|
||||
AKEYCODE_CALL = 5,
|
||||
AKEYCODE_ENDCALL = 6,
|
||||
AKEYCODE_0 = 7,
|
||||
AKEYCODE_1 = 8,
|
||||
AKEYCODE_2 = 9,
|
||||
AKEYCODE_3 = 10,
|
||||
AKEYCODE_4 = 11,
|
||||
AKEYCODE_5 = 12,
|
||||
AKEYCODE_6 = 13,
|
||||
AKEYCODE_7 = 14,
|
||||
AKEYCODE_8 = 15,
|
||||
AKEYCODE_9 = 16,
|
||||
AKEYCODE_STAR = 17,
|
||||
AKEYCODE_POUND = 18,
|
||||
AKEYCODE_DPAD_UP = 19,
|
||||
AKEYCODE_DPAD_DOWN = 20,
|
||||
AKEYCODE_DPAD_LEFT = 21,
|
||||
AKEYCODE_DPAD_RIGHT = 22,
|
||||
AKEYCODE_DPAD_CENTER = 23,
|
||||
AKEYCODE_VOLUME_UP = 24,
|
||||
AKEYCODE_VOLUME_DOWN = 25,
|
||||
AKEYCODE_POWER = 26,
|
||||
AKEYCODE_CAMERA = 27,
|
||||
AKEYCODE_CLEAR = 28,
|
||||
AKEYCODE_A = 29,
|
||||
AKEYCODE_B = 30,
|
||||
AKEYCODE_C = 31,
|
||||
AKEYCODE_D = 32,
|
||||
AKEYCODE_E = 33,
|
||||
AKEYCODE_F = 34,
|
||||
AKEYCODE_G = 35,
|
||||
AKEYCODE_H = 36,
|
||||
AKEYCODE_I = 37,
|
||||
AKEYCODE_J = 38,
|
||||
AKEYCODE_K = 39,
|
||||
AKEYCODE_L = 40,
|
||||
AKEYCODE_M = 41,
|
||||
AKEYCODE_N = 42,
|
||||
AKEYCODE_O = 43,
|
||||
AKEYCODE_P = 44,
|
||||
AKEYCODE_Q = 45,
|
||||
AKEYCODE_R = 46,
|
||||
AKEYCODE_S = 47,
|
||||
AKEYCODE_T = 48,
|
||||
AKEYCODE_U = 49,
|
||||
AKEYCODE_V = 50,
|
||||
AKEYCODE_W = 51,
|
||||
AKEYCODE_X = 52,
|
||||
AKEYCODE_Y = 53,
|
||||
AKEYCODE_Z = 54,
|
||||
AKEYCODE_COMMA = 55,
|
||||
AKEYCODE_PERIOD = 56,
|
||||
AKEYCODE_ALT_LEFT = 57,
|
||||
AKEYCODE_ALT_RIGHT = 58,
|
||||
AKEYCODE_SHIFT_LEFT = 59,
|
||||
AKEYCODE_SHIFT_RIGHT = 60,
|
||||
AKEYCODE_TAB = 61,
|
||||
AKEYCODE_SPACE = 62,
|
||||
AKEYCODE_SYM = 63,
|
||||
AKEYCODE_EXPLORER = 64,
|
||||
AKEYCODE_ENVELOPE = 65,
|
||||
AKEYCODE_ENTER = 66,
|
||||
AKEYCODE_DEL = 67,
|
||||
AKEYCODE_GRAVE = 68,
|
||||
AKEYCODE_MINUS = 69,
|
||||
AKEYCODE_EQUALS = 70,
|
||||
AKEYCODE_LEFT_BRACKET = 71,
|
||||
AKEYCODE_RIGHT_BRACKET = 72,
|
||||
AKEYCODE_BACKSLASH = 73,
|
||||
AKEYCODE_SEMICOLON = 74,
|
||||
AKEYCODE_APOSTROPHE = 75,
|
||||
AKEYCODE_SLASH = 76,
|
||||
AKEYCODE_AT = 77,
|
||||
AKEYCODE_NUM = 78,
|
||||
AKEYCODE_HEADSETHOOK = 79,
|
||||
AKEYCODE_FOCUS = 80, // *Camera* focus
|
||||
AKEYCODE_PLUS = 81,
|
||||
AKEYCODE_MENU = 82,
|
||||
AKEYCODE_NOTIFICATION = 83,
|
||||
AKEYCODE_SEARCH = 84,
|
||||
AKEYCODE_MEDIA_PLAY_PAUSE = 85,
|
||||
AKEYCODE_MEDIA_STOP = 86,
|
||||
AKEYCODE_MEDIA_NEXT = 87,
|
||||
AKEYCODE_MEDIA_PREVIOUS = 88,
|
||||
AKEYCODE_MEDIA_REWIND = 89,
|
||||
AKEYCODE_MEDIA_FAST_FORWARD = 90,
|
||||
AKEYCODE_MUTE = 91,
|
||||
AKEYCODE_PAGE_UP = 92,
|
||||
AKEYCODE_PAGE_DOWN = 93,
|
||||
AKEYCODE_PICTSYMBOLS = 94,
|
||||
AKEYCODE_SWITCH_CHARSET = 95,
|
||||
AKEYCODE_BUTTON_A = 96,
|
||||
AKEYCODE_BUTTON_B = 97,
|
||||
AKEYCODE_BUTTON_C = 98,
|
||||
AKEYCODE_BUTTON_X = 99,
|
||||
AKEYCODE_BUTTON_Y = 100,
|
||||
AKEYCODE_BUTTON_Z = 101,
|
||||
AKEYCODE_BUTTON_L1 = 102,
|
||||
AKEYCODE_BUTTON_R1 = 103,
|
||||
AKEYCODE_BUTTON_L2 = 104,
|
||||
AKEYCODE_BUTTON_R2 = 105,
|
||||
AKEYCODE_BUTTON_THUMBL = 106,
|
||||
AKEYCODE_BUTTON_THUMBR = 107,
|
||||
AKEYCODE_BUTTON_START = 108,
|
||||
AKEYCODE_BUTTON_SELECT = 109,
|
||||
AKEYCODE_BUTTON_MODE = 110,
|
||||
|
||||
// NOTE: If you add a new keycode here you must also add it to several other files.
|
||||
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
|
||||
};
|
||||
|
||||
struct _WinTranslatePair {
|
||||
|
||||
unsigned int keysym;
|
||||
|
@ -247,6 +128,8 @@ static _WinTranslatePair _ak_to_keycode[] = {
|
|||
{ KEY_BACKSLASH, AKEYCODE_BACKSLASH },
|
||||
{ KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
|
||||
{ KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
|
||||
{ KEY_CONTROL, AKEYCODE_CTRL_LEFT },
|
||||
{ KEY_CONTROL, AKEYCODE_CTRL_RIGHT },
|
||||
{ KEY_UNKNOWN, 0 }
|
||||
};
|
||||
/*
|
||||
|
|
|
@ -72,6 +72,7 @@ import android.os.VibrationEffect;
|
|||
import android.os.Vibrator;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -989,65 +990,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
|||
}
|
||||
}
|
||||
|
||||
public boolean gotTouchEvent(final MotionEvent event) {
|
||||
|
||||
final int evcount = event.getPointerCount();
|
||||
if (evcount == 0)
|
||||
return true;
|
||||
|
||||
if (mView != null) {
|
||||
final int[] arr = new int[event.getPointerCount() * 3];
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
|
||||
arr[i * 3 + 0] = (int)event.getPointerId(i);
|
||||
arr[i * 3 + 1] = (int)event.getX(i);
|
||||
arr[i * 3 + 2] = (int)event.getY(i);
|
||||
}
|
||||
final int pointer_idx = event.getPointerId(event.getActionIndex());
|
||||
|
||||
//System.out.printf("gaction: %d\n",event.getAction());
|
||||
final int action = event.getAction() & MotionEvent.ACTION_MASK;
|
||||
mView.queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
GodotLib.touch(0, 0, evcount, arr);
|
||||
//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
|
||||
} break;
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
GodotLib.touch(1, 0, evcount, arr);
|
||||
/*
|
||||
for(int i=0;i<event.getPointerCount();i++) {
|
||||
System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
GodotLib.touch(4, pointer_idx, evcount, arr);
|
||||
//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
GodotLib.touch(3, pointer_idx, evcount, arr);
|
||||
//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
GodotLib.touch(2, 0, evcount, arr);
|
||||
/*
|
||||
for(int i=0;i<event.getPointerCount();i++) {
|
||||
System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
|
||||
}
|
||||
*/
|
||||
} break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
|
||||
String s = event.getCharacters();
|
||||
if (s == null || s.length() == 0)
|
||||
|
|
|
@ -93,17 +93,19 @@ public class GodotLib {
|
|||
/**
|
||||
* Forward touch events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void touch(int what, int pointer, int howmany, int[] arr);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions, int buttonsMask);
|
||||
public static native void touch(int inputDevice, int event, int pointer, int pointerCount, float[] positions, int buttonsMask, float verticalFactor, float horizontalFactor);
|
||||
|
||||
/**
|
||||
* Forward hover events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void hover(int type, int x, int y);
|
||||
public static native void hover(int type, float x, float y);
|
||||
|
||||
/**
|
||||
* Forward double_tap events from the main thread to the GL thread.
|
||||
*/
|
||||
public static native void doubletap(int x, int y);
|
||||
public static native void doubleTap(int buttonMask, int x, int y);
|
||||
|
||||
/**
|
||||
* Forward scroll events from the main thread to the GL thread.
|
||||
|
|
|
@ -99,7 +99,7 @@ public class GodotView extends GLSurfaceView {
|
|||
public boolean onTouchEvent(MotionEvent event) {
|
||||
super.onTouchEvent(event);
|
||||
this.detector.onTouchEvent(event);
|
||||
return godot.gotTouchEvent(event);
|
||||
return inputHandler.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,6 @@ package org.godotengine.godot.input;
|
|||
import org.godotengine.godot.GodotLib;
|
||||
import org.godotengine.godot.GodotView;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
|
@ -76,10 +75,11 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
|
|||
//Log.i("GodotGesture", "onDoubleTap");
|
||||
final int x = Math.round(event.getX());
|
||||
final int y = Math.round(event.getY());
|
||||
final int buttonMask = event.getButtonState();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.doubletap(x, y);
|
||||
GodotLib.doubleTap(buttonMask, x, y);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.godotengine.godot.GodotLib;
|
|||
import org.godotengine.godot.GodotView;
|
||||
import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputDevice.MotionRange;
|
||||
|
@ -157,6 +158,53 @@ public class GodotInputHandler implements InputDeviceListener {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
// Mouse drag (mouse pressed and move) doesn't fire onGenericMotionEvent so this is needed
|
||||
if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
|
||||
if (event.getAction() != MotionEvent.ACTION_MOVE) {
|
||||
// we return true because every time a mouse event is fired, the event is already handled
|
||||
// in onGenericMotionEvent, so by touch event we can say that the event is also handled
|
||||
return true;
|
||||
}
|
||||
return handleMouseEvent(event);
|
||||
}
|
||||
|
||||
final int evcount = event.getPointerCount();
|
||||
if (evcount == 0)
|
||||
return true;
|
||||
|
||||
if (godotView != null) {
|
||||
final float[] arr = new float[event.getPointerCount() * 3]; // pointerId1, x1, y1, pointerId2, etc...
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
arr[i * 3 + 0] = event.getPointerId(i);
|
||||
arr[i * 3 + 1] = event.getX(i);
|
||||
arr[i * 3 + 2] = event.getY(i);
|
||||
}
|
||||
final int action = event.getActionMasked();
|
||||
|
||||
godotView.queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
GodotLib.touch(event.getSource(), action, 0, evcount, arr);
|
||||
} break;
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
int pointer_idx = event.getPointerId(event.getActionIndex());
|
||||
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
|
||||
|
@ -191,8 +239,8 @@ public class GodotInputHandler implements InputDeviceListener {
|
|||
return true;
|
||||
}
|
||||
} else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) {
|
||||
final int x = Math.round(event.getX());
|
||||
final int y = Math.round(event.getY());
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
|
@ -201,6 +249,10 @@ public class GodotInputHandler implements InputDeviceListener {
|
|||
}
|
||||
});
|
||||
return true;
|
||||
} else if ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return handleMouseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -368,4 +420,53 @@ public class GodotInputHandler implements InputDeviceListener {
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean handleMouseEvent(final MotionEvent event) {
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_HOVER_EXIT: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.hover(type, x, y);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_BUTTON_PRESS:
|
||||
case MotionEvent.ACTION_BUTTON_RELEASE:
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int buttonsMask = event.getButtonState();
|
||||
final int action = event.getAction();
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_SCROLL: {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int buttonsMask = event.getButtonState();
|
||||
final int action = event.getAction();
|
||||
final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#include "os_android.h"
|
||||
#include "string_android.h"
|
||||
#include "thread_jandroid.h"
|
||||
|
||||
#include <android/input.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static JavaClassWrapper *java_class_wrapper = NULL;
|
||||
|
@ -272,42 +274,51 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions) {
|
||||
|
||||
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
Vector<OS_Android::TouchPos> points;
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
jint p[3];
|
||||
env->GetIntArrayRegion(positions, i * 3, 3, p);
|
||||
for (int i = 0; i < pointer_count; i++) {
|
||||
jfloat p[3];
|
||||
env->GetFloatArrayRegion(positions, i * 3, 3, p);
|
||||
OS_Android::TouchPos tp;
|
||||
tp.pos = Point2(p[1], p[2]);
|
||||
tp.id = p[0];
|
||||
tp.id = (int)p[0];
|
||||
points.push_back(tp);
|
||||
}
|
||||
|
||||
if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
|
||||
os_android->process_mouse_event(ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor);
|
||||
} else {
|
||||
os_android->process_touch(ev, pointer, points);
|
||||
|
||||
/*
|
||||
if (os_android)
|
||||
os_android->process_touch(ev,pointer,points);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jint p_x, jint p_y) {
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) {
|
||||
touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask, vertical_factor, horizontal_factor);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
os_android->process_hover(p_type, Point2(p_x, p_y));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y) {
|
||||
if (step == 0)
|
||||
return;
|
||||
|
||||
os_android->process_double_tap(Point2(p_x, p_y));
|
||||
os_android->process_double_tap(p_button_mask, Point2(p_x, p_y));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
|
||||
|
|
|
@ -44,9 +44,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
|
|||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
|
||||
JNIEXPORT void 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_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
|
||||
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask = 0, jfloat vertical_factor = 0, jfloat horizontal_factor = 0);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "file_access_jandroid.h"
|
||||
#include "net_socket_android.h"
|
||||
|
||||
#include <android/input.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "java_godot_io_wrapper.h"
|
||||
|
@ -251,13 +252,11 @@ bool OS_Android::is_mouse_grab_enabled() const {
|
|||
}
|
||||
|
||||
Point2 OS_Android::get_mouse_position() const {
|
||||
|
||||
return Point2();
|
||||
return hover_prev_pos;
|
||||
}
|
||||
|
||||
int OS_Android::get_mouse_button_state() const {
|
||||
|
||||
return 0;
|
||||
return buttons_state;
|
||||
}
|
||||
|
||||
void OS_Android::set_window_title(const String &p_title) {
|
||||
|
@ -370,15 +369,13 @@ void OS_Android::process_event(Ref<InputEvent> p_event) {
|
|||
input->parse_input_event(p_event);
|
||||
}
|
||||
|
||||
void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
|
||||
|
||||
switch (p_what) {
|
||||
case 0: { //gesture begin
|
||||
void OS_Android::process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points) {
|
||||
|
||||
switch (p_event) {
|
||||
case AMOTION_EVENT_ACTION_DOWN: { //gesture begin
|
||||
if (touch.size()) {
|
||||
//end all if exist
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
|
||||
Ref<InputEventScreenTouch> ev;
|
||||
ev.instance();
|
||||
ev->set_index(touch[i].id);
|
||||
|
@ -396,7 +393,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
|
||||
//send touch
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
|
||||
Ref<InputEventScreenTouch> ev;
|
||||
ev.instance();
|
||||
ev->set_index(touch[i].id);
|
||||
|
@ -406,15 +402,12 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
}
|
||||
|
||||
} break;
|
||||
case 1: { //motion
|
||||
|
||||
case AMOTION_EVENT_ACTION_MOVE: { //motion
|
||||
ERR_FAIL_COND(touch.size() != p_points.size());
|
||||
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
|
||||
int idx = -1;
|
||||
for (int j = 0; j < p_points.size(); j++) {
|
||||
|
||||
if (touch[i].id == p_points[j].id) {
|
||||
idx = j;
|
||||
break;
|
||||
|
@ -436,12 +429,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
}
|
||||
|
||||
} break;
|
||||
case 2: { //release
|
||||
|
||||
case AMOTION_EVENT_ACTION_CANCEL:
|
||||
case AMOTION_EVENT_ACTION_UP: { //release
|
||||
if (touch.size()) {
|
||||
//end all if exist
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
|
||||
Ref<InputEventScreenTouch> ev;
|
||||
ev.instance();
|
||||
ev->set_index(touch[i].id);
|
||||
|
@ -452,8 +444,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
touch.clear();
|
||||
}
|
||||
} break;
|
||||
case 3: { // add touch
|
||||
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN: { // add touch
|
||||
for (int i = 0; i < p_points.size(); i++) {
|
||||
if (p_points[i].id == p_pointer) {
|
||||
TouchPos tp = p_points[i];
|
||||
|
@ -471,11 +462,9 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
}
|
||||
}
|
||||
} break;
|
||||
case 4: { // remove touch
|
||||
|
||||
case AMOTION_EVENT_ACTION_POINTER_UP: { // remove touch
|
||||
for (int i = 0; i < touch.size(); i++) {
|
||||
if (touch[i].id == p_pointer) {
|
||||
|
||||
Ref<InputEventScreenTouch> ev;
|
||||
ev.instance();
|
||||
ev->set_index(touch[i].id);
|
||||
|
@ -494,9 +483,9 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
|||
void OS_Android::process_hover(int p_type, Point2 p_pos) {
|
||||
// https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
|
||||
switch (p_type) {
|
||||
case 7: // hover move
|
||||
case 9: // hover enter
|
||||
case 10: { // hover exit
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
|
||||
case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter
|
||||
case AMOTION_EVENT_ACTION_HOVER_EXIT: { // hover exit
|
||||
Ref<InputEventMouseMotion> ev;
|
||||
ev.instance();
|
||||
ev->set_position(p_pos);
|
||||
|
@ -508,12 +497,78 @@ void OS_Android::process_hover(int p_type, Point2 p_pos) {
|
|||
}
|
||||
}
|
||||
|
||||
void OS_Android::process_double_tap(Point2 p_pos) {
|
||||
void OS_Android::process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
|
||||
int event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask);
|
||||
switch (event_action) {
|
||||
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
|
||||
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS);
|
||||
int changed_button_mask = buttons_state ^ event_buttons_mask;
|
||||
|
||||
buttons_state = event_buttons_mask;
|
||||
|
||||
ev->set_button_index(_button_index_from_mask(changed_button_mask));
|
||||
ev->set_button_mask(event_buttons_mask);
|
||||
input->parse_input_event(ev);
|
||||
} break;
|
||||
|
||||
case AMOTION_EVENT_ACTION_MOVE: {
|
||||
Ref<InputEventMouseMotion> ev;
|
||||
ev.instance();
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_relative(event_pos - hover_prev_pos);
|
||||
ev->set_button_mask(event_buttons_mask);
|
||||
input->parse_input_event(ev);
|
||||
hover_prev_pos = event_pos;
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_SCROLL: {
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
ev->set_position(event_pos);
|
||||
ev->set_global_position(event_pos);
|
||||
ev->set_pressed(true);
|
||||
buttons_state = event_buttons_mask;
|
||||
if (event_vertical_factor > 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_UP, event_vertical_factor);
|
||||
} else if (event_vertical_factor < 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_DOWN, -event_vertical_factor);
|
||||
}
|
||||
|
||||
if (event_horizontal_factor > 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_RIGHT, event_horizontal_factor);
|
||||
} else if (event_horizontal_factor < 0) {
|
||||
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_LEFT, -event_horizontal_factor);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void OS_Android::_wheel_button_click(int event_buttons_mask, const Ref<InputEventMouseButton> &ev, int wheel_button, float factor) {
|
||||
Ref<InputEventMouseButton> evd = ev->duplicate();
|
||||
evd->set_button_index(wheel_button);
|
||||
evd->set_button_mask(event_buttons_mask ^ (1 << (wheel_button - 1)));
|
||||
evd->set_factor(factor);
|
||||
input->parse_input_event(evd);
|
||||
Ref<InputEventMouseButton> evdd = evd->duplicate();
|
||||
evdd->set_pressed(false);
|
||||
evdd->set_button_mask(event_buttons_mask);
|
||||
input->parse_input_event(evdd);
|
||||
}
|
||||
|
||||
void OS_Android::process_double_tap(int event_android_button_mask, Point2 p_pos) {
|
||||
int event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask);
|
||||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
ev->set_position(p_pos);
|
||||
ev->set_global_position(p_pos);
|
||||
ev->set_pressed(false);
|
||||
ev->set_pressed(event_button_mask != 0);
|
||||
ev->set_button_index(_button_index_from_mask(event_button_mask));
|
||||
ev->set_button_mask(event_button_mask);
|
||||
ev->set_doubleclick(true);
|
||||
input->parse_input_event(ev);
|
||||
}
|
||||
|
@ -527,6 +582,44 @@ void OS_Android::process_scroll(Point2 p_pos) {
|
|||
scroll_prev_pos = p_pos;
|
||||
}
|
||||
|
||||
int OS_Android::_button_index_from_mask(int button_mask) {
|
||||
switch (button_mask) {
|
||||
case BUTTON_MASK_LEFT:
|
||||
return BUTTON_LEFT;
|
||||
case BUTTON_MASK_RIGHT:
|
||||
return BUTTON_RIGHT;
|
||||
case BUTTON_MASK_MIDDLE:
|
||||
return BUTTON_MIDDLE;
|
||||
case BUTTON_MASK_XBUTTON1:
|
||||
return BUTTON_XBUTTON1;
|
||||
case BUTTON_MASK_XBUTTON2:
|
||||
return BUTTON_XBUTTON2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int OS_Android::_android_button_mask_to_godot_button_mask(int android_button_mask) {
|
||||
int godot_button_mask = 0;
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
|
||||
godot_button_mask |= BUTTON_MASK_LEFT;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
|
||||
godot_button_mask |= BUTTON_MASK_RIGHT;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) {
|
||||
godot_button_mask |= BUTTON_MASK_MIDDLE;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) {
|
||||
godot_button_mask |= BUTTON_MASK_XBUTTON1;
|
||||
}
|
||||
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
|
||||
godot_button_mask |= BUTTON_MASK_XBUTTON2;
|
||||
}
|
||||
|
||||
return godot_button_mask;
|
||||
}
|
||||
|
||||
void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) {
|
||||
|
||||
input->set_accelerometer(p_accelerometer);
|
||||
|
@ -782,6 +875,7 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
|
|||
default_videomode.height = 600;
|
||||
default_videomode.fullscreen = true;
|
||||
default_videomode.resizable = false;
|
||||
buttons_state = 0;
|
||||
|
||||
main_loop = NULL;
|
||||
gl_extensions = NULL;
|
||||
|
|
|
@ -97,6 +97,14 @@ private:
|
|||
|
||||
int video_driver_index;
|
||||
|
||||
int buttons_state;
|
||||
|
||||
static int _button_index_from_mask(int button_mask);
|
||||
|
||||
static int _android_button_mask_to_godot_button_mask(int android_button_mask);
|
||||
|
||||
void _wheel_button_click(int event_buttons_mask, const Ref<InputEventMouseButton> &ev, int wheel_button, float factor);
|
||||
|
||||
public:
|
||||
// functions used by main to initialize/deinitialize the OS
|
||||
virtual int get_video_driver_count() const;
|
||||
|
@ -187,9 +195,10 @@ public:
|
|||
void process_gravity(const Vector3 &p_gravity);
|
||||
void process_magnetometer(const Vector3 &p_magnetometer);
|
||||
void process_gyroscope(const Vector3 &p_gyroscope);
|
||||
void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
|
||||
void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
|
||||
void process_hover(int p_type, Point2 p_pos);
|
||||
void process_double_tap(Point2 p_pos);
|
||||
void process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
|
||||
void process_double_tap(int event_android_button_mask, Point2 p_pos);
|
||||
void process_scroll(Point2 p_pos);
|
||||
void process_joy_event(JoypadEvent p_event);
|
||||
void process_event(Ref<InputEvent> p_event);
|
||||
|
|
Loading…
Reference in a new issue