From 8405f1225e449c58b1f4ceb355b52238eee738a8 Mon Sep 17 00:00:00 2001 From: thebestnom Date: Sun, 1 Nov 2020 01:09:09 +0200 Subject: [PATCH] [3.2] Android: Keyboard modifier and arrow key support --- .../src/org/godotengine/godot/GodotView.java | 4 ++ .../godot/input/GodotEditText.java | 29 ++++++++-- platform/android/java_godot_lib_jni.cpp | 23 +------- platform/android/os_android.cpp | 58 +++++++++++++++++++ platform/android/os_android.h | 8 +++ 5 files changed, 94 insertions(+), 28 deletions(-) diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java index da6058e96c6..585b61169ee 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java @@ -179,6 +179,10 @@ public class GodotView extends GLSurfaceView { godot.onBackPressed(); } + public GodotInputHandler getInputHandler() { + return inputHandler; + } + @Override public void onResume() { super.onResume(); 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 b76a494a586..0a3f10e4548 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 @@ -167,14 +167,31 @@ public class GodotEditText extends EditText { // =========================================================== @Override public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { - super.onKeyDown(keyCode, keyEvent); - - /* Let GlSurfaceView get focus if back key is input. */ - if (keyCode == KeyEvent.KEYCODE_BACK) { - this.mView.requestFocus(); + /* Let SurfaceView get focus if back key is input. */ + // pass event to godot in special cases + if (needHandlingInGodot(keyCode, keyEvent) && mView.getInputHandler().onKeyDown(keyCode, keyEvent)) { + return true; + } else { + return super.onKeyDown(keyCode, keyEvent); } + } - return true; + @Override + public boolean onKeyUp(int keyCode, KeyEvent keyEvent) { + if (needHandlingInGodot(keyCode, keyEvent) && mView.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; } // =========================================================== diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 960da5edf1a..738324bd916 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -390,28 +390,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jcla if (step == 0) return; - Ref ievent; - ievent.instance(); - int val = p_unicode_char; - int scancode = android_get_keysym(p_scancode); - ievent->set_scancode(scancode); - ievent->set_unicode(val); - ievent->set_pressed(p_pressed); - - if (val == '\n') { - ievent->set_scancode(KEY_ENTER); - } else if (val == 61448) { - ievent->set_scancode(KEY_BACKSPACE); - ievent->set_unicode(KEY_BACKSPACE); - } else if (val == 61453) { - ievent->set_scancode(KEY_ENTER); - ievent->set_unicode(KEY_ENTER); - } else if (p_scancode == 4) { - - os_android->main_loop_request_go_back(); - } - - os_android->process_event(ievent); + os_android->process_key_event(p_scancode, p_unicode_char, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index b1de7abe490..ba6c44464c5 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -46,8 +46,10 @@ #include "net_socket_android.h" #include +#include #include +#include "android_keys_utils.h" #include "java_godot_io_wrapper.h" #include "java_godot_wrapper.h" @@ -364,11 +366,61 @@ void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) { } } +void OS_Android::_set_key_modifier_state(Ref ev) const { + ev->set_shift(shift_mem); + ev->set_alt(alt_mem); + ev->set_metakey(meta_mem); + ev->set_control(control_mem); +} + void OS_Android::process_event(Ref p_event) { input->parse_input_event(p_event); } +void OS_Android::process_key_event(int p_scancode, int p_unicode_char, bool p_pressed) { + + Ref ev; + ev.instance(); + int val = p_unicode_char; + unsigned int scancode = android_get_keysym(p_scancode); + + switch (scancode) { + case KEY_SHIFT: { + shift_mem = p_pressed; + } break; + case KEY_ALT: { + alt_mem = p_pressed; + } break; + case KEY_CONTROL: { + control_mem = p_pressed; + } break; + case KEY_META: { + meta_mem = p_pressed; + } break; + } + + ev->set_scancode(scancode); + ev->set_unicode(val); + ev->set_pressed(p_pressed); + + _set_key_modifier_state(ev); + + if (val == '\n') { + ev->set_scancode(KEY_ENTER); + } else if (val == 61448) { + ev->set_scancode(KEY_BACKSPACE); + ev->set_unicode(KEY_BACKSPACE); + } else if (val == 61453) { + ev->set_scancode(KEY_ENTER); + ev->set_unicode(KEY_ENTER); + } else if (p_scancode == 4) { + main_loop_request_go_back(); + } + + input->parse_input_event(ev); +} + void OS_Android::process_touch(int p_event, int p_pointer, const Vector &p_points) { switch (p_event) { @@ -488,6 +540,7 @@ void OS_Android::process_hover(int p_type, Point2 p_pos) { case AMOTION_EVENT_ACTION_HOVER_EXIT: { // 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); @@ -504,6 +557,7 @@ void OS_Android::process_mouse_event(int event_action, int event_android_buttons case AMOTION_EVENT_ACTION_BUTTON_RELEASE: { Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(event_pos); ev->set_global_position(event_pos); ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS); @@ -519,6 +573,7 @@ void OS_Android::process_mouse_event(int event_action, int event_android_buttons case AMOTION_EVENT_ACTION_MOVE: { Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(event_pos); ev->set_global_position(event_pos); ev->set_relative(event_pos - hover_prev_pos); @@ -529,6 +584,7 @@ void OS_Android::process_mouse_event(int event_action, int event_android_buttons case AMOTION_EVENT_ACTION_SCROLL: { Ref ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(event_pos); ev->set_global_position(event_pos); ev->set_pressed(true); @@ -564,6 +620,7 @@ 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 ev; ev.instance(); + _set_key_modifier_state(ev); ev->set_position(p_pos); ev->set_global_position(p_pos); ev->set_pressed(event_button_mask != 0); @@ -576,6 +633,7 @@ void OS_Android::process_double_tap(int event_android_button_mask, Point2 p_pos) void OS_Android::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->parse_input_event(ev); diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 27869a237a4..d70021bc512 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -97,8 +97,15 @@ private: int video_driver_index; + bool alt_mem = false; + bool shift_mem = false; + bool control_mem = false; + bool meta_mem = false; + int buttons_state; + void _set_key_modifier_state(Ref ev) const; + static int _button_index_from_mask(int button_mask); static int _android_button_mask_to_godot_button_mask(int android_button_mask); @@ -201,6 +208,7 @@ public: 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_key_event(int p_scancode, int p_unicode_char, bool p_pressed); void process_event(Ref p_event); void init_video_mode(int p_video_width, int p_video_height);