diff --git a/CMakeLists.txt b/CMakeLists.txt index 587e39d6df..14878ec6d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1368,6 +1368,8 @@ list(APPEND NativeAppSource UI/MiscScreens.cpp UI/PauseScreen.h UI/PauseScreen.cpp + UI/TabbedDialogScreen.h + UI/TabbedDialogScreen.cpp UI/GameScreen.h UI/GameScreen.cpp UI/GameSettingsScreen.h diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 817e8ee7d1..b3f7f13e4b 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -95,7 +95,7 @@ extern AndroidAudioState *g_audioState; #endif GameSettingsScreen::GameSettingsScreen(const Path &gamePath, std::string gameID, bool editThenRestore) - : UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), editThenRestore_(editThenRestore) { + : TabbedUIDialogScreenWithGameBackground(gamePath), gameID_(gameID), editThenRestore_(editThenRestore) { prevInflightFrames_ = g_Config.iInflightFrames; analogSpeedMapped_ = KeyMap::InputMappingsFromPspButton(VIRTKEY_SPEED_ANALOG, nullptr, true); } @@ -191,7 +191,7 @@ static std::string PostShaderTranslateName(const char *value) { } } -void GameSettingsScreen::CreateViews() { +void GameSettingsScreen::PreCreateViews() { ReloadAllPostShaderInfo(screenManager()->getDrawContext()); ReloadAllThemeInfo(); @@ -203,49 +203,11 @@ void GameSettingsScreen::CreateViews() { iAlternateSpeedPercent1_ = g_Config.iFpsLimit1 < 0 ? -1 : (g_Config.iFpsLimit1 * 100) / 60; iAlternateSpeedPercent2_ = g_Config.iFpsLimit2 < 0 ? -1 : (g_Config.iFpsLimit2 * 100) / 60; iAlternateSpeedPercentAnalog_ = (g_Config.iAnalogFpsLimit * 100) / 60; +} - bool vertical = UseVerticalLayout(); - - // Information in the top left. - // Back button to the bottom left. - // Scrolling action menu to the right. +void GameSettingsScreen::CreateTabs() { using namespace UI; - auto ms = GetI18NCategory(I18NCat::MAINSETTINGS); - auto di = GetI18NCategory(I18NCat::DIALOG); - - root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); - - if (vertical) { - LinearLayout *verticalLayout = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)); - tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 200, new LinearLayoutParams(1.0f)); - verticalLayout->Add(tabHolder_); - verticalLayout->Add(new Choice(di->T("Back"), "", false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0))))->OnClick.Handle(this, &UIScreen::OnBack); - root_->Add(verticalLayout); - } else { - tabHolder_ = new TabHolder(ORIENT_VERTICAL, 200, new AnchorLayoutParams(10, 0, 10, 0, false)); - root_->Add(tabHolder_); - AddStandardBack(root_); - } - tabHolder_->SetTag("GameSettings"); - root_->SetDefaultFocusView(tabHolder_); - settingTabContents_.clear(); - settingTabFilterNotices_.clear(); - - float leftSide = 40.0f; - if (!vertical) { - leftSide += 200.0f; - } - settingInfo_ = new SettingInfoMessage(ALIGN_CENTER | FLAG_WRAP_TEXT, new AnchorLayoutParams( - g_display.dp_xres - leftSide - 40.0f, WRAP_CONTENT, - leftSide, g_display.dp_yres - 80.0f - 40.0f, NONE, NONE)); - settingInfo_->SetBottomCutoff(g_display.dp_yres - 200.0f); - root_->Add(settingInfo_); - - // Show it again if we recreated the view - if (!oldSettingInfo_.empty()) { - settingInfo_->Show(oldSettingInfo_, nullptr); - } LinearLayout *graphicsSettings = AddTab("GameSettingsGraphics", ms->T("Graphics")); CreateGraphicsSettings(graphicsSettings); @@ -271,27 +233,6 @@ void GameSettingsScreen::CreateViews() { LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR")); CreateVRSettings(vrSettings); } - -#if !defined(MOBILE_DEVICE) || PPSSPP_PLATFORM(ANDROID) - // Hide search if screen is too small. - if ((g_display.dp_xres < g_display.dp_yres || g_display.dp_yres >= 500) && (deviceType != DEVICE_TYPE_VR)) { - auto se = GetI18NCategory(I18NCat::SEARCH); - // Search - LinearLayout *searchSettings = AddTab("GameSettingsSearch", ms->T("Search"), true); - - searchSettings->Add(new ItemHeader(se->T("Find settings"))); - if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { - searchSettings->Add(new ChoiceWithValueDisplay(&searchFilter_, se->T("Filter"), I18NCat::NONE))->OnClick.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); - } else { - searchSettings->Add(new PopupTextInputChoice(&searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Handle(this, &GameSettingsScreen::OnChangeSearchFilter); - } - clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter"))); - clearSearchChoice_->OnClick.Handle(this, &GameSettingsScreen::OnClearSearchFilter); - noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5)))); - - ApplySearchFilter(); - } -#endif } // Graphics @@ -1174,29 +1115,6 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) { vrSettings->Add(new PopupMultiChoice(&g_Config.iCameraPitch, vr->T("Camera type"), cameraPitchModes, 0, 3, I18NCat::NONE, screenManager())); } -UI::LinearLayout *GameSettingsScreen::AddTab(const char *tag, const std::string &title, bool isSearch) { - auto se = GetI18NCategory(I18NCat::SEARCH); - - using namespace UI; - ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); - scroll->SetTag(tag); - - LinearLayout *contents = new LinearLayoutList(ORIENT_VERTICAL); - contents->SetSpacing(0); - scroll->Add(contents); - tabHolder_->AddTab(title, scroll); - - if (!isSearch) { - settingTabContents_.push_back(contents); - - auto notice = contents->Add(new TextView(se->T("Filtering settings by '%1'"), new LinearLayoutParams(Margins(20, 5)))); - notice->SetVisibility(V_GONE); - settingTabFilterNotices_.push_back(notice); - } - - return contents; -} - UI::EventReturn GameSettingsScreen::OnAutoFrameskip(UI::EventParams &e) { g_Config.UpdateAfterSettingAutoFrameSkip(); return UI::EVENT_DONE; @@ -1378,54 +1296,6 @@ void GameSettingsScreen::onFinish(DialogResult result) { NativeMessageReceived("gpu_configChanged", ""); } -void GameSettingsScreen::sendMessage(const char *message, const char *value) { - UIDialogScreenWithGameBackground::sendMessage(message, value); - if (!strcmp(message, "gameSettings_search")) { - std::string filter = value ? value : ""; - searchFilter_.resize(filter.size()); - std::transform(filter.begin(), filter.end(), searchFilter_.begin(), tolower); - - ApplySearchFilter(); - } -} - -void GameSettingsScreen::ApplySearchFilter() { - auto se = GetI18NCategory(I18NCat::SEARCH); - - bool matches = searchFilter_.empty(); - for (int t = 0; t < (int)settingTabContents_.size(); ++t) { - auto tabContents = settingTabContents_[t]; - bool tabMatches = searchFilter_.empty(); - - // Show an indicator that a filter is applied. - settingTabFilterNotices_[t]->SetVisibility(tabMatches ? UI::V_GONE : UI::V_VISIBLE); - settingTabFilterNotices_[t]->SetText(ReplaceAll(se->T("Filtering settings by '%1'"), "%1", searchFilter_)); - - UI::View *lastHeading = nullptr; - for (int i = 1; i < tabContents->GetNumSubviews(); ++i) { - UI::View *v = tabContents->GetViewByIndex(i); - if (!v->CanBeFocused()) { - lastHeading = v; - } - - std::string label = v->DescribeText(); - std::transform(label.begin(), label.end(), label.begin(), tolower); - bool match = v->CanBeFocused() && label.find(searchFilter_) != label.npos; - tabMatches = tabMatches || match; - - if (match && lastHeading) - lastHeading->SetVisibility(UI::V_VISIBLE); - v->SetVisibility(searchFilter_.empty() || match ? UI::V_VISIBLE : UI::V_GONE); - } - tabHolder_->EnableTab(t, tabMatches); - matches = matches || tabMatches; - } - - noSearchResults_->SetText(ReplaceAll(se->T("No settings matched '%1'"), "%1", searchFilter_)); - noSearchResults_->SetVisibility(matches ? UI::V_GONE : UI::V_VISIBLE); - clearSearchChoice_->SetVisibility(searchFilter_.empty() ? UI::V_GONE : UI::V_VISIBLE); -} - void GameSettingsScreen::dialogFinished(const Screen *dialog, DialogResult result) { if (result == DialogResult::DR_OK) { g_Config.iFpsLimit1 = iAlternateSpeedPercent1_ < 0 ? -1 : (iAlternateSpeedPercent1_ * 60) / 100; @@ -1442,11 +1312,6 @@ void GameSettingsScreen::dialogFinished(const Screen *dialog, DialogResult resul } } -void GameSettingsScreen::RecreateViews() { - oldSettingInfo_ = settingInfo_ ? settingInfo_->GetText() : "N/A"; - UIScreen::RecreateViews(); -} - void GameSettingsScreen::CallbackMemstickFolder(bool yes) { auto sy = GetI18NCategory(I18NCat::SYSTEM); @@ -1721,24 +1586,6 @@ UI::EventReturn GameSettingsScreen::OnSysInfo(UI::EventParams &e) { return UI::EVENT_DONE; } -UI::EventReturn GameSettingsScreen::OnChangeSearchFilter(UI::EventParams &e) { -#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__) - auto se = GetI18NCategory(I18NCat::SEARCH); - System_InputBoxGetString(se->T("Search term"), searchFilter_, [](const std::string &value, int) { - NativeMessageReceived("gameSettings_search", StripSpaces(value).c_str()); - }); -#else - if (!System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) - NativeMessageReceived("gameSettings_search", StripSpaces(searchFilter_).c_str()); -#endif - return UI::EVENT_DONE; -} - -UI::EventReturn GameSettingsScreen::OnClearSearchFilter(UI::EventParams &e) { - NativeMessageReceived("gameSettings_search", ""); - return UI::EVENT_DONE; -} - void DeveloperToolsScreen::CreateViews() { using namespace UI; root_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)); diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index a5c20c50c4..97a31234ff 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -25,10 +25,11 @@ #include "Common/UI/UIScreen.h" #include "Core/ConfigValues.h" #include "UI/MiscScreens.h" +#include "UI/TabbedDialogScreen.h" // Per-game settings screen - enables you to configure graphic options, control options, etc // per game. -class GameSettingsScreen : public UIDialogScreenWithGameBackground { +class GameSettingsScreen : public TabbedUIDialogScreenWithGameBackground { public: GameSettingsScreen(const Path &gamePath, std::string gameID = "", bool editThenRestore = false); @@ -36,17 +37,18 @@ public: const char *tag() const override { return "GameSettings"; } protected: - void sendMessage(const char *message, const char *value) override; - void CreateViews() override; void CallbackRestoreDefaults(bool yes); void CallbackRenderingBackend(bool yes); void CallbackRenderingDevice(bool yes); void CallbackInflightFrames(bool yes); void CallbackMemstickFolder(bool yes); void dialogFinished(const Screen *dialog, DialogResult result) override; - void RecreateViews() override; + + void CreateTabs() override; private: + void PreCreateViews() override; + void CreateGraphicsSettings(UI::ViewGroup *graphicsSettings); void CreateControlsSettings(UI::ViewGroup *tools); void CreateAudioSettings(UI::ViewGroup *audioSettings); @@ -55,8 +57,6 @@ private: void CreateSystemSettings(UI::ViewGroup *systemSettings); void CreateVRSettings(UI::ViewGroup *vrSettings); - UI::LinearLayout *AddTab(const char *tag, const std::string &title, bool isSearch = false); - void ApplySearchFilter(); void TriggerRestart(const char *why); std::string gameID_; @@ -66,9 +66,6 @@ private: UI::Choice *backgroundChoice_ = nullptr; UI::PopupMultiChoice *resolutionChoice_ = nullptr; UI::CheckBox *frameSkipAuto_ = nullptr; - SettingInfoMessage *settingInfo_ = nullptr; - UI::Choice *clearSearchChoice_ = nullptr; - UI::TextView *noSearchResults_ = nullptr; #ifdef _WIN32 UI::CheckBox *SavePathInMyDocumentChoice = nullptr; UI::CheckBox *SavePathInOtherChoice = nullptr; @@ -79,10 +76,6 @@ private: std::string memstickDisplay_; - UI::TabHolder *tabHolder_ = nullptr; - std::vector settingTabContents_; - std::vector settingTabFilterNotices_; - // Event handlers UI::EventReturn OnControlMapping(UI::EventParams &e); UI::EventReturn OnCalibrateAnalogs(UI::EventParams &e); @@ -131,8 +124,6 @@ private: UI::EventReturn OnSavedataManager(UI::EventParams &e); UI::EventReturn OnSysInfo(UI::EventParams &e); - UI::EventReturn OnChangeSearchFilter(UI::EventParams &e); - UI::EventReturn OnClearSearchFilter(UI::EventParams &e); // Temporaries to convert setting types, cache enabled, etc. int iAlternateSpeedPercent1_ = 0; @@ -143,16 +134,11 @@ private: bool enableReportsSet_ = false; bool analogSpeedMapped_ = false; - std::string searchFilter_; - // edit the game-specific settings and restore the global settings after exiting bool editThenRestore_ = false; // Android-only std::string pendingMemstickFolder_; - - // If we recreate the views while this is active we show it again - std::string oldSettingInfo_; }; class DeveloperToolsScreen : public UIDialogScreenWithGameBackground { diff --git a/UI/TabbedDialogScreen.cpp b/UI/TabbedDialogScreen.cpp new file mode 100644 index 0000000000..72b541ca6d --- /dev/null +++ b/UI/TabbedDialogScreen.cpp @@ -0,0 +1,173 @@ +#include + +#include "Common/StringUtils.h" +#include "Common/System/NativeApp.h" +#include "Common/System/Request.h" +#include "Common/System/Display.h" +#include "UI/TabbedDialogScreen.h" + +UI::LinearLayout *TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag, const std::string &title, bool isSearch) { + auto se = GetI18NCategory(I18NCat::SEARCH); + + using namespace UI; + ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); + scroll->SetTag(tag); + + LinearLayout *contents = new LinearLayoutList(ORIENT_VERTICAL); + contents->SetSpacing(0); + scroll->Add(contents); + tabHolder_->AddTab(title, scroll); + + if (!isSearch) { + settingTabContents_.push_back(contents); + + auto notice = contents->Add(new TextView(se->T("Filtering settings by '%1'"), new LinearLayoutParams(Margins(20, 5)))); + notice->SetVisibility(V_GONE); + settingTabFilterNotices_.push_back(notice); + } + + return contents; +} + +void TabbedUIDialogScreenWithGameBackground::CreateViews() { + PreCreateViews(); + + bool vertical = UseVerticalLayout(); + + // Information in the top left. + // Back button to the bottom left. + // Scrolling action menu to the right. + using namespace UI; + + auto ms = GetI18NCategory(I18NCat::MAINSETTINGS); + auto di = GetI18NCategory(I18NCat::DIALOG); + + root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); + + if (vertical) { + LinearLayout *verticalLayout = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)); + tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 200, new LinearLayoutParams(1.0f)); + verticalLayout->Add(tabHolder_); + verticalLayout->Add(new Choice(di->T("Back"), "", false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0))))->OnClick.Handle(this, &UIScreen::OnBack); + root_->Add(verticalLayout); + } else { + tabHolder_ = new TabHolder(ORIENT_VERTICAL, 200, new AnchorLayoutParams(10, 0, 10, 0, false)); + root_->Add(tabHolder_); + AddStandardBack(root_); + } + tabHolder_->SetTag("GameSettings"); + root_->SetDefaultFocusView(tabHolder_); + settingTabContents_.clear(); + settingTabFilterNotices_.clear(); + + float leftSide = 40.0f; + if (!vertical) { + leftSide += 200.0f; + } + settingInfo_ = new SettingInfoMessage(ALIGN_CENTER | FLAG_WRAP_TEXT, new AnchorLayoutParams( + g_display.dp_xres - leftSide - 40.0f, WRAP_CONTENT, + leftSide, g_display.dp_yres - 80.0f - 40.0f, NONE, NONE)); + settingInfo_->SetBottomCutoff(g_display.dp_yres - 200.0f); + root_->Add(settingInfo_); + + // Show it again if we recreated the view + if (!oldSettingInfo_.empty()) { + settingInfo_->Show(oldSettingInfo_, nullptr); + } + + // Let the subclass create its tabs. + CreateTabs(); + +#if !defined(MOBILE_DEVICE) || PPSSPP_PLATFORM(ANDROID) + // Hide search if screen is too small. + int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE); + if ((g_display.dp_xres < g_display.dp_yres || g_display.dp_yres >= 500) && (deviceType != DEVICE_TYPE_VR)) { + auto se = GetI18NCategory(I18NCat::SEARCH); + // Search + LinearLayout *searchSettings = AddTab("GameSettingsSearch", ms->T("Search"), true); + + searchSettings->Add(new ItemHeader(se->T("Find settings"))); + if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { + searchSettings->Add(new ChoiceWithValueDisplay(&searchFilter_, se->T("Filter"), I18NCat::NONE))->OnClick.Handle(this, &TabbedUIDialogScreenWithGameBackground::OnChangeSearchFilter); + } else { + searchSettings->Add(new PopupTextInputChoice(&searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Handle(this, &TabbedUIDialogScreenWithGameBackground::OnChangeSearchFilter); + } + clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter"))); + clearSearchChoice_->OnClick.Handle(this, &TabbedUIDialogScreenWithGameBackground::OnClearSearchFilter); + noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5)))); + + ApplySearchFilter(); + } +#endif +} + +void TabbedUIDialogScreenWithGameBackground::sendMessage(const char *message, const char *value) { + UIDialogScreenWithGameBackground::sendMessage(message, value); + if (!strcmp(message, "gameSettings_search")) { + std::string filter = value ? value : ""; + searchFilter_.resize(filter.size()); + std::transform(filter.begin(), filter.end(), searchFilter_.begin(), tolower); + + ApplySearchFilter(); + } +} + +void TabbedUIDialogScreenWithGameBackground::RecreateViews() { + oldSettingInfo_ = settingInfo_ ? settingInfo_->GetText() : "N/A"; + UIScreen::RecreateViews(); +} + +void TabbedUIDialogScreenWithGameBackground::ApplySearchFilter() { + auto se = GetI18NCategory(I18NCat::SEARCH); + + bool matches = searchFilter_.empty(); + for (int t = 0; t < (int)settingTabContents_.size(); ++t) { + auto tabContents = settingTabContents_[t]; + bool tabMatches = searchFilter_.empty(); + + // Show an indicator that a filter is applied. + settingTabFilterNotices_[t]->SetVisibility(tabMatches ? UI::V_GONE : UI::V_VISIBLE); + settingTabFilterNotices_[t]->SetText(ReplaceAll(se->T("Filtering settings by '%1'"), "%1", searchFilter_)); + + UI::View *lastHeading = nullptr; + for (int i = 1; i < tabContents->GetNumSubviews(); ++i) { + UI::View *v = tabContents->GetViewByIndex(i); + if (!v->CanBeFocused()) { + lastHeading = v; + } + + std::string label = v->DescribeText(); + std::transform(label.begin(), label.end(), label.begin(), tolower); + bool match = v->CanBeFocused() && label.find(searchFilter_) != label.npos; + tabMatches = tabMatches || match; + + if (match && lastHeading) + lastHeading->SetVisibility(UI::V_VISIBLE); + v->SetVisibility(searchFilter_.empty() || match ? UI::V_VISIBLE : UI::V_GONE); + } + tabHolder_->EnableTab(t, tabMatches); + matches = matches || tabMatches; + } + + noSearchResults_->SetText(ReplaceAll(se->T("No settings matched '%1'"), "%1", searchFilter_)); + noSearchResults_->SetVisibility(matches ? UI::V_GONE : UI::V_VISIBLE); + clearSearchChoice_->SetVisibility(searchFilter_.empty() ? UI::V_GONE : UI::V_VISIBLE); +} + +UI::EventReturn TabbedUIDialogScreenWithGameBackground::OnChangeSearchFilter(UI::EventParams &e) { +#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__) + auto se = GetI18NCategory(I18NCat::SEARCH); + System_InputBoxGetString(se->T("Search term"), searchFilter_, [](const std::string &value, int) { + NativeMessageReceived("gameSettings_search", StripSpaces(value).c_str()); + }); +#else + if (!System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) + NativeMessageReceived("gameSettings_search", StripSpaces(searchFilter_).c_str()); +#endif + return UI::EVENT_DONE; +} + +UI::EventReturn TabbedUIDialogScreenWithGameBackground::OnClearSearchFilter(UI::EventParams &e) { + NativeMessageReceived("gameSettings_search", ""); + return UI::EVENT_DONE; +} diff --git a/UI/TabbedDialogScreen.h b/UI/TabbedDialogScreen.h new file mode 100644 index 0000000000..ef24c2c085 --- /dev/null +++ b/UI/TabbedDialogScreen.h @@ -0,0 +1,39 @@ +#pragma once + +#include "ppsspp_config.h" + +#include "Common/UI/UIScreen.h" +#include "Core/ConfigValues.h" +#include "UI/MiscScreens.h" + +class TabbedUIDialogScreenWithGameBackground : public UIDialogScreenWithGameBackground { +public: + TabbedUIDialogScreenWithGameBackground(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {} + + UI::LinearLayout *AddTab(const char *tag, const std::string &title, bool isSearch = false); + void CreateViews() override; + + +protected: + // Load data and define your tabs here. + virtual void PreCreateViews() {} + virtual void CreateTabs() {}; + void RecreateViews() override; + + UI::EventReturn OnChangeSearchFilter(UI::EventParams &e); + UI::EventReturn OnClearSearchFilter(UI::EventParams &e); + SettingInfoMessage *settingInfo_ = nullptr; + +private: + void sendMessage(const char *message, const char *value) override; + void ApplySearchFilter(); + + UI::TabHolder *tabHolder_ = nullptr; + std::vector settingTabContents_; + std::vector settingTabFilterNotices_; + UI::Choice *clearSearchChoice_ = nullptr; + UI::TextView *noSearchResults_ = nullptr; + // If we recreate the views while this is active we show it again + std::string oldSettingInfo_; + std::string searchFilter_; +}; diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index d7286261b2..ccf71e8f91 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -62,6 +62,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 120b04c9d3..049f31c217 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -83,6 +83,9 @@ Screens + + Screens + @@ -166,6 +169,9 @@ Screens + + Screens + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index e9054bb141..b911519463 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -294,6 +294,7 @@ + @@ -329,6 +330,7 @@ + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj.filters b/UWP/UI_UWP/UI_UWP.vcxproj.filters index 56716f7b53..d0d4d113f4 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj.filters +++ b/UWP/UI_UWP/UI_UWP.vcxproj.filters @@ -34,6 +34,7 @@ + @@ -69,5 +70,6 @@ + \ No newline at end of file diff --git a/android/jni/Android.mk b/android/jni/Android.mk index f28625f35b..d5c6ca3cef 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -727,6 +727,7 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/DisplayLayoutScreen.cpp \ $(SRC)/UI/EmuScreen.cpp \ $(SRC)/UI/MainScreen.cpp \ + $(SRC)/UI/TabbedDialogScreen.cpp \ $(SRC)/UI/MemStickScreen.cpp \ $(SRC)/UI/MiscScreens.cpp \ $(SRC)/UI/RemoteISOScreen.cpp \