Android: improve real keyboard support

This commit is contained in:
MoNTE48 2020-06-18 15:11:35 +02:00
parent 5534ed1d5e
commit bd13027ac3
8 changed files with 62 additions and 15 deletions

View File

@ -23,6 +23,7 @@ package com.multicraft.game;
import android.app.ActivityManager;
import android.app.NativeActivity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
@ -42,6 +43,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static android.content.res.Configuration.KEYBOARD_QWERTY;
import static com.multicraft.game.AdManager.initAd;
import static com.multicraft.game.AdManager.setAdsCallback;
import static com.multicraft.game.AdManager.startAd;
@ -72,11 +74,14 @@ public class GameActivity extends NativeActivity {
private boolean consent, isMultiPlayer;
private PreferencesHelper pf;
private Disposable adInitSub;
private boolean hasKeyboard;
public static native void putMessageBoxResult(String text);
public static native void pauseGame();
public static native void keyboardEvent(boolean keyboard);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -85,6 +90,8 @@ public class GameActivity extends NativeActivity {
width = bundle != null ? bundle.getInt("width", 0) : getResources().getDisplayMetrics().widthPixels;
consent = bundle == null || bundle.getBoolean("consent", true);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
hasKeyboard = !(getResources().getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY);
keyboardEvent(hasKeyboard);
pf = getInstance(this);
if (pf.isAdsEnable()) {
adInitSub = Completable.fromAction(() -> initAd(this, consent))
@ -123,6 +130,16 @@ public class GameActivity extends NativeActivity {
pauseGame();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
boolean statusKeyboard = !(getResources().getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY);
if (hasKeyboard != statusKeyboard) {
hasKeyboard = statusKeyboard;
keyboardEvent(hasKeyboard);
}
}
public void showDialog(String acceptButton, String hint, String current, int editType) {
runOnUiThread(() -> showDialogUI(hint, current, editType));
}

View File

@ -1488,7 +1488,6 @@ private:
bool m_camera_offset_changed;
#if defined(__ANDROID__) || defined(__IOS__)
bool show_minimap;
bool m_cache_hold_aux1;
bool m_android_chat_open;
#endif
@ -2513,10 +2512,12 @@ void Game::processUserInput(f32 dtime)
input->step(dtime);
#if defined(__ANDROID__) || defined(__IOS__)
if (current_formspec != NULL)
current_formspec->getAndroidUIInput();
else
handleAndroidChatInput();
if (!porting::hasRealKeyboard()) {
if (current_formspec != NULL)
current_formspec->getAndroidUIInput();
else
handleAndroidChatInput();
}
#endif
// Increase timer for double tap of "keymap_jump"
@ -2724,9 +2725,11 @@ void Game::openConsole(float scale, const wchar_t *line)
assert(scale > 0.0f && scale <= 1.0f);
#if defined(__ANDROID__) || defined(__IOS__)
porting::showInputDialog(gettext("ok"), "", "", 2);
m_android_chat_open = true;
#else
if (!porting::hasRealKeyboard()) {
porting::showInputDialog(gettext("OK"), "", "", 2);
m_android_chat_open = true;
} else {
#endif
if (gui_chat_console->isOpenInhibited())
return;
gui_chat_console->openConsole(scale);
@ -2734,6 +2737,8 @@ void Game::openConsole(float scale, const wchar_t *line)
gui_chat_console->setCloseOnEnter(true);
gui_chat_console->replaceAndAddToHistory(line);
}
#if defined(__ANDROID__) || defined(__IOS__)
}
#endif
}
@ -3124,7 +3129,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
* Android then its meaning is inverted (i.e. holding aux1 means walk and
* not fast)
*/
if (m_cache_hold_aux1) {
if (m_cache_hold_aux1 && !porting::hasRealKeyboard()) {
control.aux1 = control.aux1 ^ true;
keypress_bits ^= ((u32)(1U << 5));
}

View File

@ -150,6 +150,10 @@ void GUIChatConsole::closeConsoleAtOnce()
closeConsole();
m_height = 0;
recalculateConsolePosition();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->show();
#endif
}
f32 GUIChatConsole::getDesiredHeight() const
@ -438,7 +442,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
m_close_on_enter = false;
return true;
}
else if(event.KeyInput.Key == KEY_ESCAPE)
else if(event.KeyInput.Key == KEY_ESCAPE || event.KeyInput.Key == KEY_CANCEL)
{
closeConsoleAtOnce();
m_close_on_enter = false;

View File

@ -340,7 +340,8 @@ void GUIEngine::run()
m_script->step();
#if defined(__ANDROID__) || defined(__IOS__)
m_menu->getAndroidUIInput();
if (!porting::hasRealKeyboard())
m_menu->getAndroidUIInput();
#endif
}
}

View File

@ -3068,7 +3068,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
std::string field_name = getNameByID(hovered->getID());
// read-only field
if (field_name.empty())
if (field_name.empty() || porting::hasRealKeyboard())
return retval;
m_JavaDialogFieldName = getNameByID(hovered->getID());
@ -3089,8 +3089,8 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
if (((gui::IGUIEditBox *)hovered)->isPasswordBox())
type = 3;
porting::showInputDialog(gettext("ok"), "",
wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type);
porting::showInputDialog(gettext("OK"), "",
wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type);
return retval;
}
}

View File

@ -878,6 +878,13 @@ v2u32 getDisplaySize()
# endif // __ANDROID__/__IOS__
#endif // SERVER
#ifndef __ANDROID__
// Dummy for other OS with a touchscreen
bool hasRealKeyboard()
{
return false;
}
#endif
////
//// OS-specific Secure Random

View File

@ -334,6 +334,9 @@ inline const char *getPlatformName()
;
}
// Touchscreen device specific function
bool hasRealKeyboard();
void setXorgClassHint(const video::SExposedVideoData &video_data,
const std::string &name);

View File

@ -61,7 +61,7 @@ void android_main(android_app *app) {
/* handler for finished message box input */
/* Intentionally NOT in namespace porting */
/* TODO this doesn't work as expected, no idea why but there's a workaround */
/* TODO this doesn't work as expected, no idea why but there's a workaround */
/* for it right now */
extern "C" {
JNIEXPORT void JNICALL
@ -75,6 +75,12 @@ JNIEXPORT void JNICALL
Java_com_multicraft_game_GameActivity_pauseGame(JNIEnv *env, jclass clazz) {
external_pause_game();
}
bool device_has_keyboard = false;
JNIEXPORT void JNICALL
Java_com_multicraft_game_GameActivity_keyboardEvent(JNIEnv *env, jclass clazz,
jboolean hasKeyboard) {
device_has_keyboard = hasKeyboard;
}
}
namespace porting {
@ -257,6 +263,10 @@ namespace porting {
return device_memory_max;
}
bool hasRealKeyboard() {
return device_has_keyboard;
}
void notifyAbortLoading() {
jmethodID notifyAbort = jnienv->GetMethodID(nativeActivity,
"notifyAbortLoading", "()V");