1
0

Mobile: improve the chat experience (#146)

* Some chat input dialog fixes.

- If getAndroidChatOpen() is true then input dialog is created by chat.
- Hide touchscreengui when chat input dialog is open.

* Check input dialog owner in config registration, just in case

* Make sure there is no menu active before showing touchscreengui

* Reset input dialog owner when reading value
This commit is contained in:
Deve 2023-09-17 18:18:40 +02:00 committed by GitHub
parent 2c244aa28c
commit 52228db808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 79 additions and 37 deletions

View File

@ -259,6 +259,9 @@ class GameActivity : SDLActivity() {
} }
} }
@Suppress("unused")
fun isDialogActive() = isInputActive
@Suppress("unused") @Suppress("unused")
fun getDialogState() = messageReturnCode fun getDialogState() = messageReturnCode

View File

@ -819,7 +819,7 @@ protected:
} }
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
void handleAndroidChatInput(); void handleTouchChatInput();
#endif #endif
private: private:
@ -1873,6 +1873,14 @@ void Game::processUserInput(f32 dtime)
g_touchscreengui->hide(); g_touchscreengui->hide();
#endif #endif
} }
#if defined(__ANDROID__) || defined(__IOS__)
if (porting::isInputDialogActive() && porting::getInputDialogOwner() == "chat") {
input->clear();
g_touchscreengui->hide();
}
#endif
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
else if (g_touchscreengui) { else if (g_touchscreengui) {
/* on touchscreengui step may generate own input events which ain't /* on touchscreengui step may generate own input events which ain't
@ -1889,13 +1897,11 @@ void Game::processUserInput(f32 dtime)
input->step(dtime); input->step(dtime);
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
if (!porting::hasRealKeyboard()) { handleTouchChatInput();
auto formspec = m_game_ui->getFormspecGUI(); auto formspec = m_game_ui->getFormspecGUI();
if (formspec) if (formspec)
formspec->getAndroidUIInput(); formspec->getTouchUIInput();
else
handleAndroidChatInput();
}
#endif #endif
bool doubletap_jump = m_cache_doubletap_jump; bool doubletap_jump = m_cache_doubletap_jump;
@ -1923,9 +1929,6 @@ void Game::processKeyInput()
} else if (wasKeyDown(KeyType::INVENTORY)) { } else if (wasKeyDown(KeyType::INVENTORY)) {
openInventory(); openInventory();
} else if (input->cancelPressed()) { } else if (input->cancelPressed()) {
#if defined(__ANDROID__) || defined(__IOS__)
gui_chat_console->setAndroidChatOpen(false);
#endif
if (!gui_chat_console->isOpenInhibited()) { if (!gui_chat_console->isOpenInhibited()) {
showPauseMenu(); showPauseMenu();
} }
@ -2137,21 +2140,21 @@ void Game::openConsole(float scale, const wchar_t *line)
{ {
assert(scale > 0.0f && scale <= 1.0f); assert(scale > 0.0f && scale <= 1.0f);
if (gui_chat_console->getAndroidChatOpen()) if (gui_chat_console->isOpenInhibited())
return; return;
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
if (porting::isInputDialogActive())
return;
if (!porting::hasRealKeyboard()) { if (!porting::hasRealKeyboard()) {
porting::showInputDialog("", "", 2); porting::showInputDialog("", "", 2, "chat");
gui_chat_console->setAndroidChatOpen(true);
} }
if (!RenderingEngine::isTablet()) if (!RenderingEngine::isTablet())
return; return;
#endif #endif
if (gui_chat_console->isOpenInhibited())
return;
gui_chat_console->openConsole(scale); gui_chat_console->openConsole(scale);
if (line) { if (line) {
gui_chat_console->setCloseOnEnter(true); gui_chat_console->setCloseOnEnter(true);
@ -2160,16 +2163,21 @@ void Game::openConsole(float scale, const wchar_t *line)
} }
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
void Game::handleAndroidChatInput() void Game::handleTouchChatInput()
{ {
if (gui_chat_console->getAndroidChatOpen() && if (porting::getInputDialogOwner() == "chat" &&
porting::getInputDialogState() == 0) { porting::getInputDialogState() == 0) {
std::string text = porting::getInputDialogValue(); std::string text = porting::getInputDialogValue();
client->typeChatMessage(utf8_to_wide(text)); client->typeChatMessage(utf8_to_wide(text));
gui_chat_console->setAndroidChatOpen(false);
if (!text.empty() && gui_chat_console->isOpen()) { if (!text.empty() && gui_chat_console->isOpen()) {
gui_chat_console->closeConsole(); gui_chat_console->closeConsole();
} }
#ifdef HAVE_TOUCHSCREENGUI
if (!gui_chat_console->isOpen() && !isMenuActive()) {
if (g_touchscreengui && g_touchscreengui->isActive())
g_touchscreengui->show();
}
#endif
} }
} }
#endif #endif

View File

@ -1589,10 +1589,9 @@ bool GUIChatConsole::preprocessEvent(SEvent event)
event.TouchInput.Y >= prompt_y && event.TouchInput.Y >= prompt_y &&
event.TouchInput.Y <= m_height) { event.TouchInput.Y <= m_height) {
if (event.TouchInput.Event == ETIE_PRESSED_DOWN && if (event.TouchInput.Event == ETIE_PRESSED_DOWN &&
!m_android_chat_open) { !porting::isInputDialogActive()) {
ChatPrompt& prompt = m_chat_backend->getPrompt(); ChatPrompt& prompt = m_chat_backend->getPrompt();
porting::showInputDialog("", "", 2); porting::showInputDialog("", "", 2, "chat");
m_android_chat_open = true;
} }
} }
#endif #endif

View File

@ -170,9 +170,6 @@ public:
bool preprocessEvent(SEvent event); bool preprocessEvent(SEvent event);
bool getAndroidChatOpen() { return m_android_chat_open; }
void setAndroidChatOpen(bool value) { m_android_chat_open = value; }
void onLinesModified(); void onLinesModified();
void onPromptModified(); void onPromptModified();
@ -253,6 +250,4 @@ private:
u32 m_scrollbar_width = 0; u32 m_scrollbar_width = 0;
GUIScrollBar *m_vscrollbar = nullptr; GUIScrollBar *m_vscrollbar = nullptr;
s32 m_bottom_scroll_pos = 0; s32 m_bottom_scroll_pos = 0;
bool m_android_chat_open = false;
}; };

View File

@ -220,7 +220,7 @@ void GUIConfirmRegistration::drawMenu()
gui::IGUIElement::draw(); gui::IGUIElement::draw();
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
getAndroidUIInput(); getTouchUIInput();
#endif #endif
} }
@ -308,11 +308,14 @@ bool GUIConfirmRegistration::OnEvent(const SEvent &event)
} }
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
bool GUIConfirmRegistration::getAndroidUIInput() bool GUIConfirmRegistration::getTouchUIInput()
{ {
if (m_jni_field_name.empty() || m_jni_field_name != "password") if (m_jni_field_name.empty() || m_jni_field_name != "password")
return false; return false;
if (porting::getInputDialogOwner() != "modalmenu")
return false;
// still waiting // still waiting
if (porting::getInputDialogState() == -1) if (porting::getInputDialogState() == -1)
return true; return true;

View File

@ -52,7 +52,7 @@ public:
bool OnEvent(const SEvent &event); bool OnEvent(const SEvent &event);
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
bool getAndroidUIInput(); bool getTouchUIInput();
#endif #endif
private: private:

View File

@ -348,7 +348,7 @@ void GUIEngine::run()
m_script->step(); m_script->step();
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
m_menu->getAndroidUIInput(); m_menu->getTouchUIInput();
#endif #endif
} }
} }

View File

@ -3602,11 +3602,14 @@ void GUIFormSpecMenu::legacySortElements(core::list<IGUIElement *>::Iterator fro
} }
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
bool GUIFormSpecMenu::getAndroidUIInput() bool GUIFormSpecMenu::getTouchUIInput()
{ {
if (m_jni_field_name.empty()) if (m_jni_field_name.empty())
return false; return false;
if (porting::getInputDialogOwner() != "modalmenu")
return false;
// still waiting // still waiting
if (porting::getInputDialogState() == -1) if (porting::getInputDialogState() == -1)
return true; return true;

View File

@ -266,7 +266,7 @@ public:
std::vector<std::string>* getDropDownValues(const std::string &name); std::vector<std::string>* getDropDownValues(const std::string &name);
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
bool getAndroidUIInput(); bool getTouchUIInput();
#endif #endif
protected: protected:

View File

@ -346,6 +346,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
if (field_name.empty() || porting::hasRealKeyboard()) if (field_name.empty() || porting::hasRealKeyboard())
return retval; return retval;
if (porting::isInputDialogActive())
return retval;
m_jni_field_name = field_name; m_jni_field_name = field_name;
// single line text input // single line text input
@ -360,7 +363,8 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
type = 3; type = 3;
porting::showInputDialog(wide_to_utf8(getLabelByID(hovered->getID())), 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; return retval;
} }
} }

View File

@ -58,7 +58,7 @@ public:
virtual bool OnEvent(const SEvent &event) { return false; }; virtual bool OnEvent(const SEvent &event) { return false; };
virtual bool pausesGame() { return false; } // Used for pause menu virtual bool pausesGame() { return false; } // Used for pause menu
#if defined(__ANDROID__) || defined(__IOS__) #if defined(__ANDROID__) || defined(__IOS__)
virtual bool getAndroidUIInput() { return false; } virtual bool getTouchUIInput() { return false; }
#endif #endif
protected: protected:

View File

@ -95,6 +95,7 @@ namespace porting {
JNIEnv *jnienv; JNIEnv *jnienv;
jclass activityClass; jclass activityClass;
jobject activityObj; jobject activityObj;
std::string input_dialog_owner;
jclass findClass(const std::string &classname) jclass findClass(const std::string &classname)
{ {
@ -209,8 +210,10 @@ void initializePaths()
activityObj, mt_getAbsPath, "getCacheDir"); activityObj, mt_getAbsPath, "getCacheDir");
} }
void showInputDialog(const std::string &hint, const std::string &current, int editType) void showInputDialog(const std::string &hint, const std::string &current, int editType, std::string owner)
{ {
input_dialog_owner = owner;
jmethodID showdialog = jnienv->GetMethodID(activityClass, "showDialog", jmethodID showdialog = jnienv->GetMethodID(activityClass, "showDialog",
"(Ljava/lang/String;Ljava/lang/String;I)V"); "(Ljava/lang/String;Ljava/lang/String;I)V");
@ -236,6 +239,22 @@ void openURIAndroid(const std::string &url)
jnienv->CallVoidMethod(activityObj, url_open, jurl); 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() int getInputDialogState()
{ {
jmethodID dialogstate = jnienv->GetMethodID(activityClass, jmethodID dialogstate = jnienv->GetMethodID(activityClass,
@ -249,6 +268,8 @@ int getInputDialogState()
std::string getInputDialogValue() std::string getInputDialogValue()
{ {
input_dialog_owner = "";
jmethodID dialogvalue = jnienv->GetMethodID(activityClass, jmethodID dialogvalue = jnienv->GetMethodID(activityClass,
"getDialogValue", "()Ljava/lang/String;"); "getDialogValue", "()Ljava/lang/String;");

View File

@ -34,6 +34,8 @@ namespace porting {
// java <-> c++ interaction interface // java <-> c++ interaction interface
extern JNIEnv *jnienv; extern JNIEnv *jnienv;
extern std::string input_dialog_owner;
// do initialization required on android only // do initialization required on android only
void initAndroid(); void initAndroid();
@ -51,7 +53,11 @@ void initializePaths();
* @param editType type of texfield * @param editType type of texfield
* (1 == multiline text input; 2 == single line text input; 3 == password field) * (1 == multiline text input; 2 == single line text input; 3 == password field)
*/ */
void showInputDialog(const std::string &hint, const std::string &current, int editType); void showInputDialog(const std::string &hint, const std::string &current, int editType, std::string owner = "");
std::string getInputDialogOwner();
bool isInputDialogActive();
void openURIAndroid(const std::string &url); void openURIAndroid(const std::string &url);