mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
OSK support final update
- Renamed few functions to avoid confusion - Now UI will report text (gotfocus, lostfocus), popup_closed to the frontend - Both cases (DPad, Keyboard) covered
This commit is contained in:
parent
3225446ff6
commit
4e2652bd4b
@ -391,8 +391,8 @@ void PopupScreen::TriggerFinish(DialogResult result) {
|
||||
OnCompleted(result);
|
||||
}
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
// Inform UI to hide OSK and to disable keyboard mode
|
||||
System_NotifyUIState("hide_keyboard");
|
||||
// Inform UI that popup close to hide OSK (if visible)
|
||||
System_NotifyUIState("popup_closed");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1086,13 +1086,10 @@ TextEdit::TextEdit(const std::string &text, const std::string &title, const std:
|
||||
void TextEdit::FocusChanged(int focusFlags) {
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
if (focusFlags == FF_GOTFOCUS) {
|
||||
System_NotifyUIState("show_keyboard");
|
||||
System_NotifyUIState("text_gotfocus");
|
||||
}
|
||||
else {
|
||||
// OSK will be hidden by `Back` button and no reason to check focus
|
||||
if (!isInputPaneVisible()) {
|
||||
System_NotifyUIState("hide_keyboard");
|
||||
}
|
||||
System_NotifyUIState("text_lostfocus");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1271,7 +1271,7 @@ bool NativeKey(const KeyInput &key) {
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
// Ignore if key sent from OnKeyDown/OnKeyUp/XInput while keyboard mode active
|
||||
// Ignore if key sent from OnKeyDown/OnKeyUp/XInput while text edit active
|
||||
// it's already handled by `OnCharacterReceived`
|
||||
if (IgnoreInput(key.keyCode) && !(key.flags & KEY_CHAR)) {
|
||||
return false;
|
||||
|
@ -192,6 +192,9 @@ void PPSSPP_UWPMain::OnDeviceRestored() {
|
||||
|
||||
void PPSSPP_UWPMain::OnKeyDown(int scanCode, Windows::System::VirtualKey virtualKey, int repeatCount) {
|
||||
// TODO: Look like (Ctrl, Alt, Shift) don't trigger this event
|
||||
bool isDPad = (int)virtualKey >= 195 && (int)virtualKey <= 218; // DPad buttons range
|
||||
DPadInputState(isDPad);
|
||||
|
||||
auto iter = virtualKeyCodeToNKCode.find(virtualKey);
|
||||
if (iter != virtualKeyCodeToNKCode.end()) {
|
||||
KeyInput key{};
|
||||
@ -216,7 +219,7 @@ void PPSSPP_UWPMain::OnKeyUp(int scanCode, Windows::System::VirtualKey virtualKe
|
||||
void PPSSPP_UWPMain::OnCharacterReceived(int scanCode, unsigned int keyCode) {
|
||||
// This event triggered only in chars case, (Arrows, Delete..etc don't call it)
|
||||
// TODO: Add ` && !IsCtrlOnHold()` once it's ready and implemented
|
||||
if (isKeyboardActive()) {
|
||||
if (isTextEditActive()) {
|
||||
KeyInput key{};
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
key.keyCode = (InputKeyCode)keyCode;
|
||||
@ -426,7 +429,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
||||
// Do actual check
|
||||
// touch devices has input pane, we need to depend on it
|
||||
// I don't know any possible way to display input dialog in non-xaml apps
|
||||
return isKeybaordAvailable() || isTouchAvailable();
|
||||
return isKeyboardAvailable() || isTouchAvailable();
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
@ -536,26 +539,19 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
|
||||
}
|
||||
case SystemRequestType::NOTIFY_UI_STATE:
|
||||
{
|
||||
if (!param1.empty() && !strcmp(param1.c_str(), "menu")) {
|
||||
CloseLaunchItem();
|
||||
}
|
||||
else if (!strcmp(param1.c_str(), "show_keyboard")) {
|
||||
// Must be performed from UI thread
|
||||
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([]()
|
||||
{
|
||||
ActivateKeyboardInput();
|
||||
}));
|
||||
}
|
||||
else if (!strcmp(param1.c_str(), "hide_keyboard")) {
|
||||
// Must be performed from UI thread
|
||||
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([]()
|
||||
{
|
||||
DeactivateKeyboardInput();
|
||||
}));
|
||||
if (!param1.empty()) {
|
||||
if (!strcmp(param1.c_str(), "menu")) {
|
||||
CloseLaunchItem();
|
||||
}
|
||||
else if (!strcmp(param1.c_str(), "popup_closed")) {
|
||||
DeactivateTextEditInput();
|
||||
}
|
||||
else if (!strcmp(param1.c_str(), "text_gotfocus")) {
|
||||
ActivateTextEditInput(true);
|
||||
}
|
||||
else if (!strcmp(param1.c_str(), "text_lostfocus")) {
|
||||
DeactivateTextEditInput(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -41,9 +41,8 @@ bool findInList(std::list<T>& inputList, T& str) {
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Input Keyboard
|
||||
|
||||
bool isKeybaordAvailable() {
|
||||
#pragma region Input Devices
|
||||
bool isKeyboardAvailable() {
|
||||
Windows::Devices::Input::KeyboardCapabilities^ keyboardCapabilities = ref new Windows::Devices::Input::KeyboardCapabilities();
|
||||
bool hasKeyboard = keyboardCapabilities->KeyboardPresent != 0;
|
||||
return hasKeyboard;
|
||||
@ -54,8 +53,12 @@ bool isTouchAvailable() {
|
||||
bool hasTouch = touchCapabilities->TouchPresent != 0;
|
||||
return hasTouch;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
bool keyboardActive = false;
|
||||
#pragma region Input Keyboard
|
||||
|
||||
bool dPadInputActive = false;
|
||||
bool textEditActive = false;
|
||||
bool inputPaneVisible = false;
|
||||
Platform::Agile<Windows::UI::ViewManagement::InputPane> inputPane = nullptr;
|
||||
|
||||
@ -72,45 +75,87 @@ void PrepareInputPane() {
|
||||
inputPane->Hiding += ref new Windows::Foundation::TypedEventHandler<InputPane^, InputPaneVisibilityEventArgs^>(&OnHiding);
|
||||
}
|
||||
|
||||
// Show input pane (OSK)
|
||||
bool ShowInputPane() {
|
||||
return !isInputPaneVisible() ? inputPane->TryShow() : true;
|
||||
}
|
||||
// Hide input pane (OSK)
|
||||
bool HideInputPane() {
|
||||
return isInputPaneVisible() ? inputPane->TryHide() : true;
|
||||
}
|
||||
|
||||
// Check if input pane (OSK) visible
|
||||
bool isInputPaneVisible() {
|
||||
return inputPaneVisible;
|
||||
}
|
||||
|
||||
bool isKeyboardActive() {
|
||||
return keyboardActive;
|
||||
// Check if text edit active (got focus)
|
||||
bool isTextEditActive() {
|
||||
return textEditActive;
|
||||
}
|
||||
|
||||
void ActivateKeyboardInput() {
|
||||
DEBUG_LOG(COMMON, "Activate input keyboard");
|
||||
if (inputPane->TryShow()) {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryShow accepted");
|
||||
}
|
||||
else {
|
||||
DEBUG_LOG(COMMON, "Input pane: (TryShow is not accepted or pane is not supported)");
|
||||
|
||||
}
|
||||
keyboardActive = true;
|
||||
// Set if the current input is DPad
|
||||
void DPadInputState(bool inputState) {
|
||||
dPadInputActive = inputState;
|
||||
}
|
||||
|
||||
void DeactivateKeyboardInput() {
|
||||
DEBUG_LOG(COMMON, "Deactivate input keyboard");
|
||||
if (inputPane->TryHide()) {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryHide accepted");
|
||||
}
|
||||
else {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryHide is not accepted, or pane is not visible");
|
||||
}
|
||||
keyboardActive = false;
|
||||
// Check if the current input is DPad
|
||||
bool isDPadActive() {
|
||||
return dPadInputActive;
|
||||
}
|
||||
|
||||
void ActivateTextEditInput(bool byFocus) {
|
||||
// Must be performed from UI thread
|
||||
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
if (byFocus) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
if (!isInputPaneVisible() && (isDPadActive() || !IsXBox())) {
|
||||
if (ShowInputPane()) {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryShow accepted");
|
||||
}
|
||||
else {
|
||||
DEBUG_LOG(COMMON, "Input pane: (TryShow is not accepted or not supported)");
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(COMMON, "Text edit active");
|
||||
textEditActive = true;
|
||||
}));
|
||||
}
|
||||
|
||||
void DeactivateTextEditInput(bool byFocus) {
|
||||
// Must be performed from UI thread
|
||||
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
if (isInputPaneVisible()) {
|
||||
if (HideInputPane()) {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryHide accepted");
|
||||
}
|
||||
else {
|
||||
DEBUG_LOG(COMMON, "Input pane: TryHide is not accepted, or not supported");
|
||||
}
|
||||
}
|
||||
if (isTextEditActive()) {
|
||||
DEBUG_LOG(COMMON, "Text edit inactive");
|
||||
textEditActive = false;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
bool IgnoreInput(int keyCode) {
|
||||
// When keyboard mode active and char is passed this function return 'true'
|
||||
// When text edit active and char is passed this function return 'true'
|
||||
// it will help to prevent KeyDown from sending the same code again
|
||||
bool ignoreInput = false;
|
||||
// TODO: Add ` && !IsCtrlOnHold()` once it's ready and implemented
|
||||
if (isKeyboardActive()) {
|
||||
if (isTextEditActive()) {
|
||||
// To avoid bothering KeyDown to check this case always
|
||||
// we don't get here unless keyboard mode is active
|
||||
// we don't get here unless text edit is active
|
||||
std::list<int> nonCharList = {
|
||||
NKCODE_CTRL_LEFT,
|
||||
NKCODE_CTRL_RIGHT,
|
||||
@ -127,7 +172,6 @@ bool IgnoreInput(int keyCode) {
|
||||
NKCODE_EXT_MOUSEBUTTON_3,
|
||||
NKCODE_EXT_MOUSEBUTTON_4,
|
||||
NKCODE_EXT_MOUSEBUTTON_5,
|
||||
NKCODE_ESCAPE
|
||||
};
|
||||
if (!isInputPaneVisible()) {
|
||||
// Keyboard active but no on-screen keyboard
|
||||
@ -137,6 +181,7 @@ bool IgnoreInput(int keyCode) {
|
||||
nonCharList.push_back(NKCODE_DPAD_LEFT);
|
||||
nonCharList.push_back(NKCODE_DPAD_RIGHT);
|
||||
nonCharList.push_back(NKCODE_BACK);
|
||||
nonCharList.push_back(NKCODE_ESCAPE);
|
||||
}
|
||||
|
||||
ignoreInput = !findInList(nonCharList, keyCode);
|
||||
|
@ -19,17 +19,25 @@
|
||||
#include <string>
|
||||
|
||||
// Input Devices
|
||||
bool isKeybaordAvailable();
|
||||
bool isKeyboardAvailable();
|
||||
bool isTouchAvailable();
|
||||
|
||||
// Input Keyboard/Pane
|
||||
// Input Pane
|
||||
void PrepareInputPane();
|
||||
bool isInputPaneVisible();
|
||||
bool isKeyboardActive();
|
||||
void ActivateKeyboardInput();
|
||||
void DeactivateKeyboardInput();
|
||||
bool ShowInputPane();
|
||||
bool HideInputPane();
|
||||
|
||||
// Text Edit
|
||||
bool isTextEditActive();
|
||||
void ActivateTextEditInput(bool byFocus = false);
|
||||
void DeactivateTextEditInput(bool byFocus = false);
|
||||
bool IgnoreInput(int keyCode);
|
||||
|
||||
// Input DPad
|
||||
void DPadInputState(bool inputState);
|
||||
bool isDPadActive();
|
||||
|
||||
// Keys Status
|
||||
bool IsCapsLockOn();
|
||||
bool IsShiftOnHold();
|
||||
|
Loading…
Reference in New Issue
Block a user