Add support for unicode characters for hardware keyboard on android

This commit is contained in:
Deve 2018-08-20 23:31:31 +02:00
parent 11bb2f3b0a
commit 07fd42ee3c
3 changed files with 111 additions and 16 deletions

View File

@ -50,6 +50,7 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
Gyroscope(0),
AccelerometerActive(false),
GyroscopeActive(false),
TextInputEnabled(false),
IsMousePressed(false),
GamepadAxisX(0),
GamepadAxisY(0),
@ -701,7 +702,15 @@ s32 CIrrDeviceAndroid::handleKeyboard(AInputEvent* androidEvent)
if (event.KeyInput.Key > 0)
{
getKeyChar(event);
if (TextInputEnabled == true)
{
event.KeyInput.Char = getUnicodeChar(androidEvent);
}
if (event.KeyInput.Char == 0)
{
event.KeyInput.Char = getKeyChar(event);
}
}
// If button doesn't return key code, then at least use device-specific
@ -1110,59 +1119,118 @@ void CIrrDeviceAndroid::createKeyMap()
KeyMap[AKEYCODE_MEDIA_AUDIO_TRACK] = IRR_KEY_UNKNOWN;
}
void CIrrDeviceAndroid::getKeyChar(SEvent& event)
wchar_t CIrrDeviceAndroid::getKeyChar(SEvent& event)
{
// Handle ASCII chars
event.KeyInput.Char = 0;
wchar_t key_char = 0;
// A-Z
if (event.KeyInput.SystemKeyCode > 28 && event.KeyInput.SystemKeyCode < 55)
{
if (event.KeyInput.Shift)
{
event.KeyInput.Char = event.KeyInput.SystemKeyCode + 36;
key_char = event.KeyInput.SystemKeyCode + 36;
}
else
{
event.KeyInput.Char = event.KeyInput.SystemKeyCode + 68;
key_char = event.KeyInput.SystemKeyCode + 68;
}
}
// 0-9
else if (event.KeyInput.SystemKeyCode > 6 && event.KeyInput.SystemKeyCode < 17)
{
event.KeyInput.Char = event.KeyInput.SystemKeyCode + 41;
key_char = event.KeyInput.SystemKeyCode + 41;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_BACK)
{
event.KeyInput.Char = 8;
key_char = 8;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_DEL)
{
event.KeyInput.Char = 8;
key_char = 8;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_TAB)
{
event.KeyInput.Char = 9;
key_char = 9;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_ENTER)
{
event.KeyInput.Char = 13;
key_char = 13;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_SPACE)
{
event.KeyInput.Char = 32;
key_char = 32;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_COMMA)
{
event.KeyInput.Char = 44;
key_char = 44;
}
else if (event.KeyInput.SystemKeyCode == AKEYCODE_PERIOD)
{
event.KeyInput.Char = 46;
key_char = 46;
}
return key_char;
}
wchar_t CIrrDeviceAndroid::getUnicodeChar(AInputEvent* event)
{
bool was_detached = false;
JNIEnv* env = NULL;
jint status = Android->activity->vm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (status == JNI_EDETACHED)
{
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = "NativeThread";
args.group = NULL;
status = Android->activity->vm->AttachCurrentThread(&env, &args);
was_detached = true;
}
if (status != JNI_OK)
{
os::Printer::log("Cannot get unicode character.", ELL_DEBUG);
return 0;
}
jlong down_time = AKeyEvent_getDownTime(event);
jlong event_time = AKeyEvent_getEventTime(event);
jint action = AKeyEvent_getAction(event);
jint code = AKeyEvent_getKeyCode(event);
jint repeat = AKeyEvent_getRepeatCount(event);
jint meta_state = AKeyEvent_getMetaState(event);
jint device_id = AInputEvent_getDeviceId(event);
jint scan_code = AKeyEvent_getScanCode(event);
jint flags = AKeyEvent_getFlags(event);
jint source = AInputEvent_getSource(event);
jclass key_event = env->FindClass("android/view/KeyEvent");
jmethodID key_event_constructor = env->GetMethodID(key_event, "<init>",
"(JJIIIIIIII)V");
jobject key_event_obj = env->NewObject(key_event, key_event_constructor,
down_time, event_time, action, code,
repeat, meta_state, device_id,
scan_code, flags, source);
jmethodID get_unicode = env->GetMethodID(key_event, "getUnicodeChar", "(I)I");
wchar_t unicode_char = env->CallIntMethod(key_event_obj, get_unicode,
meta_state);
if (was_detached)
{
Android->activity->vm->DetachCurrentThread();
}
return unicode_char;
}
void CIrrDeviceAndroid::hideNavBar(ANativeActivity* activity)

View File

@ -64,6 +64,7 @@ namespace irr
virtual bool deactivateGyroscope();
virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable();
virtual void setTextInputEnabled(bool enabled) {TextInputEnabled = enabled;}
class CCursorControl : public gui::ICursorControl
{
@ -113,6 +114,7 @@ namespace irr
const ASensor* Gyroscope;
bool AccelerometerActive;
bool GyroscopeActive;
bool TextInputEnabled;
static bool IsPaused;
static bool IsFocused;
@ -141,7 +143,8 @@ namespace irr
void createDriver();
void createKeyMap();
void createVideoModeList();
void getKeyChar(SEvent& event);
wchar_t getKeyChar(SEvent& event);
wchar_t getUnicodeChar(AInputEvent* event);
static void hideNavBar(ANativeActivity* activity);
int getRotation();
DeviceOrientation getDefaultOrientation();

View File

@ -120,6 +120,14 @@ CGUIEditBox::~CGUIEditBox()
dl->setIMEEnable(false);
}
#endif
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(false);
}
#endif
#endif
}
@ -268,11 +276,19 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
irr_driver->getDevice());
dl->setIMEEnable(false);
}
#endif
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(false);
}
#endif
}
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
{
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
if (irr_driver->getDevice()->getType() == irr::EIDT_X11)
{
CIrrDeviceLinux* dl = dynamic_cast<CIrrDeviceLinux*>(
@ -280,8 +296,16 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
dl->setIMEEnable(true);
dl->setIMELocation(calculateICPos());
}
}
#endif
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(true);
}
#endif
}
break;
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
case EET_IMPUT_METHOD_EVENT: