Browse Source

Merge pull request #40398 from thebestnom/android_keyboard_modifiers_and_arrows

Android: Keyboard modifier and arrow key support for text edit
Rémi Verschelde 5 years ago
parent
commit
25d59a5a1a

+ 4 - 0
platform/android/android_keys_utils.h

@@ -148,6 +148,8 @@ enum {
 	AKEYCODE_BUTTON_START = 108,
 	AKEYCODE_BUTTON_START = 108,
 	AKEYCODE_BUTTON_SELECT = 109,
 	AKEYCODE_BUTTON_SELECT = 109,
 	AKEYCODE_BUTTON_MODE = 110,
 	AKEYCODE_BUTTON_MODE = 110,
+	AKEYCODE_CONTROL_LEFT = 113,
+	AKEYCODE_CONTROL_RIGHT = 114,
 
 
 	// NOTE: If you add a new keycode here you must also add it to several other files.
 	// 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.
 	//       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
@@ -246,6 +248,8 @@ static _WinTranslatePair _ak_to_keycode[] = {
 	{ KEY_BACKSLASH, AKEYCODE_BACKSLASH },
 	{ KEY_BACKSLASH, AKEYCODE_BACKSLASH },
 	{ KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
 	{ KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET },
 	{ KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
 	{ KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET },
+	{ KEY_CONTROL, AKEYCODE_CONTROL_LEFT },
+	{ KEY_CONTROL, AKEYCODE_CONTROL_RIGHT },
 	{ KEY_UNKNOWN, 0 }
 	{ KEY_UNKNOWN, 0 }
 };
 };
 /*
 /*

+ 26 - 0
platform/android/display_server_android.cpp

@@ -486,17 +486,40 @@ void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p
 	}
 	}
 }
 }
 
 
+void DisplayServerAndroid::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) {
+	ev->set_shift(shift_mem);
+	ev->set_alt(alt_mem);
+	ev->set_metakey(meta_mem);
+	ev->set_control(control_mem);
+}
+
 void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
 void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
 	Ref<InputEventKey> ev;
 	Ref<InputEventKey> ev;
 	ev.instance();
 	ev.instance();
 	int val = p_unicode_char;
 	int val = p_unicode_char;
 	int keycode = android_get_keysym(p_keycode);
 	int keycode = android_get_keysym(p_keycode);
 	int phy_keycode = android_get_keysym(p_scancode);
 	int phy_keycode = android_get_keysym(p_scancode);
+
+	if (keycode == KEY_SHIFT) {
+		shift_mem = p_pressed;
+	}
+	if (keycode == KEY_ALT) {
+		alt_mem = p_pressed;
+	}
+	if (keycode == KEY_CONTROL) {
+		control_mem = p_pressed;
+	}
+	if (keycode == KEY_META) {
+		meta_mem = p_pressed;
+	}
+
 	ev->set_keycode(keycode);
 	ev->set_keycode(keycode);
 	ev->set_physical_keycode(phy_keycode);
 	ev->set_physical_keycode(phy_keycode);
 	ev->set_unicode(val);
 	ev->set_unicode(val);
 	ev->set_pressed(p_pressed);
 	ev->set_pressed(p_pressed);
 
 
+	_set_key_modifier_state(ev);
+
 	if (val == '\n') {
 	if (val == '\n') {
 		ev->set_keycode(KEY_ENTER);
 		ev->set_keycode(KEY_ENTER);
 	} else if (val == 61448) {
 	} else if (val == 61448) {
@@ -629,6 +652,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
 		case 10: { // hover exit
 		case 10: { // hover exit
 			Ref<InputEventMouseMotion> ev;
 			Ref<InputEventMouseMotion> ev;
 			ev.instance();
 			ev.instance();
+			_set_key_modifier_state(ev);
 			ev->set_position(p_pos);
 			ev->set_position(p_pos);
 			ev->set_global_position(p_pos);
 			ev->set_global_position(p_pos);
 			ev->set_relative(p_pos - hover_prev_pos);
 			ev->set_relative(p_pos - hover_prev_pos);
@@ -641,6 +665,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
 void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
 void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
 	Ref<InputEventMouseButton> ev;
 	Ref<InputEventMouseButton> ev;
 	ev.instance();
 	ev.instance();
+	_set_key_modifier_state(ev);
 	ev->set_position(p_pos);
 	ev->set_position(p_pos);
 	ev->set_global_position(p_pos);
 	ev->set_global_position(p_pos);
 	ev->set_pressed(false);
 	ev->set_pressed(false);
@@ -651,6 +676,7 @@ void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
 void DisplayServerAndroid::process_scroll(Point2 p_pos) {
 void DisplayServerAndroid::process_scroll(Point2 p_pos) {
 	Ref<InputEventPanGesture> ev;
 	Ref<InputEventPanGesture> ev;
 	ev.instance();
 	ev.instance();
+	_set_key_modifier_state(ev);
 	ev->set_position(p_pos);
 	ev->set_position(p_pos);
 	ev->set_delta(p_pos - scroll_prev_pos);
 	ev->set_delta(p_pos - scroll_prev_pos);
 	Input::get_singleton()->parse_input_event(ev);
 	Input::get_singleton()->parse_input_event(ev);

+ 7 - 0
platform/android/display_server_android.h

@@ -63,6 +63,11 @@ public:
 private:
 private:
 	String rendering_driver;
 	String rendering_driver;
 
 
+	bool alt_mem = false;
+	bool shift_mem = false;
+	bool control_mem = false;
+	bool meta_mem = false;
+
 	bool keep_screen_on;
 	bool keep_screen_on;
 
 
 	Vector<TouchPos> touch;
 	Vector<TouchPos> touch;
@@ -84,6 +89,8 @@ private:
 
 
 	static void _dispatch_input_events(const Ref<InputEvent> &p_event);
 	static void _dispatch_input_events(const Ref<InputEvent> &p_event);
 
 
+	void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
+
 public:
 public:
 	static DisplayServerAndroid *get_singleton();
 	static DisplayServerAndroid *get_singleton();
 
 

+ 5 - 0
platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java

@@ -117,6 +117,11 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
 		godot.onBackPressed();
 		godot.onBackPressed();
 	}
 	}
 
 
+	@Override
+	public GodotInputHandler getInputHandler() {
+		return inputHandler;
+	}
+
 	@SuppressLint("ClickableViewAccessibility")
 	@SuppressLint("ClickableViewAccessibility")
 	@Override
 	@Override
 	public boolean onTouchEvent(MotionEvent event) {
 	public boolean onTouchEvent(MotionEvent event) {

+ 4 - 0
platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java

@@ -30,6 +30,8 @@
 
 
 package org.godotengine.godot;
 package org.godotengine.godot;
 
 
+import org.godotengine.godot.input.GodotInputHandler;
+
 import android.view.SurfaceView;
 import android.view.SurfaceView;
 
 
 public interface GodotRenderView {
 public interface GodotRenderView {
@@ -43,4 +45,6 @@ public interface GodotRenderView {
 	abstract public void onActivityResumed();
 	abstract public void onActivityResumed();
 
 
 	abstract public void onBackPressed();
 	abstract public void onBackPressed();
+
+	abstract public GodotInputHandler getInputHandler();
 }
 }

+ 5 - 0
platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java

@@ -90,6 +90,11 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
 		godot.onBackPressed();
 		godot.onBackPressed();
 	}
 	}
 
 
+	@Override
+	public GodotInputHandler getInputHandler() {
+		return mInputHandler;
+	}
+
 	@SuppressLint("ClickableViewAccessibility")
 	@SuppressLint("ClickableViewAccessibility")
 	@Override
 	@Override
 	public boolean onTouchEvent(MotionEvent event) {
 	public boolean onTouchEvent(MotionEvent event) {

+ 25 - 4
platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java

@@ -155,14 +155,35 @@ public class GodotEditText extends EditText {
 	// ===========================================================
 	// ===========================================================
 	@Override
 	@Override
 	public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
 	public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
-		super.onKeyDown(keyCode, keyEvent);
-
-		/* Let GlSurfaceView get focus if back key is input. */
+		/* Let SurfaceView get focus if back key is input. */
 		if (keyCode == KeyEvent.KEYCODE_BACK) {
 		if (keyCode == KeyEvent.KEYCODE_BACK) {
 			mRenderView.getView().requestFocus();
 			mRenderView.getView().requestFocus();
 		}
 		}
 
 
-		return true;
+		// pass event to godot in special cases
+		if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyDown(keyCode, keyEvent)) {
+			return true;
+		} else {
+			return super.onKeyDown(keyCode, keyEvent);
+		}
+	}
+
+	@Override
+	public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
+		if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyUp(keyCode, keyEvent)) {
+			return true;
+		} else {
+			return super.onKeyUp(keyCode, keyEvent);
+		}
+	}
+
+	private boolean needHandlingInGodot(int keyCode, KeyEvent keyEvent) {
+		boolean isArrowKey = keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN ||
+							 keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT;
+		boolean isModifiedKey = keyEvent.isAltPressed() || keyEvent.isCtrlPressed() || keyEvent.isSymPressed() ||
+								keyEvent.isFunctionPressed() || keyEvent.isMetaPressed();
+		return isArrowKey || keyCode == KeyEvent.KEYCODE_TAB || KeyEvent.isModifierKey(keyCode) ||
+				isModifiedKey;
 	}
 	}
 
 
 	// ===========================================================
 	// ===========================================================