From 166103c759cbac8bafd0d389bca1ecbce348b4c9 Mon Sep 17 00:00:00 2001 From: thebestnom Date: Wed, 15 Jul 2020 02:47:24 +0300 Subject: [PATCH] Android: Keyboard modifier and arrow key support --- platform/android/android_keys_utils.h | 4 +++ platform/android/display_server_android.cpp | 26 +++++++++++++++++ platform/android/display_server_android.h | 7 +++++ .../godotengine/godot/GodotGLRenderView.java | 5 ++++ .../godotengine/godot/GodotRenderView.java | 4 +++ .../godot/GodotVulkanRenderView.java | 5 ++++ .../godot/input/GodotEditText.java | 29 ++++++++++++++++--- 7 files changed, 76 insertions(+), 4 deletions(-) diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h index fb442f4c5433..857bef02d139 100644 --- a/platform/android/android_keys_utils.h +++ b/platform/android/android_keys_utils.h @@ -148,6 +148,8 @@ enum { AKEYCODE_BUTTON_START = 108, AKEYCODE_BUTTON_SELECT = 109, 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. // 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_BRACKETLEFT, AKEYCODE_LEFT_BRACKET }, { KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET }, + { KEY_CONTROL, AKEYCODE_CONTROL_LEFT }, + { KEY_CONTROL, AKEYCODE_CONTROL_RIGHT }, { KEY_UNKNOWN, 0 } }; /* diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 3bc9e6d87693..7193519a524d 100644 --- a/platform/android/display_server_android.cpp +++ b/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 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) { Ref ev; ev.instance(); int val = p_unicode_char; int keycode = android_get_keysym(p_keycode); 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_physical_keycode(phy_keycode); ev->set_unicode(val); ev->set_pressed(p_pressed); + _set_key_modifier_state(ev); + if (val == '\n') { ev->set_keycode(KEY_ENTER); } else if (val == 61448) { @@ -629,6 +652,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) { case 10: { // hover exit Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(p_pos); ev->set_global_position(p_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) { Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(p_pos); ev->set_global_position(p_pos); ev->set_pressed(false); @@ -651,6 +676,7 @@ void DisplayServerAndroid::process_double_tap(Point2 p_pos) { void DisplayServerAndroid::process_scroll(Point2 p_pos) { Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(p_pos); ev->set_delta(p_pos - scroll_prev_pos); Input::get_singleton()->parse_input_event(ev); diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index d64542df58ab..4cae52fa763b 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -63,6 +63,11 @@ class DisplayServerAndroid : public DisplayServer { private: String rendering_driver; + bool alt_mem = false; + bool shift_mem = false; + bool control_mem = false; + bool meta_mem = false; + bool keep_screen_on; Vector touch; @@ -84,6 +89,8 @@ class DisplayServerAndroid : public DisplayServer { static void _dispatch_input_events(const Ref &p_event); + void _set_key_modifier_state(Ref ev); + public: static DisplayServerAndroid *get_singleton(); 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 4da2f3125031..d169f465992b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -117,6 +117,11 @@ public void onBackPressed() { godot.onBackPressed(); } + @Override + public GodotInputHandler getInputHandler() { + return inputHandler; + } + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java index 27e63f3a6642..68b8a16641fa 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java @@ -30,6 +30,8 @@ package org.godotengine.godot; +import org.godotengine.godot.input.GodotInputHandler; + import android.view.SurfaceView; public interface GodotRenderView { @@ -43,4 +45,6 @@ public interface GodotRenderView { abstract public void onActivityResumed(); abstract public void onBackPressed(); + + abstract public GodotInputHandler getInputHandler(); } 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 aace593bae0c..65708389c325 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -90,6 +90,11 @@ public void onBackPressed() { godot.onBackPressed(); } + @Override + public GodotInputHandler getInputHandler() { + return mInputHandler; + } + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { 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 7f596575a846..c0defd008e91 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 @@ -155,14 +155,35 @@ public void setView(final GodotRenderView view) { // =========================================================== @Override 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) { 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; } // ===========================================================