Merge pull request #10015 from unknownbrackets/osk-limit

OSK: Limit allowed keyboards based on input mask
This commit is contained in:
Henrik Rydgård 2017-10-15 10:39:33 +02:00 committed by GitHub
commit 6c6cdd0d68
2 changed files with 88 additions and 32 deletions

View File

@ -23,7 +23,7 @@ indent_style = space
indent_size = 4
[Core/Dialog/PSPOskDialog.cpp]
charset = utf-16le
charset = utf-8-bom
[ext/native/tools/kanjifilter.h]
# This file may need to force a BOM so compilers treat as utf-8.

View File

@ -143,6 +143,18 @@ static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
},
};
// This isn't a complete representation of these flags, it just helps ensure we show the right keyboards.
int allowedInputFlagsMap[OSK_KEYBOARD_COUNT] = {
PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT,
PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL,
PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HIRAGANA,
PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_KATAKANA | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HALF_KATAKANA,
PSP_UTILITY_OSK_INPUTTYPE_KOREAN,
PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_LOWERCASE,
PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_UPPERCASE,
PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_DIGIT,
PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL,
};
PSPOskDialog::PSPOskDialog() : PSPDialog() {
// This can break all kinds of stuff, changing the decimal point in sprintf for example.
@ -227,6 +239,42 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input)
_string = stringBuffer;
}
static void FindValidKeyboard(s32 inputType, int direction, OskKeyboardLanguage &lang, OskKeyboardDisplay &disp) {
OskKeyboardLanguage origLang = lang;
OskKeyboardDisplay origDisp = disp;
if (inputType == 0) {
return;
}
// TODO: Limit by allowed keyboards properly... this is just an approximation.
int tries = OSK_LANGUAGE_COUNT * 2;
while (!(inputType & allowedInputFlagsMap[disp]) && tries > 0) {
if ((--tries % 1) == 0) {
lang = (OskKeyboardLanguage)((OSK_LANGUAGE_COUNT + lang + direction) % OSK_LANGUAGE_COUNT);
disp = OskKeyboardCases[lang][LOWERCASE];
} else {
disp = OskKeyboardCases[lang][UPPERCASE];
}
}
if (tries == 0) {
// In case of error, let's just fall back to allowing all.
lang = origLang;
disp = origDisp;
}
}
static bool IsKeyboardShiftValid(s32 inputType, OskKeyboardLanguage lang, OskKeyboardDisplay disp) {
// Swap disp and check if it's valid.
if (disp == OskKeyboardCases[lang][UPPERCASE])
disp = OskKeyboardCases[lang][LOWERCASE];
else
disp = OskKeyboardCases[lang][UPPERCASE];
return inputType == 0 || (inputType & allowedInputFlagsMap[disp]) != 0;
}
int PSPOskDialog::Init(u32 oskPtr) {
// Ignore if already running
if (GetStatus() != SCE_UTILITY_STATUS_NONE) {
@ -259,8 +307,9 @@ int PSPOskDialog::Init(u32 oskPtr) {
ChangeStatusInit(OSK_INIT_DELAY_US);
selectedChar = 0;
currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE;
currentKeyboardLanguage = OSK_LANGUAGE_ENGLISH;
currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE;
FindValidKeyboard(oskParams->fields[0].inputtype, 1, currentKeyboardLanguage, currentKeyboard);
ConvertUCS2ToUTF8(oskDesc, oskParams->fields[0].desc);
ConvertUCS2ToUTF8(oskIntext, oskParams->fields[0].intext);
@ -887,37 +936,43 @@ int PSPOskDialog::Update(int animSpeed) {
PPGeDrawText("Start", 135, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Finish"), 185, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
int index = (currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT;
const char *countryCode;
auto lookupLangName = [&](int direction) {
// First, find the valid one...
OskKeyboardLanguage lang = (OskKeyboardLanguage)((OSK_LANGUAGE_COUNT + currentKeyboardLanguage + direction) % OSK_LANGUAGE_COUNT);
OskKeyboardDisplay disp = OskKeyboardCases[lang][LOWERCASE];
FindValidKeyboard(oskParams->fields[0].inputtype, direction, lang, disp);
if (index >= 0)
countryCode = OskKeyboardNames[(currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT].c_str();
else
countryCode = OskKeyboardNames[OSK_LANGUAGE_COUNT - 1].c_str();
if (lang == currentKeyboardLanguage) {
return (const char *)nullptr;
}
const char *language = languageMapping[countryCode].first.c_str();
// Now, let's grab the name.
const char *countryCode = OskKeyboardNames[lang].c_str();
const char *language = languageMapping[countryCode].first.c_str();
if (!strcmp(countryCode, "English Full-width"))
language = "English Full-width";
countryCode = OskKeyboardNames[currentKeyboardLanguage].c_str();
if (strcmp(countryCode, "ko_KR")) {
// It seems like this is a "fake" country code for extra keyboard purposes.
if (!strcmp(countryCode, "English Full-width"))
language = "English Full-width";
return language;
};
if (OskKeyboardNames[currentKeyboardLanguage] != "ko_KR" && IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) {
PPGeDrawText("Select", 135, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Shift"), 185, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
}
PPGeDrawText("L", 235, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(language, 255, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
countryCode = OskKeyboardNames[(currentKeyboardLanguage + 1) % OSK_LANGUAGE_COUNT].c_str();
language = languageMapping[countryCode].first.c_str();
const char *prevLang = lookupLangName(-1);
if (prevLang) {
PPGeDrawText("L", 235, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(prevLang, 255, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
}
if (!strcmp(countryCode, "English Full-width"))
language = "English Full-width";
PPGeDrawText("R", 235, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(language, 255, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
const char *nextLang = lookupLangName(1);
if (nextLang) {
PPGeDrawText("R", 235, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(nextLang, 255, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
}
if (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upBtnFramesHeld, framesHeldThreshold, framesHeldRepeatRate)) {
selectedChar -= numKeyCols[currentKeyboard];
@ -939,10 +994,12 @@ int PSPOskDialog::Update(int animSpeed) {
inputChars = CombinationString(true);
} else if (IsButtonPressed(CTRL_SELECT)) {
// Select now swaps case.
if (currentKeyboard == OskKeyboardCases[currentKeyboardLanguage][UPPERCASE])
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE];
else
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][UPPERCASE];
if (IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) {
if (currentKeyboard == OskKeyboardCases[currentKeyboardLanguage][UPPERCASE])
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE];
else
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][UPPERCASE];
}
if (selectedRow >= numKeyRows[currentKeyboard]) {
selectedRow = numKeyRows[currentKeyboard] - 1;
@ -954,10 +1011,10 @@ int PSPOskDialog::Update(int animSpeed) {
selectedChar = selectedRow * numKeyCols[currentKeyboard] + selectedExtra;
} else if (IsButtonPressed(CTRL_RTRIGGER)) {
// TODO: Limit by allowed keyboards...
// RTRIGGER now cycles languages forward.
currentKeyboardLanguage = (OskKeyboardLanguage)((currentKeyboardLanguage + 1) % OSK_LANGUAGE_COUNT);
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE];
FindValidKeyboard(oskParams->fields[0].inputtype, 1, currentKeyboardLanguage, currentKeyboard);
if (selectedRow >= numKeyRows[currentKeyboard]) {
selectedRow = numKeyRows[currentKeyboard] - 1;
@ -969,14 +1026,13 @@ int PSPOskDialog::Update(int animSpeed) {
selectedChar = selectedRow * numKeyCols[currentKeyboard] + selectedExtra;
} else if (IsButtonPressed(CTRL_LTRIGGER)) {
// TODO: Limit by allowed keyboards...
// LTRIGGER now cycles languages backward.
if (currentKeyboardLanguage - 1 >= 0)
currentKeyboardLanguage = (OskKeyboardLanguage)((currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT);
else
currentKeyboardLanguage = (OskKeyboardLanguage)(OSK_LANGUAGE_COUNT - 1);
currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE];
FindValidKeyboard(oskParams->fields[0].inputtype, -1, currentKeyboardLanguage, currentKeyboard);
if (selectedRow >= numKeyRows[currentKeyboard]) {
selectedRow = numKeyRows[currentKeyboard] - 1;