From 6af6c0baee214c21f8522571c7d3412a743681d7 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 20 Feb 2020 15:20:49 +0100 Subject: [PATCH] Add an option to filter the list using the built in on screen keyboard --- src/menu/KeyboardHelper.cpp | 115 +++++++++++++++++++++++++++++++++ src/menu/KeyboardHelper.h | 32 +++++++++ src/menu/MainDrcButtonsFrame.h | 14 +++- src/menu/MainWindow.cpp | 38 +++++++++++ src/menu/MainWindow.h | 3 + 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 src/menu/KeyboardHelper.cpp create mode 100644 src/menu/KeyboardHelper.h diff --git a/src/menu/KeyboardHelper.cpp b/src/menu/KeyboardHelper.cpp new file mode 100644 index 0000000..59416cc --- /dev/null +++ b/src/menu/KeyboardHelper.cpp @@ -0,0 +1,115 @@ +#include +#include "KeyboardHelper.h" +#include "utils/logger.h" +#include + +KeyboardHelper::KeyboardHelper() { + FSClient *fsClient = (FSClient *)MEMAllocFromDefaultHeap(sizeof(FSClient)); + FSAddClient(fsClient, 0); + + // Create swkbd + nn::swkbd::CreateArg createArg; + createArg.regionType = nn::swkbd::RegionType::Europe; + createArg.workMemory = MEMAllocFromDefaultHeap(nn::swkbd::GetWorkMemorySize(0)); + memset(createArg.workMemory,0, sizeof(nn::swkbd::GetWorkMemorySize(0))); + this->workMemory = createArg.workMemory; + createArg.fsClient = fsClient; + this->fsClient = createArg.fsClient; + DEBUG_FUNCTION_LINE("Calling create\n"); + if (!nn::swkbd::Create(createArg)) { + DEBUG_FUNCTION_LINE("Failed to create keyboard\n"); + return; + } + + keyboardCreated = true; +} + +KeyboardHelper::~KeyboardHelper() { + if(keyboardCreated) { + nn::swkbd::Destroy(); + MEMFreeToDefaultHeap(this->workMemory); + this->workMemory = NULL; + + FSDelClient(fsClient, 0); + MEMFreeToDefaultHeap(this->fsClient); + keyboardCreated = false; + } +} + +bool KeyboardHelper::openKeyboard() { + if(keyboardCreated) { + // Show the keyboard + nn::swkbd::AppearArg appearArg; + appearArg.keyboardArg.configArg.languageType = nn::swkbd::LanguageType::English; + if (!nn::swkbd::AppearInputForm(appearArg)) { + DEBUG_FUNCTION_LINE("nn::swkbd::AppearInputForm failed\n"); + return false; + } + keyboardOpen = true; + return true; + } + return false; +} + +std::string KeyboardHelper::getResult() { + return resultStr; +} + +bool KeyboardHelper::checkResult() { + if(keyboardCreated) { + VPADStatus vpadStatus; + if(keyboardOpen) { + VPADRead(VPAD_CHAN_0, &vpadStatus, 1, nullptr); + VPADGetTPCalibratedPoint(VPAD_CHAN_0, &vpadStatus.tpNormal, &vpadStatus.tpNormal); + } + // Update keyboard + nn::swkbd::ControllerInfo controllerInfo; + controllerInfo.vpad = &vpadStatus; + controllerInfo.kpad[0] = nullptr; + controllerInfo.kpad[1] = nullptr; + controllerInfo.kpad[2] = nullptr; + controllerInfo.kpad[3] = nullptr; + nn::swkbd::Calc(controllerInfo); + + if (nn::swkbd::IsNeedCalcSubThreadFont()) { + nn::swkbd::CalcSubThreadFont(); + } + + if (nn::swkbd::IsNeedCalcSubThreadPredict()) { + nn::swkbd::CalcSubThreadPredict(); + } + + if (nn::swkbd::IsDecideOkButton(nullptr) || nn::swkbd::IsDecideCancelButton(nullptr)) { + const char16_t *str = nn::swkbd::GetInputFormString(); + // Quick hack to get from a char16_t str to char for our log function + char logStr[128]; + logStr[0] = 0; + + for (int i = 0; i < 128; ++i) { + if (!str[i]) { + logStr[i] = 0; + break; + } + + if (str[i] > 0x7F) { + logStr[i] = '?'; + } else { + logStr[i] = str[i]; + } + } + this->resultStr = logStr; + keyboardOpen = false; + nn::swkbd::DisappearInputForm(); + return true; + } + } + return false; +} + +void KeyboardHelper::drawDRC() { + nn::swkbd::DrawDRC(); +} + +void KeyboardHelper::drawTV() { + nn::swkbd::DrawTV(); +} diff --git a/src/menu/KeyboardHelper.h b/src/menu/KeyboardHelper.h new file mode 100644 index 0000000..c1daa02 --- /dev/null +++ b/src/menu/KeyboardHelper.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include + +class KeyboardHelper { +public: + KeyboardHelper(); + + ~KeyboardHelper(); + + bool checkResult(); + + void drawTV(); + + void drawDRC(); + + bool openKeyboard(); + + bool isReady(){ + return keyboardCreated; + } + + std::string getResult(); + +private: + + void * workMemory = NULL; + FSClient * fsClient = NULL; + bool keyboardOpen = false; + bool keyboardCreated = false; + std::string resultStr = ""; +}; diff --git a/src/menu/MainDrcButtonsFrame.h b/src/menu/MainDrcButtonsFrame.h index 5cf5b17..0a1bc52 100644 --- a/src/menu/MainDrcButtonsFrame.h +++ b/src/menu/MainDrcButtonsFrame.h @@ -33,7 +33,7 @@ public: , settingsIcon(settingsIconData) , switchLayoutButton(switchIcon.getWidth(), switchIcon.getHeight()) , settingsButton(settingsIcon.getWidth(), settingsIcon.getHeight()) - , gameImageDownloadButton(w, h) + , gameListFilterButton(w, h) , touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH) , wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) , settingsTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_ZL, true) @@ -61,6 +61,12 @@ public: switchLayoutButton.setEffectGrow(); switchLayoutButton.clicked.connect(this, &MainDrcButtonsFrame::OnLayoutSwithClick); append(&switchLayoutButton); + + gameListFilterButton.setClickable(true); + gameListFilterButton.setSoundClick(buttonClickSound); + gameListFilterButton.setTrigger(&plusTrigger); + gameListFilterButton.clicked.connect(this, &MainDrcButtonsFrame::OnGameListFilterButtonClicked); + append(&gameListFilterButton); } virtual ~MainDrcButtonsFrame() { @@ -72,6 +78,7 @@ public: sigslot::signal1 settingsButtonClicked; sigslot::signal1 layoutSwitchClicked; + sigslot::signal1 gameListFilterClicked; private: void OnSettingsButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *) { settingsButtonClicked(this); @@ -79,6 +86,9 @@ private: void OnLayoutSwithClick(GuiButton *button, const GuiController *controller, GuiTrigger *) { layoutSwitchClicked(this); } + void OnGameListFilterButtonClicked(GuiButton *button, const GuiController *controller, GuiTrigger *) { + gameListFilterClicked(this); + } GuiSound *buttonClickSound; GuiSound *screenSwitchSound; @@ -89,7 +99,7 @@ private: GuiButton switchLayoutButton; GuiButton settingsButton; - GuiButton gameImageDownloadButton; + GuiButton gameListFilterButton; GuiTrigger touchTrigger; GuiTrigger wpadTouchTrigger; diff --git a/src/menu/MainWindow.cpp b/src/menu/MainWindow.cpp index 5cdc269..8391f1e 100644 --- a/src/menu/MainWindow.cpp +++ b/src/menu/MainWindow.cpp @@ -18,6 +18,7 @@ #include "Application.h" #include "utils/logger.h" #include "utils/StringTools.h" + #include "resources/Resources.h" #include "gui/GuiTitleBrowser.h" #include "gui/GuiIconGrid.h" @@ -107,6 +108,19 @@ void MainWindow::process() { tvElements[i]->process(); } } + + if(keyboardInstance != NULL) { + if(keyboardInstance->checkResult()) { + std::string result = keyboardInstance->getResult(); + + currentTvFrame->clearState(GuiElement::STATE_DISABLED); + currentDrcFrame->clearState(GuiElement::STATE_DISABLED); + mainSwitchButtonFrame->clearState(GuiElement::STATE_DISABLED); + + gameList.filterList(result.c_str()); + }else{ + } + } } void MainWindow::OnGameTitleListChanged(GameList * list) { @@ -186,6 +200,10 @@ void MainWindow::drawDrc(CVideo *video) { pointerImg[i]->setAlpha(1.0f); } } + + if(keyboardInstance != NULL) { + keyboardInstance->drawDRC(); + } } void MainWindow::drawTv(CVideo *video) { @@ -199,6 +217,9 @@ void MainWindow::drawTv(CVideo *video) { pointerValid[i] = false; } } + if(keyboardInstance != NULL) { + keyboardInstance->drawTV(); + } } void MainWindow::SetupMainView() { @@ -268,6 +289,23 @@ void MainWindow::OnLayoutSwitchClicked(GuiElement *element) { mainSwitchButtonFrame->setState(GuiElement::STATE_DISABLED); } +void MainWindow::OnGameListFilterButtonClicked(GuiElement *element) { + if(!currentTvFrame || !currentDrcFrame || !mainSwitchButtonFrame) { + return; + } + + if(keyboardInstance == NULL) { + keyboardInstance = new KeyboardHelper(); + } + if(keyboardInstance->isReady()) { + if(keyboardInstance->openKeyboard()) { + currentTvFrame->setState(GuiElement::STATE_DISABLED); + currentDrcFrame->setState(GuiElement::STATE_DISABLED); + mainSwitchButtonFrame->setState(GuiElement::STATE_DISABLED); + } + } +} + void MainWindow::OnLayoutSwitchEffectFinish(GuiElement *element) { if(!currentTvFrame || !currentDrcFrame || !mainSwitchButtonFrame) return; diff --git a/src/menu/MainWindow.h b/src/menu/MainWindow.h index c2387ae..f18d94d 100644 --- a/src/menu/MainWindow.h +++ b/src/menu/MainWindow.h @@ -22,6 +22,7 @@ #include #include "game/GameList.h" #include "system/CMutex.h" +#include "KeyboardHelper.h" #include "gui/GuiTitleBrowser.h" #include "MainDrcButtonsFrame.h" @@ -123,6 +124,7 @@ private: void OnSettingsButtonClicked(GuiElement *element); void OnLayoutSwitchClicked(GuiElement *element); void OnLayoutSwitchEffectFinish(GuiElement *element); + void OnGameListFilterButtonClicked(GuiElement *element); void OnGameTitleListChanged(GameList * list); void OnGameTitleUpdated(gameInfo * info); @@ -146,6 +148,7 @@ private: GameList gameList; CMutex guiMutex; + KeyboardHelper * keyboardInstance = NULL; }; #endif //_MAIN_WINDOW_H_