diff options
Diffstat (limited to 'platform/android/java/lib')
12 files changed, 257 insertions, 182 deletions
diff --git a/platform/android/java/lib/CMakeLists.txt b/platform/android/java/lib/CMakeLists.txt deleted file mode 100644 index d3bdf6a5f2..0000000000 --- a/platform/android/java/lib/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required(VERSION 3.6) -project(godot) - -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -set(GODOT_ROOT_DIR ../../../..) - -# Get sources -file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**) -file(GLOB_RECURSE HEADERS ${GODOT_ROOT_DIR}/*.h**) - -add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) -target_include_directories(${PROJECT_NAME} -        SYSTEM PUBLIC -        ${GODOT_ROOT_DIR} -        ${GODOT_ROOT_DIR}/modules/gdnative/include) diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 19eee5a315..89ce3d15e6 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -18,6 +18,11 @@ android {          targetSdkVersion versions.targetSdk      } +    compileOptions { +        sourceCompatibility versions.javaVersion +        targetCompatibility versions.javaVersion +    } +      lintOptions {          abortOnError false          disable 'MissingTranslation', 'UnusedResources' @@ -50,15 +55,6 @@ android {          def buildType = variant.buildType.name.capitalize() -        def taskPrefix = "" -        if (project.path != ":") { -            taskPrefix = project.path + ":" -        } - -        // Disable the externalNativeBuild* task as it would cause build failures since the cmake build -        // files is only setup for editing support. -        gradle.startParameter.excludedTaskNames += taskPrefix + "externalNativeBuild" + buildType -          def releaseTarget = buildType.toLowerCase()          if (releaseTarget == null || releaseTarget == "") {              throw new GradleException("Invalid build type: " + buildType) @@ -68,20 +64,46 @@ android {              throw new GradleException("Invalid default abi: " + defaultAbi)          } +        // Find scons' executable path +        File sconsExecutableFile = null +        def sconsName = "scons" +        def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows() +            ? [".bat", ".exe"] +            : [""]) +        logger.lifecycle("Looking for $sconsName executable path") +        for (ext in sconsExts) { +            String sconsNameExt = sconsName + ext +            logger.lifecycle("Checking $sconsNameExt") + +            sconsExecutableFile = org.gradle.internal.os.OperatingSystem.current().findInPath(sconsNameExt) +            if (sconsExecutableFile != null) { +                // We're done! +                break +            } + +            // Check all the options in path +            List<File> allOptions = org.gradle.internal.os.OperatingSystem.current().findAllInPath(sconsNameExt) +            if (!allOptions.isEmpty()) { +                // Pick the first option and we're done! +                sconsExecutableFile = allOptions.get(0) +                break +            } +        } + +        if (sconsExecutableFile == null) { +            throw new GradleException("Unable to find executable path for the '$sconsName' command.") +        } else { +            logger.lifecycle("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}") +        } +          // Creating gradle task to generate the native libraries for the default abi.          def taskName = getSconsTaskName(buildType)          tasks.create(name: taskName, type: Exec) { -            executable "scons" + sconsExt +            executable sconsExecutableFile.absolutePath              args "--directory=${pathToRootDir}", "platform=android", "target=${releaseTarget}", "android_arch=${defaultAbi}", "-j" + Runtime.runtime.availableProcessors()          }          // Schedule the tasks so the generated libs are present before the aar file is packaged.          tasks["merge${buildType}JniLibFolders"].dependsOn taskName      } - -    externalNativeBuild { -        cmake { -            path "CMakeLists.txt" -        } -    }  } diff --git a/platform/android/java/lib/res/values/dimens.xml b/platform/android/java/lib/res/values/dimens.xml new file mode 100644 index 0000000000..9034dbbcc1 --- /dev/null +++ b/platform/android/java/lib/res/values/dimens.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> +	<dimen name="text_edit_height">48dp</dimen> +</resources> 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; +	}  }  |