Android: Enable native keyboard for OSK.

And make Windows/Qt follow the same async behavior for input boxes.
This commit is contained in:
Unknown W. Brackets 2020-03-09 17:36:52 -07:00
parent e97e3c4218
commit 998f95786a
7 changed files with 67 additions and 36 deletions

View File

@ -968,7 +968,7 @@ static ConfigSetting systemParamSettings[] = {
ReportedConfigSetting("ButtonPreference", &g_Config.iButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS, true, true),
ConfigSetting("LockParentalLevel", &g_Config.iLockParentalLevel, 0, true, true),
ConfigSetting("WlanAdhocChannel", &g_Config.iWlanAdhocChannel, PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC, true, true),
#if defined(USING_WIN_UI)
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
ConfigSetting("BypassOSKWithKeyboard", &g_Config.bBypassOSKWithKeyboard, false, true, true),
#endif
ConfigSetting("WlanPowerSave", &g_Config.bWlanPowerSave, (bool) PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF, true, true),

View File

@ -410,7 +410,6 @@ public:
int iPSPModel;
int iFirmwareVersion;
// TODO: Make this work with your platform, too!
bool bBypassOSKWithKeyboard;
// Debugger

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "base/NativeApp.h"
#include "i18n/i18n.h"
#include "math/math_util.h"
#include "util/text/utf8.h"
@ -30,10 +31,6 @@
#include "Common/ChunkFile.h"
#include "GPU/GPUState.h"
#if defined(USING_WIN_UI)
#include "base/NativeApp.h"
#endif
#ifndef _WIN32
#include <ctype.h>
#include <math.h>
@ -332,6 +329,9 @@ int PSPOskDialog::Init(u32 oskPtr) {
// Eat any keys pressed before the dialog inited.
UpdateButtons();
std::lock_guard<std::mutex> guard(nativeMutex_);
nativeStatus_ = PSPOskNativeStatus::IDLE;
StartFade(true);
return 0;
}
@ -837,7 +837,6 @@ void PSPOskDialog::RenderKeyboard()
}
}
#if defined(USING_WIN_UI)
// TODO: Why does this have a 2 button press lag/delay when
// re-opening the dialog box? I don't get it.
int PSPOskDialog::NativeKeyboard() {
@ -845,28 +844,51 @@ int PSPOskDialog::NativeKeyboard() {
return SCE_ERROR_UTILITY_INVALID_STATUS;
}
std::wstring titleText;
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
bool beginInputBox = false;
if (nativeStatus_ == PSPOskNativeStatus::IDLE) {
std::lock_guard<std::mutex> guard(nativeMutex_);
if (nativeStatus_ == PSPOskNativeStatus::IDLE) {
nativeStatus_ = PSPOskNativeStatus::WAITING;
beginInputBox = true;
}
}
std::wstring defaultText;
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
if (beginInputBox) {
std::wstring titleText;
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
if (defaultText.empty())
defaultText.assign(L"VALUE");
std::wstring defaultText;
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
// TODO: This is USING_WIN_UI only, so we rely on it being synchronous...
// But we should really have this set some state that is checked each time NativeKeyboard is called.
System_InputBoxGetString(ConvertWStringToUTF8(titleText), ConvertWStringToUTF8(defaultText), [&](bool result, const std::string &value) {
if (result) {
inputChars = ConvertUTF8ToWString(value);
u32 maxLength = FieldMaxLength();
if (inputChars.length() > maxLength) {
ERROR_LOG(SCEUTILITY, "NativeKeyboard: input text too long(%d characters/glyphs max), truncating to game-requested length.", maxLength);
inputChars.erase(maxLength, std::string::npos);
if (defaultText.empty())
defaultText.assign(L"VALUE");
System_InputBoxGetString(ConvertWStringToUTF8(titleText), ConvertWStringToUTF8(defaultText), [&](bool result, const std::string &value) {
std::lock_guard<std::mutex> guard(nativeMutex_);
if (nativeStatus_ != PSPOskNativeStatus::WAITING) {
return;
}
nativeValue_ = value;
nativeStatus_ = result ? PSPOskNativeStatus::SUCCESS : PSPOskNativeStatus::FAILURE;
});
} else if (nativeStatus_ == PSPOskNativeStatus::SUCCESS) {
inputChars = ConvertUTF8ToWString(nativeValue_);
nativeValue_.clear();
u32 maxLength = FieldMaxLength();
if (inputChars.length() > maxLength) {
ERROR_LOG(SCEUTILITY, "NativeKeyboard: input text too long(%d characters/glyphs max), truncating to game-requested length.", maxLength);
inputChars.erase(maxLength, std::string::npos);
}
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
});
nativeStatus_ = PSPOskNativeStatus::DONE;
} else if (nativeStatus_ == PSPOskNativeStatus::FAILURE) {
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
nativeStatus_ = PSPOskNativeStatus::DONE;
}
#endif
u16_le *outText = oskParams->fields[0].outtext;
@ -886,7 +908,6 @@ int PSPOskDialog::NativeKeyboard() {
return 0;
}
#endif
int PSPOskDialog::Update(int animSpeed) {
if (GetStatus() != SCE_UTILITY_STATUS_RUNNING) {
@ -908,12 +929,10 @@ int PSPOskDialog::Update(int animSpeed) {
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
int selectedExtra = selectedChar % numKeyCols[currentKeyboard];
// TODO: Add your platforms here when you have a NativeKeyboard func.
#if defined(USING_WIN_UI)
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
// Windows: Fall back to the OSK/continue normally if we're in fullscreen.
// The dialog box doesn't work right if in fullscreen.
if(g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
return NativeKeyboard();
#endif
@ -1095,6 +1114,7 @@ int PSPOskDialog::Shutdown(bool force)
if (!force) {
ChangeStatusShutdown(OSK_SHUTDOWN_DELAY_US);
}
nativeStatus_ = PSPOskNativeStatus::IDLE;
return 0;
}
@ -1113,6 +1133,7 @@ void PSPOskDialog::DoState(PointerWrap &p)
p.Do(oskOuttext);
p.Do(selectedChar);
p.Do(inputChars);
// Don't need to save state native status or value.
}
pspUtilityDialogCommon *PSPOskDialog::GetCommonParam()

View File

@ -17,6 +17,7 @@
#pragma once
#include <mutex>
#include <string>
#include "Core/Dialog/PSPDialog.h"
@ -202,6 +203,14 @@ static const std::string OskKeyboardNames[] =
"English Full-width",
};
enum class PSPOskNativeStatus {
IDLE,
DONE,
WAITING,
SUCCESS,
FAILURE,
};
class PSPOskDialog: public PSPDialog {
public:
PSPOskDialog();
@ -222,9 +231,7 @@ private:
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le>& em_address);
void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input);
void RenderKeyboard();
#if defined(USING_WIN_UI)
int NativeKeyboard();
#endif
std::wstring CombinationString(bool isInput); // for Japanese, Korean
std::wstring CombinationKorean(bool isInput); // for Korea
@ -244,6 +251,10 @@ private:
OskKeyboardLanguage currentKeyboardLanguage;
bool isCombinated;
std::mutex nativeMutex_;
PSPOskNativeStatus nativeStatus_ = PSPOskNativeStatus::IDLE;
std::string nativeValue_;
int i_level; // for Korean Keyboard support
int i_value[3]; // for Korean Keyboard support
};

View File

@ -230,9 +230,9 @@ PermissionStatus System_GetPermissionStatus(SystemPermission permission) { retur
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) {
QString text = emugl->InputBoxGetQString(QString::fromStdString(title), QString::fromStdString(defaultValue));
if (text.isEmpty()) {
cb(false, "");
NativeInputBoxReceived(cb, false, "");
} else {
cb(true, text.toStdString());
NativeInputBoxReceived(cb, true, text.toStdString());
}
}

View File

@ -801,8 +801,8 @@ void GameSettingsScreen::CreateViews() {
systemSettings->Add(new CheckBox(&g_Config.bEnableStateUndo, sy->T("Savestate slot backups")));
static const char *autoLoadSaveStateChoices[] = { "Off", "Oldest Save", "Newest Save", "Slot 1", "Slot 2", "Slot 3", "Slot 4", "Slot 5" };
systemSettings->Add(new PopupMultiChoice(&g_Config.iAutoLoadSaveState, sy->T("Auto Load Savestate"), autoLoadSaveStateChoices, 0, ARRAY_SIZE(autoLoadSaveStateChoices), sy->GetName(), screenManager()));
#if defined(USING_WIN_UI)
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Enable Windows native keyboard", "Enable Windows native keyboard")));
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Use system native keyboard")));
#endif
#if PPSSPP_PLATFORM(ANDROID)
auto memstickPath = systemSettings->Add(new ChoiceWithValueDisplay(&g_Config.memStickDirectory, sy->T("Change Memory Stick folder"), (const char *)nullptr));

View File

@ -341,9 +341,9 @@ void EnableCrashingOnCrashes() {
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) {
std::string out;
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(title).c_str(), defaultValue, out)) {
cb(true, out);
NativeInputBoxReceived(cb, true, out);
} else {
cb(false, "");
NativeInputBoxReceived(cb, false, "");
}
}