Browse Source

[3.2] Android: Keyboard modifier and arrow key support

thebestnom 4 years ago
parent
commit
8405f1225e

+ 4 - 0
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();

+ 22 - 5
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 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);
+		}
+	}
 
-		/* Let GlSurfaceView get focus if back key is input. */
-		if (keyCode == KeyEvent.KEYCODE_BACK) {
-			this.mView.requestFocus();
+	@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);
 		}
+	}
 
-		return true;
+	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;
 	}
 
 	// ===========================================================

+ 1 - 22
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<InputEventKey> 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) {

+ 58 - 0
platform/android/os_android.cpp

@@ -46,8 +46,10 @@
 #include "net_socket_android.h"
 
 #include <android/input.h>
+#include <core/os/keyboard.h>
 #include <dlfcn.h>
 
+#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<InputEventWithModifiers> 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<InputEvent> 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<InputEventKey> 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<TouchPos> &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<InputEventMouseMotion> 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<InputEventMouseButton> 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<InputEventMouseMotion> 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<InputEventMouseButton> 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<InputEventMouseButton> 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<InputEventPanGesture> 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);

+ 8 - 0
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<InputEventWithModifiers> 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<InputEvent> p_event);
 	void init_video_mode(int p_video_width, int p_video_height);