mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-22 23:59:42 +00:00
Android: Enable native keyboard for OSK.
And make Windows/Qt follow the same async behavior for input boxes.
This commit is contained in:
parent
e97e3c4218
commit
998f95786a
@ -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),
|
||||
|
@ -410,7 +410,6 @@ public:
|
||||
|
||||
int iPSPModel;
|
||||
int iFirmwareVersion;
|
||||
// TODO: Make this work with your platform, too!
|
||||
bool bBypassOSKWithKeyboard;
|
||||
|
||||
// Debugger
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user