diff --git a/Android/app/src/main/java/com/multicraft/game/GameActivity.kt b/Android/app/src/main/java/com/multicraft/game/GameActivity.kt index 27c98241d..822bee9de 100644 --- a/Android/app/src/main/java/com/multicraft/game/GameActivity.kt +++ b/Android/app/src/main/java/com/multicraft/game/GameActivity.kt @@ -259,6 +259,9 @@ class GameActivity : SDLActivity() { } } + @Suppress("unused") + fun isDialogActive() = isInputActive + @Suppress("unused") fun getDialogState() = messageReturnCode diff --git a/src/client/game.cpp b/src/client/game.cpp index 7bdbf484d..12152e38d 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -819,7 +819,7 @@ protected: } #if defined(__ANDROID__) || defined(__IOS__) - void handleAndroidChatInput(); + void handleTouchChatInput(); #endif private: @@ -1873,6 +1873,14 @@ void Game::processUserInput(f32 dtime) g_touchscreengui->hide(); #endif } + +#if defined(__ANDROID__) || defined(__IOS__) + if (porting::isInputDialogActive() && porting::getInputDialogOwner() == "chat") { + input->clear(); + g_touchscreengui->hide(); + } +#endif + #ifdef HAVE_TOUCHSCREENGUI else if (g_touchscreengui) { /* on touchscreengui step may generate own input events which ain't @@ -1889,13 +1897,11 @@ void Game::processUserInput(f32 dtime) input->step(dtime); #if defined(__ANDROID__) || defined(__IOS__) - if (!porting::hasRealKeyboard()) { - auto formspec = m_game_ui->getFormspecGUI(); - if (formspec) - formspec->getAndroidUIInput(); - else - handleAndroidChatInput(); - } + handleTouchChatInput(); + + auto formspec = m_game_ui->getFormspecGUI(); + if (formspec) + formspec->getTouchUIInput(); #endif bool doubletap_jump = m_cache_doubletap_jump; @@ -1923,9 +1929,6 @@ void Game::processKeyInput() } else if (wasKeyDown(KeyType::INVENTORY)) { openInventory(); } else if (input->cancelPressed()) { -#if defined(__ANDROID__) || defined(__IOS__) - gui_chat_console->setAndroidChatOpen(false); -#endif if (!gui_chat_console->isOpenInhibited()) { showPauseMenu(); } @@ -2137,21 +2140,21 @@ void Game::openConsole(float scale, const wchar_t *line) { assert(scale > 0.0f && scale <= 1.0f); - if (gui_chat_console->getAndroidChatOpen()) + if (gui_chat_console->isOpenInhibited()) return; #if defined(__ANDROID__) || defined(__IOS__) + if (porting::isInputDialogActive()) + return; + if (!porting::hasRealKeyboard()) { - porting::showInputDialog("", "", 2); - gui_chat_console->setAndroidChatOpen(true); + porting::showInputDialog("", "", 2, "chat"); } if (!RenderingEngine::isTablet()) return; #endif - if (gui_chat_console->isOpenInhibited()) - return; gui_chat_console->openConsole(scale); if (line) { gui_chat_console->setCloseOnEnter(true); @@ -2160,16 +2163,21 @@ void Game::openConsole(float scale, const wchar_t *line) } #if defined(__ANDROID__) || defined(__IOS__) -void Game::handleAndroidChatInput() +void Game::handleTouchChatInput() { - if (gui_chat_console->getAndroidChatOpen() && + if (porting::getInputDialogOwner() == "chat" && porting::getInputDialogState() == 0) { std::string text = porting::getInputDialogValue(); client->typeChatMessage(utf8_to_wide(text)); - gui_chat_console->setAndroidChatOpen(false); if (!text.empty() && gui_chat_console->isOpen()) { gui_chat_console->closeConsole(); } +#ifdef HAVE_TOUCHSCREENGUI + if (!gui_chat_console->isOpen() && !isMenuActive()) { + if (g_touchscreengui && g_touchscreengui->isActive()) + g_touchscreengui->show(); + } +#endif } } #endif diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index ea6be6339..4d82dd3c9 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -1589,10 +1589,9 @@ bool GUIChatConsole::preprocessEvent(SEvent event) event.TouchInput.Y >= prompt_y && event.TouchInput.Y <= m_height) { if (event.TouchInput.Event == ETIE_PRESSED_DOWN && - !m_android_chat_open) { + !porting::isInputDialogActive()) { ChatPrompt& prompt = m_chat_backend->getPrompt(); - porting::showInputDialog("", "", 2); - m_android_chat_open = true; + porting::showInputDialog("", "", 2, "chat"); } } #endif diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 1ff952b81..3a88266de 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -170,9 +170,6 @@ public: bool preprocessEvent(SEvent event); - bool getAndroidChatOpen() { return m_android_chat_open; } - void setAndroidChatOpen(bool value) { m_android_chat_open = value; } - void onLinesModified(); void onPromptModified(); @@ -253,6 +250,4 @@ private: u32 m_scrollbar_width = 0; GUIScrollBar *m_vscrollbar = nullptr; s32 m_bottom_scroll_pos = 0; - - bool m_android_chat_open = false; }; diff --git a/src/gui/guiConfirmRegistration.cpp b/src/gui/guiConfirmRegistration.cpp index 3effcfbc9..04f2eb463 100644 --- a/src/gui/guiConfirmRegistration.cpp +++ b/src/gui/guiConfirmRegistration.cpp @@ -220,7 +220,7 @@ void GUIConfirmRegistration::drawMenu() gui::IGUIElement::draw(); #if defined(__ANDROID__) || defined(__IOS__) - getAndroidUIInput(); + getTouchUIInput(); #endif } @@ -308,11 +308,14 @@ bool GUIConfirmRegistration::OnEvent(const SEvent &event) } #if defined(__ANDROID__) || defined(__IOS__) -bool GUIConfirmRegistration::getAndroidUIInput() +bool GUIConfirmRegistration::getTouchUIInput() { if (m_jni_field_name.empty() || m_jni_field_name != "password") return false; + if (porting::getInputDialogOwner() != "modalmenu") + return false; + // still waiting if (porting::getInputDialogState() == -1) return true; diff --git a/src/gui/guiConfirmRegistration.h b/src/gui/guiConfirmRegistration.h index 31df018a3..cf8659a03 100644 --- a/src/gui/guiConfirmRegistration.h +++ b/src/gui/guiConfirmRegistration.h @@ -52,7 +52,7 @@ public: bool OnEvent(const SEvent &event); #if defined(__ANDROID__) || defined(__IOS__) - bool getAndroidUIInput(); + bool getTouchUIInput(); #endif private: diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index bd7349174..7850f71ce 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -348,7 +348,7 @@ void GUIEngine::run() m_script->step(); #if defined(__ANDROID__) || defined(__IOS__) - m_menu->getAndroidUIInput(); + m_menu->getTouchUIInput(); #endif } } diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 5b690a5ed..b3a687adc 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -3602,11 +3602,14 @@ void GUIFormSpecMenu::legacySortElements(core::list::Iterator fro } #if defined(__ANDROID__) || defined(__IOS__) -bool GUIFormSpecMenu::getAndroidUIInput() +bool GUIFormSpecMenu::getTouchUIInput() { if (m_jni_field_name.empty()) return false; + if (porting::getInputDialogOwner() != "modalmenu") + return false; + // still waiting if (porting::getInputDialogState() == -1) return true; diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index 82a61b609..374349203 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -266,7 +266,7 @@ public: std::vector* getDropDownValues(const std::string &name); #if defined(__ANDROID__) || defined(__IOS__) - bool getAndroidUIInput(); + bool getTouchUIInput(); #endif protected: diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp index 3272dfc46..23e424e17 100644 --- a/src/gui/modalMenu.cpp +++ b/src/gui/modalMenu.cpp @@ -346,6 +346,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event) if (field_name.empty() || porting::hasRealKeyboard()) return retval; + if (porting::isInputDialogActive()) + return retval; + m_jni_field_name = field_name; // single line text input @@ -360,7 +363,8 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event) type = 3; porting::showInputDialog(wide_to_utf8(getLabelByID(hovered->getID())), - wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type); + wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type, + "modalmenu"); return retval; } } diff --git a/src/gui/modalMenu.h b/src/gui/modalMenu.h index 7fd5c7b45..a2bfaf90b 100644 --- a/src/gui/modalMenu.h +++ b/src/gui/modalMenu.h @@ -58,7 +58,7 @@ public: virtual bool OnEvent(const SEvent &event) { return false; }; virtual bool pausesGame() { return false; } // Used for pause menu #if defined(__ANDROID__) || defined(__IOS__) - virtual bool getAndroidUIInput() { return false; } + virtual bool getTouchUIInput() { return false; } #endif protected: diff --git a/src/porting_android.cpp b/src/porting_android.cpp index 4d30bd93f..9e9c5b408 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -95,6 +95,7 @@ namespace porting { JNIEnv *jnienv; jclass activityClass; jobject activityObj; +std::string input_dialog_owner; jclass findClass(const std::string &classname) { @@ -209,8 +210,10 @@ void initializePaths() activityObj, mt_getAbsPath, "getCacheDir"); } -void showInputDialog(const std::string &hint, const std::string ¤t, int editType) +void showInputDialog(const std::string &hint, const std::string ¤t, int editType, std::string owner) { + input_dialog_owner = owner; + jmethodID showdialog = jnienv->GetMethodID(activityClass, "showDialog", "(Ljava/lang/String;Ljava/lang/String;I)V"); @@ -236,6 +239,22 @@ void openURIAndroid(const std::string &url) jnienv->CallVoidMethod(activityObj, url_open, jurl); } +std::string getInputDialogOwner() +{ + return input_dialog_owner; +} + +bool isInputDialogActive() +{ + jmethodID dialog_active = jnienv->GetMethodID(activityClass, + "isDialogActive", "()Z"); + + FATAL_ERROR_IF(dialog_active == nullptr, + "porting::isInputDialogActive unable to find Java dialog state method"); + + return jnienv->CallBooleanMethod(activityObj, dialog_active); +} + int getInputDialogState() { jmethodID dialogstate = jnienv->GetMethodID(activityClass, @@ -249,6 +268,8 @@ int getInputDialogState() std::string getInputDialogValue() { + input_dialog_owner = ""; + jmethodID dialogvalue = jnienv->GetMethodID(activityClass, "getDialogValue", "()Ljava/lang/String;"); diff --git a/src/porting_android.h b/src/porting_android.h index cf7438722..e970e6f97 100644 --- a/src/porting_android.h +++ b/src/porting_android.h @@ -34,6 +34,8 @@ namespace porting { // java <-> c++ interaction interface extern JNIEnv *jnienv; +extern std::string input_dialog_owner; + // do initialization required on android only void initAndroid(); @@ -51,7 +53,11 @@ void initializePaths(); * @param editType type of texfield * (1 == multiline text input; 2 == single line text input; 3 == password field) */ -void showInputDialog(const std::string &hint, const std::string ¤t, int editType); +void showInputDialog(const std::string &hint, const std::string ¤t, int editType, std::string owner = ""); + +std::string getInputDialogOwner(); + +bool isInputDialogActive(); void openURIAndroid(const std::string &url);