diff options
Diffstat (limited to 'platform/android/java/lib/src')
9 files changed, 215 insertions, 148 deletions
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java index 138c2de94c..5aa48d87da 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -34,6 +34,8 @@ import android.content.Intent;  import android.os.Bundle;  import android.view.KeyEvent; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable;  import androidx.fragment.app.FragmentActivity;  /** @@ -43,13 +45,18 @@ import androidx.fragment.app.FragmentActivity;   * within an Android app.   */  public abstract class FullScreenGodotApp extends FragmentActivity { -	protected Godot godotFragment; +	@Nullable +	private Godot godotFragment;  	@Override  	public void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState);  		setContentView(R.layout.godot_app_layout); -		godotFragment = new Godot(); +		godotFragment = initGodotInstance(); +		if (godotFragment == null) { +			throw new IllegalStateException("Godot instance must be non-null."); +		} +  		getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss();  	} @@ -76,4 +83,17 @@ public abstract class FullScreenGodotApp extends FragmentActivity {  		}  		return super.onKeyMultiple(inKeyCode, repeatCount, event);  	} + +	/** +	 * Used to initialize the Godot fragment instance in {@link FullScreenGodotApp#onCreate(Bundle)}. +	 */ +	@NonNull +	protected Godot initGodotInstance() { +		return new Godot(); +	} + +	@Nullable +	protected final Godot getGodotFragment() { +		return godotFragment; +	}  } diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 35852f31ef..6cf340c418 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -56,6 +56,8 @@ import android.content.SharedPreferences.Editor;  import android.content.pm.ConfigurationInfo;  import android.content.pm.PackageManager;  import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.Point; +import android.graphics.Rect;  import android.hardware.Sensor;  import android.hardware.SensorEvent;  import android.hardware.SensorEventListener; @@ -68,6 +70,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; @@ -75,6 +78,7 @@ import android.view.Surface;  import android.view.View;  import android.view.ViewGroup;  import android.view.ViewGroup.LayoutParams; +import android.view.ViewTreeObserver;  import android.view.Window;  import android.view.WindowManager;  import android.widget.Button; @@ -148,8 +152,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  	private void setButtonPausedState(boolean paused) {  		mStatePaused = paused; -		int stringResourceID = paused ? R.string.text_button_resume : -										R.string.text_button_pause; +		int stringResourceID = paused ? R.string.text_button_resume : R.string.text_button_pause;  		mPauseButton.setText(stringResourceID);  	} @@ -160,8 +163,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  	public GodotRenderView mRenderView;  	private boolean godot_initialized = false; -	private GodotEditText mEditText; -  	private SensorManager mSensorManager;  	private Sensor mAccelerometer;  	private Sensor mGravity; @@ -218,6 +219,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  		containerLayout = new FrameLayout(activity);  		containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); +		// GodotEditText layout +		GodotEditText editText = new GodotEditText(activity); +		editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, +				(int)getResources().getDimension(R.dimen.text_edit_height))); +		// ...add to FrameLayout +		containerLayout.addView(editText); +  		GodotLib.setup(command_line);  		final String videoDriver = GodotLib.getGlobal("rendering/quality/driver/driver_name"); @@ -230,9 +238,21 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  		View view = mRenderView.getView();  		containerLayout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); +		editText.setView(mRenderView); +		io.setEdit(editText); -		mEditText = new GodotEditText(activity, mRenderView); -		io.setEdit(mEditText); +		view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { +			@Override +			public void onGlobalLayout() { +				Point fullSize = new Point(); +				activity.getWindowManager().getDefaultDisplay().getSize(fullSize); +				Rect gameSize = new Rect(); +				mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); + +				final int keyboardHeight = fullSize.y - gameSize.bottom; +				GodotLib.setVirtualKeyboardHeight(keyboardHeight); +			} +		});  		mRenderView.queueOnRenderThread(new Runnable() {  			@Override @@ -448,7 +468,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  		final Activity activity = getActivity();  		Window window = activity.getWindow();  		window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); -		window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);  		mClipboard = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE);  		pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this); @@ -585,21 +604,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  	}  	@Override -	public void onStart() { -		super.onStart(); - -		mRenderView.getView().post(new Runnable() { -			@Override -			public void run() { -				mEditText.onInitView(); -			} -		}); -	} - -	@Override  	public void onDestroy() { -		mEditText.onDestroyView(); -  		for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {  			plugin.onMainDestroy();  		} @@ -850,63 +855,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 (mRenderView != 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; -			mRenderView.queueOnRenderThread(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) diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index d169f46599..d731e080c4 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -29,7 +29,6 @@  /*************************************************************************/  package org.godotengine.godot; -  import org.godotengine.godot.input.GodotGestureHandler;  import org.godotengine.godot.input.GodotInputHandler;  import org.godotengine.godot.utils.GLUtils; @@ -127,7 +126,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView  	public boolean onTouchEvent(MotionEvent event) {  		super.onTouchEvent(event);  		this.detector.onTouchEvent(event); -		return godot.gotTouchEvent(event); +		return inputHandler.onTouchEvent(event);  	}  	@Override diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index c2f3c88416..874fd88848 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -37,12 +37,16 @@ import android.content.*;  import android.content.Intent;  import android.content.pm.ActivityInfo;  import android.content.res.AssetManager; +import android.graphics.Point;  import android.media.*;  import android.net.Uri;  import android.os.*;  import android.util.DisplayMetrics;  import android.util.Log;  import android.util.SparseArray; +import android.view.Display; +import android.view.DisplayCutout; +import android.view.WindowInsets;  import java.io.IOException;  import java.io.InputStream; @@ -461,6 +465,28 @@ public class GodotIO {  		return (int)(metrics.density * 160f);  	} +	public int[] screenGetUsableRect() { +		DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); +		Display display = activity.getWindowManager().getDefaultDisplay(); +		Point size = new Point(); +		display.getRealSize(size); + +		int result[] = { 0, 0, size.x, size.y }; +		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { +			WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets(); +			DisplayCutout cutout = insets.getDisplayCutout(); +			if (cutout != null) { +				int insetLeft = cutout.getSafeInsetLeft(); +				int insetTop = cutout.getSafeInsetTop(); +				result[0] = insetLeft; +				result[1] = insetTop; +				result[2] -= insetLeft + cutout.getSafeInsetRight(); +				result[3] -= insetTop + cutout.getSafeInsetBottom(); +			} +		} +		return result; +	} +  	public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {  		if (edit != null)  			edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); 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 318e2816ff..6ccbe91e60 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -94,17 +94,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. diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java index 65708389c3..6cd5ca7b4e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -38,6 +38,7 @@ import org.godotengine.godot.vulkan.VkSurfaceView;  import android.annotation.SuppressLint;  import android.content.Context;  import android.view.GestureDetector; +import android.view.InputDevice;  import android.view.KeyEvent;  import android.view.MotionEvent;  import android.view.SurfaceView; @@ -100,22 +101,22 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV  	public boolean onTouchEvent(MotionEvent event) {  		super.onTouchEvent(event);  		mGestureDetector.onTouchEvent(event); -		return godot.gotTouchEvent(event); +		return mInputHandler.onTouchEvent(event);  	}  	@Override  	public boolean onKeyUp(final int keyCode, KeyEvent event) { -		return mInputHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event); +		return mInputHandler.onKeyUp(keyCode, event);  	}  	@Override  	public boolean onKeyDown(final int keyCode, KeyEvent event) { -		return mInputHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event); +		return mInputHandler.onKeyDown(keyCode, event);  	}  	@Override  	public boolean onGenericMotionEvent(MotionEvent event) { -		return mInputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event); +		return mInputHandler.onGenericMotionEvent(event);  	}  	@Override diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index 6855f91f1c..c95339c583 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -32,27 +32,16 @@ package org.godotengine.godot.input;  import org.godotengine.godot.*; -import android.app.Activity;  import android.content.Context; -import android.graphics.Point; -import android.graphics.Rect;  import android.os.Handler;  import android.os.Message;  import android.text.InputFilter;  import android.text.InputType;  import android.util.AttributeSet; -import android.view.Gravity;  import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.view.ViewTreeObserver; -import android.view.WindowManager;  import android.view.inputmethod.EditorInfo;  import android.view.inputmethod.InputMethodManager;  import android.widget.EditText; -import android.widget.FrameLayout; -import android.widget.PopupWindow;  import java.lang.ref.WeakReference; @@ -67,8 +56,6 @@ public class GodotEditText extends EditText {  	// Fields  	// ===========================================================  	private GodotRenderView mRenderView; -	private View mKeyboardView; -	private PopupWindow mKeyboardWindow;  	private GodotTextInputWrapper mInputWrapper;  	private EditHandler sHandler = new EditHandler(this);  	private String mOriginText; @@ -93,52 +80,24 @@ public class GodotEditText extends EditText {  	// ===========================================================  	// Constructors  	// =========================================================== -	public GodotEditText(final Context context, final GodotRenderView view) { +	public GodotEditText(final Context context) {  		super(context); +		initView(); +	} -		setPadding(0, 0, 0, 0); -		setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); -		setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - -		mRenderView = view; -		mInputWrapper = new GodotTextInputWrapper(mRenderView, this); -		setOnEditorActionListener(mInputWrapper); -		view.getView().requestFocus(); - -		// Create a popup window with an invisible layout for the virtual keyboard, -		// so the view can be resized to get the vk height without resizing the main godot view. -		final FrameLayout keyboardLayout = new FrameLayout(context); -		keyboardLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); -		keyboardLayout.setVisibility(View.INVISIBLE); -		keyboardLayout.addView(this); -		mKeyboardView = keyboardLayout; - -		mKeyboardWindow = new PopupWindow(keyboardLayout, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); -		mKeyboardWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); -		mKeyboardWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); -		mKeyboardWindow.setFocusable(true); // for the text edit to work -		mKeyboardWindow.setTouchable(false); // inputs need to go through - -		keyboardLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { -			@Override -			public void onGlobalLayout() { -				Point fullSize = new Point(); -				((Activity)mRenderView.getView().getContext()).getWindowManager().getDefaultDisplay().getSize(fullSize); -				Rect gameSize = new Rect(); -				mKeyboardWindow.getContentView().getWindowVisibleDisplayFrame(gameSize); - -				final int keyboardHeight = fullSize.y - gameSize.bottom; -				GodotLib.setVirtualKeyboardHeight(keyboardHeight); -			} -		}); +	public GodotEditText(final Context context, final AttributeSet attrs) { +		super(context, attrs); +		initView();  	} -	public void onInitView() { -		mKeyboardWindow.showAtLocation(mRenderView.getView(), Gravity.NO_GRAVITY, 0, 0); +	public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) { +		super(context, attrs, defStyle); +		initView();  	} -	public void onDestroyView() { -		mKeyboardWindow.dismiss(); +	protected void initView() { +		setPadding(0, 0, 0, 0); +		setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE);  	}  	public boolean isMultiline() { @@ -170,7 +129,7 @@ public class GodotEditText extends EditText {  					edit.mInputWrapper.setOriginText(text);  					edit.addTextChangedListener(edit.mInputWrapper); -					final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); +					final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);  					imm.showSoftInput(edit, 0);  				}  			} break; @@ -179,7 +138,7 @@ public class GodotEditText extends EditText {  				GodotEditText edit = (GodotEditText)msg.obj;  				edit.removeTextChangedListener(mInputWrapper); -				final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); +				final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);  				imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);  				edit.mRenderView.getView().requestFocus();  			} break; @@ -193,6 +152,17 @@ public class GodotEditText extends EditText {  	}  	// =========================================================== +	// Getter & Setter +	// =========================================================== +	public void setView(final GodotRenderView view) { +		mRenderView = view; +		if (mInputWrapper == null) +			mInputWrapper = new GodotTextInputWrapper(mRenderView, this); +		setOnEditorActionListener(mInputWrapper); +		view.getView().requestFocus(); +	} + +	// ===========================================================  	// Methods for/from SuperClass/Interfaces  	// ===========================================================  	@Override diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index 1c9a683bbd..fb151fa504 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -33,7 +33,6 @@ package org.godotengine.godot.input;  import org.godotengine.godot.GodotLib;  import org.godotengine.godot.GodotRenderView; -import android.util.Log;  import android.view.GestureDetector;  import android.view.MotionEvent; @@ -75,10 +74,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; 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 9abd65cc67..f3e985f944 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 @@ -36,6 +36,7 @@ import org.godotengine.godot.GodotLib;  import org.godotengine.godot.GodotRenderView;  import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; +import android.os.Build;  import android.util.Log;  import android.view.InputDevice;  import android.view.InputDevice.MotionRange; @@ -156,6 +157,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 (mRenderView != 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(); + +			mRenderView.queueOnRenderThread(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) {  			final int device_id = findJoystickDevice(event.getDeviceId()); @@ -189,8 +237,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 @@ -199,6 +247,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; @@ -366,4 +418,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; +	}  }  |