Restore function for hardware keyboard on android

This commit is contained in:
Deve 2019-12-27 23:43:40 +01:00
parent cecf5cffac
commit 8df28b07b1
3 changed files with 89 additions and 0 deletions
lib/irrlicht/source/Irrlicht
src/guiengine/widgets

@ -69,6 +69,7 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
Gyroscope(0),
AccelerometerActive(false),
GyroscopeActive(false),
TextInputEnabled(false),
HasTouchDevice(false),
GamepadAxisX(0),
GamepadAxisY(0),
@ -682,6 +683,11 @@ s32 CIrrDeviceAndroid::handleKeyboard(AInputEvent* androidEvent)
if (event.KeyInput.Key > 0)
{
if (TextInputEnabled == true)
{
event.KeyInput.Char = getUnicodeChar(androidEvent);
}
if (event.KeyInput.Char == 0)
{
event.KeyInput.Char = getKeyChar(event);
@ -1151,6 +1157,63 @@ wchar_t CIrrDeviceAndroid::getKeyChar(SEvent& event)
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::openURL(const std::string& url)
{
if (!Android)

@ -72,6 +72,7 @@ namespace irr
virtual bool deactivateGyroscope();
virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable();
virtual void setTextInputEnabled(bool enabled) {TextInputEnabled = enabled;}
void fromSTKEditBox(int widget_id, const core::stringw& text, int selection_start, int selection_end, int type);
virtual void toggleOnScreenKeyboard(bool show, s32 type = 0);
virtual bool supportsTouchDevice() const { return HasTouchDevice; }
@ -101,6 +102,7 @@ namespace irr
const ASensor* Gyroscope;
bool AccelerometerActive;
bool GyroscopeActive;
bool TextInputEnabled;
static AndroidApplicationInfo ApplicationInfo;
static bool IsPaused;
@ -131,6 +133,7 @@ namespace irr
void createKeyMap();
void createVideoModeList();
wchar_t getKeyChar(SEvent& event);
wchar_t getUnicodeChar(AInputEvent* event);
static void readApplicationInfo(ANativeActivity* activity);
int getRotation();
DeviceOrientation getDefaultOrientation();

@ -244,6 +244,14 @@ CGUIEditBox::~CGUIEditBox()
}
#elif defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
DestroyCaret();
#endif
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(false);
}
#endif
if (GUIEngine::ScreenKeyboard::shouldUseScreenKeyboard() &&
GUIEngine::ScreenKeyboard::hasSystemScreenKeyboard())
@ -361,6 +369,14 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
}
#elif defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
DestroyCaret();
#endif
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(false);
}
#endif
m_from_android_edittext = false;
m_composing_start = 0;
@ -380,6 +396,13 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
#endif
calculateScrollPos();
#ifdef ANDROID
if (irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)
{
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
dl->setTextInputEnabled(true);
}
if (GUIEngine::ScreenKeyboard::shouldUseScreenKeyboard() &&
GUIEngine::ScreenKeyboard::hasSystemScreenKeyboard() &&
irr_driver->getDevice()->getType() == irr::EIDT_ANDROID)