CHange the TabbedDialog create-tab API to allow for future lazy-loading

This commit is contained in:
Henrik Rydgård 2025-03-21 13:31:37 +01:00
parent 4b977b43c2
commit 6efb758893
12 changed files with 249 additions and 145 deletions

View file

@ -523,9 +523,44 @@ void SystemInfoScreen::CreateTabs() {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
LinearLayout *deviceSpecs = AddTab("Device Info", si->T("Device Info"));
AddTab("Device Info", si->T("Device Info"), [this](UI::LinearLayout *parent) {
CreateDeviceInfoTab(parent);
});
AddTab("Storage", si->T("Storage"), [this](UI::LinearLayout *parent) {
CreateStorageTab(parent);
});
AddTab("DevSystemInfoBuildConfig", si->T("Build Config"), [this](UI::LinearLayout *parent) {
CreateBuildConfigTab(parent);
});
AddTab("DevSystemInfoCPUExt", si->T("CPU Extensions"), [this](UI::LinearLayout *parent) {
CreateCPUExtensionsTab(parent);
});
if (GetGPUBackend() == GPUBackend::OPENGL) {
AddTab("DevSystemInfoOGLExt", si->T("OGL Extensions"), [this](UI::LinearLayout *parent) {
CreateOpenGLExtsTab(parent);
});
} else if (GetGPUBackend() == GPUBackend::VULKAN) {
AddTab("DevSystemInfoVulkanExt", si->T("Vulkan Extensions"), [this](UI::LinearLayout *parent) {
CreateVulkanExtsTab(parent);
});
}
AddTab("DevSystemInfoDriverBugs", si->T("Driver bugs"), [this](UI::LinearLayout *parent) {
CreateDriverBugsTab(parent);
});
AddTab("DevSystemInfoInternals", si->T("Internals"), [this](UI::LinearLayout *parent) {
CreateInternalsTab(parent);
});
}
CollapsibleSection *systemInfo = deviceSpecs->Add(new CollapsibleSection(si->T("System Information")));
void SystemInfoScreen::CreateDeviceInfoTab(UI::LinearLayout *deviceSpecs) {
using namespace Draw;
using namespace UI;
auto di = GetI18NCategory(I18NCat::DIALOG);
auto si = GetI18NCategory(I18NCat::SYSINFO);
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
UI::CollapsibleSection *systemInfo = deviceSpecs->Add(new UI::CollapsibleSection(si->T("System Information")));
systemInfo->Add(new Choice(si->T("Copy summary to clipboard")))->OnClick.Handle(this, &SystemInfoScreen::CopySummaryToClipboard);
systemInfo->Add(new InfoItem(si->T("System Name", "Name"), System_GetProperty(SYSPROP_NAME)));
@ -546,7 +581,7 @@ void SystemInfoScreen::CreateTabs() {
systemInfo->Add(new InfoItem(si->T("Debugger Present"), di->T("Yes")));
}
CollapsibleSection *cpuInfo = deviceSpecs->Add(new CollapsibleSection(si->T("CPU Information")));
UI::CollapsibleSection *cpuInfo = deviceSpecs->Add(new UI::CollapsibleSection(si->T("CPU Information")));
// Don't bother showing the CPU name if we don't have one.
if (strcmp(cpu_info.brand_string, "Unknown") != 0) {
@ -721,8 +756,12 @@ void SystemInfoScreen::CreateTabs() {
}
}
}
}
LinearLayout *storage = AddTab("Storage", si->T("Storage"));
void SystemInfoScreen::CreateStorageTab(UI::LinearLayout *storage) {
using namespace UI;
auto si = GetI18NCategory(I18NCat::SYSINFO);
storage->Add(new ItemHeader(si->T("Directories")));
// Intentionally non-translated
@ -740,8 +779,12 @@ void SystemInfoScreen::CreateTabs() {
storage->Add(new InfoItem("IsStoragePreservedLegacy", Android_IsExternalStoragePreservedLegacy() ? di->T("Yes") : di->T("No")));
}
#endif
}
LinearLayout *buildConfig = AddTab("DevSystemInfoBuildConfig", si->T("Build Config"));
void SystemInfoScreen::CreateBuildConfigTab(UI::LinearLayout *buildConfig) {
using namespace UI;
auto si = GetI18NCategory(I18NCat::SYSINFO);
buildConfig->Add(new ItemHeader(si->T("Build Configuration")));
#ifdef ANDROID_LEGACY
@ -773,17 +816,28 @@ void SystemInfoScreen::CreateTabs() {
if (System_GetPropertyBool(SYSPROP_APP_GOLD)) {
buildConfig->Add(new InfoItem("GOLD", ""));
}
}
void SystemInfoScreen::CreateCPUExtensionsTab(UI::LinearLayout *cpuExtensions) {
using namespace UI;
auto si = GetI18NCategory(I18NCat::SYSINFO);
LinearLayout *cpuExtensions = AddTab("DevSystemInfoCPUExt", si->T("CPU Extensions"));
cpuExtensions->Add(new ItemHeader(si->T("CPU Extensions")));
std::vector<std::string> exts = cpu_info.Features();
for (std::string &ext : exts) {
cpuExtensions->Add(new TextView(ext, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
}
LinearLayout *driverBugs = AddTab("DevSystemInfoDriverBugs", si->T("Driver bugs"));
void SystemInfoScreen::CreateDriverBugsTab(UI::LinearLayout *driverBugs) {
using namespace UI;
using namespace Draw;
auto si = GetI18NCategory(I18NCat::SYSINFO);
bool anyDriverBugs = false;
Draw::DrawContext *draw = screenManager()->getDrawContext();
for (int i = 0; i < (int)draw->GetBugs().MaxBugIndex(); i++) {
if (draw->GetBugs().Has(i)) {
anyDriverBugs = true;
@ -794,90 +848,92 @@ void SystemInfoScreen::CreateTabs() {
if (!anyDriverBugs) {
driverBugs->Add(new TextView(si->T("No GPU driver bugs detected"), new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
}
if (GetGPUBackend() == GPUBackend::OPENGL) {
LinearLayout *gpuExtensions = AddTab("DevSystemInfoOGLExt", si->T("OGL Extensions"));
void SystemInfoScreen::CreateOpenGLExtsTab(UI::LinearLayout *gpuExtensions) {
using namespace UI;
if (!gl_extensions.IsGLES) {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL Extensions")));
} else if (gl_extensions.GLES3) {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL ES 3.0 Extensions")));
} else {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL ES 2.0 Extensions")));
}
exts.clear();
SplitString(g_all_gl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end());
for (auto &extension : exts) {
gpuExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
auto si = GetI18NCategory(I18NCat::SYSINFO);
Draw::DrawContext *draw = screenManager()->getDrawContext();
exts.clear();
SplitString(g_all_egl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end());
// If there aren't any EGL extensions, no need to show the tab.
if (exts.size() > 0) {
LinearLayout *eglExtensions = AddTab("EglExt", si->T("EGL Extensions"));
eglExtensions->SetSpacing(0);
eglExtensions->Add(new ItemHeader(si->T("EGL Extensions")));
for (auto &extension : exts) {
eglExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
}
} else if (GetGPUBackend() == GPUBackend::VULKAN) {
LinearLayout *gpuExtensions = AddTab("DevSystemInfoOGLExt", si->T("Vulkan Features"));
CollapsibleSection *vulkanFeatures = gpuExtensions->Add(new CollapsibleSection(si->T("Vulkan Features")));
std::vector<std::string> features = draw->GetFeatureList();
for (auto &feature : features) {
vulkanFeatures->Add(new TextView(feature, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *presentModes = gpuExtensions->Add(new CollapsibleSection(si->T("Present modes")));
for (auto mode : draw->GetPresentModeList(di->T("Current"))) {
presentModes->Add(new TextView(mode, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *colorFormats = gpuExtensions->Add(new CollapsibleSection(si->T("Display Color Formats")));
for (auto &format : draw->GetSurfaceFormatList()) {
colorFormats->Add(new TextView(format, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *enabledExtensions = gpuExtensions->Add(new CollapsibleSection(std::string(si->T("Vulkan Extensions")) + " (" + std::string(di->T("Enabled")) + ")"));
std::vector<std::string> extensions = draw->GetExtensionList(true, true);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
enabledExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
// Also get instance extensions
enabledExtensions->Add(new ItemHeader(si->T("Instance")));
extensions = draw->GetExtensionList(false, true);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
enabledExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *vulkanExtensions = gpuExtensions->Add(new CollapsibleSection(si->T("Vulkan Extensions")));
extensions = draw->GetExtensionList(true, false);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
vulkanExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
vulkanExtensions->Add(new ItemHeader(si->T("Instance")));
// Also get instance extensions
extensions = draw->GetExtensionList(false, false);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
vulkanExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
if (!gl_extensions.IsGLES) {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL Extensions")));
} else if (gl_extensions.GLES3) {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL ES 3.0 Extensions")));
} else {
gpuExtensions->Add(new ItemHeader(si->T("OpenGL ES 2.0 Extensions")));
}
#ifdef _DEBUG
LinearLayout *internals = AddTab("DevSystemInfoInternals", si->T("Internals"));
CreateInternalsTab(internals);
#endif
std::vector<std::string> exts;
SplitString(g_all_gl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end());
for (auto &extension : exts) {
gpuExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
exts.clear();
SplitString(g_all_egl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end());
// If there aren't any EGL extensions, no need to show the tab.
gpuExtensions->Add(new ItemHeader(si->T("EGL Extensions")));
for (auto &extension : exts) {
gpuExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
}
void SystemInfoScreen::CreateVulkanExtsTab(UI::LinearLayout *gpuExtensions) {
using namespace UI;
auto si = GetI18NCategory(I18NCat::SYSINFO);
auto di = GetI18NCategory(I18NCat::DIALOG);
Draw::DrawContext *draw = screenManager()->getDrawContext();
CollapsibleSection *vulkanFeatures = gpuExtensions->Add(new CollapsibleSection(si->T("Vulkan Features")));
std::vector<std::string> features = draw->GetFeatureList();
for (const auto &feature : features) {
vulkanFeatures->Add(new TextView(feature, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *presentModes = gpuExtensions->Add(new CollapsibleSection(si->T("Present modes")));
for (const auto &mode : draw->GetPresentModeList(di->T("Current"))) {
presentModes->Add(new TextView(mode, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *colorFormats = gpuExtensions->Add(new CollapsibleSection(si->T("Display Color Formats")));
for (const auto &format : draw->GetSurfaceFormatList()) {
colorFormats->Add(new TextView(format, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *enabledExtensions = gpuExtensions->Add(new CollapsibleSection(std::string(si->T("Vulkan Extensions")) + " (" + std::string(di->T("Enabled")) + ")"));
std::vector<std::string> extensions = draw->GetExtensionList(true, true);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
enabledExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
// Also get instance extensions
enabledExtensions->Add(new ItemHeader(si->T("Instance")));
extensions = draw->GetExtensionList(false, true);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
enabledExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
CollapsibleSection *vulkanExtensions = gpuExtensions->Add(new CollapsibleSection(si->T("Vulkan Extensions")));
extensions = draw->GetExtensionList(true, false);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
vulkanExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
vulkanExtensions->Add(new ItemHeader(si->T("Instance")));
// Also get instance extensions
extensions = draw->GetExtensionList(false, false);
std::sort(extensions.begin(), extensions.end());
for (auto &extension : extensions) {
vulkanExtensions->Add(new TextView(extension, new LayoutParams(FILL_PARENT, WRAP_CONTENT)))->SetFocusable(true);
}
}
void SystemInfoScreen::CreateInternalsTab(UI::ViewGroup *internals) {

View file

@ -115,7 +115,17 @@ public:
protected:
UI::EventReturn CopySummaryToClipboard(UI::EventParams &e);
bool ShowSearchControls() const override { return false; }
private:
void CreateDeviceInfoTab(UI::LinearLayout *deviceInfo);
void CreateStorageTab(UI::LinearLayout *storage);
void CreateBuildConfigTab(UI::LinearLayout *storage);
void CreateCPUExtensionsTab(UI::LinearLayout *storage);
void CreateDriverBugsTab(UI::LinearLayout *storage);
void CreateInternalsTab(UI::ViewGroup *internals);
void CreateOpenGLExtsTab(UI::LinearLayout *gpuExtensions);
void CreateVulkanExtsTab(UI::LinearLayout *gpuExtensions);
};
class GPIGPOScreen : public PopupScreen {

View file

@ -152,8 +152,9 @@ void DriverManagerScreen::CreateTabs() {
using namespace UI;
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
LinearLayout *drivers = AddTab("DriverManagerDrivers", gr->T("Drivers"));
CreateDriverTab(drivers);
AddTab("DriverManagerDrivers", gr->T("Drivers"), [this](UI::LinearLayout *parent) {
CreateDriverTab(parent);
});
}
void DriverManagerScreen::CreateDriverTab(UI::ViewGroup *drivers) {

View file

@ -212,10 +212,6 @@ EmuScreen::EmuScreen(const Path &filename)
// Usually, we don't want focus movement enabled on this screen, so disable on start.
// Only if you open chat or dev tools do we want it to start working.
UI::EnableFocusMovement(false);
// TODO: Do this only on demand.
IMGUI_CHECKVERSION();
ImGui::CreateContext();
}
bool EmuScreen::bootAllowStorage(const Path &filename) {
@ -460,7 +456,7 @@ void EmuScreen::bootComplete() {
EmuScreen::~EmuScreen() {
if (imguiInited_) {
ImGui_ImplThin3d_Shutdown();
ImGui::DestroyContext();
ImGui::DestroyContext(ctx_);
}
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
@ -1770,6 +1766,11 @@ void EmuScreen::runImDebugger() {
Draw::DrawContext *draw = screenManager()->getDrawContext();
if (!imguiInited_) {
imguiInited_ = true;
// TODO: Do this only on demand.
IMGUI_CHECKVERSION();
ctx_ = ImGui::CreateContext();
ImGui_ImplPlatform_Init(GetSysDirectory(DIRECTORY_SYSTEM) / "imgui.ini");
imDebugger_ = std::make_unique<ImDebugger>();

View file

@ -154,6 +154,8 @@ private:
bool lastImguiEnabled_ = false;
std::vector<VirtKey> queuedVirtKeys_;
ImGuiContext *ctx_ = nullptr;
};
bool MustRunBehind();

View file

@ -250,29 +250,37 @@ void GameSettingsScreen::CreateTabs() {
using namespace UI;
auto ms = GetI18NCategory(I18NCat::MAINSETTINGS);
LinearLayout *graphicsSettings = AddTab("GameSettingsGraphics", ms->T("Graphics"));
CreateGraphicsSettings(graphicsSettings);
AddTab("GameSettingsGraphics", ms->T("Graphics"), [this](UI::LinearLayout *parent) {
CreateGraphicsSettings(parent);
});
LinearLayout *controlsSettings = AddTab("GameSettingsControls", ms->T("Controls"));
CreateControlsSettings(controlsSettings);
AddTab("GameSettingsControls", ms->T("Controls"), [this](UI::LinearLayout *parent) {
CreateControlsSettings(parent);
});
LinearLayout *audioSettings = AddTab("GameSettingsAudio", ms->T("Audio"));
CreateAudioSettings(audioSettings);
AddTab("GameSettingsAudio", ms->T("Audio"), [this](UI::LinearLayout *parent) {
CreateAudioSettings(parent);
});
LinearLayout *networkingSettings = AddTab("GameSettingsNetworking", ms->T("Networking"));
CreateNetworkingSettings(networkingSettings);
AddTab("GameSettingsNetworking", ms->T("Networking"), [this](UI::LinearLayout *parent) {
CreateNetworkingSettings(parent);
});
LinearLayout *tools = AddTab("GameSettingsTools", ms->T("Tools"));
CreateToolsSettings(tools);
AddTab("GameSettingsTools", ms->T("Tools"), [this](UI::LinearLayout *parent) {
CreateToolsSettings(parent);
});
LinearLayout *systemSettings = AddTab("GameSettingsSystem", ms->T("System"));
systemSettings->SetSpacing(0);
CreateSystemSettings(systemSettings);
AddTab("GameSettingsSystem", ms->T("System"), [this](UI::LinearLayout *parent) {
parent->SetSpacing(0);
CreateSystemSettings(parent);
});
int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE);
if ((deviceType == DEVICE_TYPE_VR) || g_Config.bForceVR) {
LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR"));
CreateVRSettings(vrSettings);
AddTab("GameSettingsVR", ms->T("VR"), [this](UI::LinearLayout *parent) {
CreateVRSettings(parent);
});
}
}

View file

@ -278,12 +278,14 @@ RemoteISOScreen::RemoteISOScreen(const Path &filename) : TabbedUIDialogScreenWit
void RemoteISOScreen::CreateTabs() {
auto ri = GetI18NCategory(I18NCat::REMOTEISO);
UI::LinearLayout *connect = AddTab("Connect", ri->T("Connect"));
connect->SetSpacing(5.0f);
CreateConnectTab(connect);
AddTab("Connect", ri->T("Connect"), [this](UI::LinearLayout *connect) {
connect->SetSpacing(5.0f);
CreateConnectTab(connect);
});
UI::LinearLayout *settings = AddTab("Settings", ri->T("Settings"));
CreateSettingsTab(settings);
AddTab("Settings", ri->T("Settings"), [this](UI::LinearLayout *settings) {
CreateSettingsTab(settings);
});
}
void RemoteISOScreen::update() {

View file

@ -62,16 +62,21 @@ AudioFileChooser::AudioFileChooser(RequesterToken token, std::string *value, std
void RetroAchievementsListScreen::CreateTabs() {
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
UI::LinearLayout *achievements = AddTab("Achievements", ac->T("Achievements"));
achievements->SetSpacing(5.0f);
CreateAchievementsTab(achievements);
AddTab("Achievements", ac->T("Achievements"), [this](UI::LinearLayout *parent) {
parent->SetSpacing(5.0f);
CreateAchievementsTab(parent);
});
UI::LinearLayout *leaderboards = AddTab("Leaderboards", ac->T("Leaderboards"));
leaderboards->SetSpacing(5.0f);
CreateLeaderboardsTab(leaderboards);
AddTab("Leaderboards", ac->T("Leaderboards"), [this](UI::LinearLayout *parent) {
parent->SetSpacing(5.0f);
CreateLeaderboardsTab(parent);
});
#ifdef _DEBUG
CreateStatisticsTab(AddTab("AchievementsStatistics", ac->T("Statistics")));
AddTab("AchievementsStatistics", ac->T("Statistics"), [this](UI::LinearLayout *parent) {
parent->SetSpacing(5.0f);
CreateStatisticsTab(parent);
});
#endif
}
@ -200,7 +205,15 @@ void RetroAchievementsLeaderboardScreen::CreateTabs() {
const rc_client_leaderboard_t *leaderboard = rc_client_get_leaderboard_info(Achievements::GetClient(), leaderboardID_);
using namespace UI;
UI::LinearLayout *layout = AddTab("AchievementsLeaderboard", leaderboard->title);
AddTab("AchievementsLeaderboard", leaderboard->title, [this, leaderboard](UI::LinearLayout *parent) {
CreateLeaderboardTab(parent, leaderboard);
});
}
void RetroAchievementsLeaderboardScreen::CreateLeaderboardTab(UI::LinearLayout *layout, const rc_client_leaderboard_t *leaderboard) {
using namespace UI;
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
layout->Add(new TextView(leaderboard->description));
layout->Add(new ItemHeader(ac->T("Leaderboard")));
@ -254,10 +267,16 @@ void RetroAchievementsSettingsScreen::CreateTabs() {
using namespace UI;
CreateAccountTab(AddTab("AchievementsAccount", ac->T("Account")));
AddTab("AchievementsAccount", ac->T("Account"), [this](UI::LinearLayout *layout) {
CreateAccountTab(layout);
});
// Don't bother creating this tab if we don't have a file browser.
CreateCustomizeTab(AddTab("AchievementsCustomize", ac->T("Customize")));
CreateDeveloperToolsTab(AddTab("AchievementsDeveloperTools", sy->T("Developer Tools")));
AddTab("AchievementsCustomize", ac->T("Customize"), [this](UI::LinearLayout *layout) {
CreateCustomizeTab(layout);
});
AddTab("AchievementsDeveloperTools", sy->T("Developer Tools"), [this](UI::LinearLayout *layout) {
CreateDeveloperToolsTab(layout);
});
}
void RetroAchievementsSettingsScreen::sendMessage(UIMessage message, const char *value) {

View file

@ -66,6 +66,7 @@ protected:
bool ShowSearchControls() const override { return false; }
private:
void CreateLeaderboardTab(UI::LinearLayout *layout, const rc_client_leaderboard_t *leaderboard);
void FetchEntries();
void Poll();

View file

@ -666,11 +666,13 @@ void SavedataScreen::CreateTabs() {
using namespace UI;
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
LinearLayout *savedata = AddTab("SavedataBrowser", sa->T("Save Data"));
CreateSavedataTab(savedata);
AddTab("SavedataBrowser", sa->T("Save Data"), [this](UI::LinearLayout *parent) {
CreateSavedataTab(parent);
});
LinearLayout *savestate = AddTab("SavedataStatesBrowser", sa->T("Save States"));
CreateSavestateTab(savestate);
AddTab("SavedataStatesBrowser", sa->T("Save States"), [this](UI::LinearLayout *parent) {
CreateSavestateTab(parent);
});
}
void SavedataScreen::CreateExtraButtons(UI::LinearLayout *verticalLayout, int margins) {

View file

@ -6,7 +6,7 @@
#include "Common/System/Display.h"
#include "UI/TabbedDialogScreen.h"
UI::LinearLayout *TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag, std::string_view title, bool isSearch) {
void TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag, std::string_view title, std::function<void(UI::LinearLayout *)> createCallback, bool isSearch) {
using namespace UI;
ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scroll->SetTag(tag);
@ -16,7 +16,7 @@ UI::LinearLayout *TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag
scroll->Add(contents);
tabHolder_->AddTab(title, scroll);
return contents;
createCallback(contents);
}
void TabbedUIDialogScreenWithGameBackground::CreateViews() {
@ -74,24 +74,25 @@ void TabbedUIDialogScreenWithGameBackground::CreateViews() {
// 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) && ShowSearchControls()) {
auto se = GetI18NCategory(I18NCat::SEARCH);
auto ms = GetI18NCategory(I18NCat::MAINSETTINGS);
// Search
LinearLayout *searchSettings = AddTab("GameSettingsSearch", ms->T("Search"), true);
auto ms = GetI18NCategory(I18NCat::MAINSETTINGS);
AddTab("GameSettingsSearch", ms->T("Search"), [this](UI::LinearLayout *searchSettings) {
auto se = GetI18NCategory(I18NCat::SEARCH);
searchSettings->Add(new ItemHeader(se->T("Find settings")));
searchSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Add([=](UI::EventParams &e) {
System_PostUIMessage(UIMessage::GAMESETTINGS_SEARCH, StripSpaces(searchFilter_));
return UI::EVENT_DONE;
});
searchSettings->Add(new ItemHeader(se->T("Find settings")));
searchSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &searchFilter_, se->T("Filter"), "", 64, screenManager()))->OnChange.Add([=](UI::EventParams &e) {
System_PostUIMessage(UIMessage::GAMESETTINGS_SEARCH, StripSpaces(searchFilter_));
return UI::EVENT_DONE;
});
clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter")));
clearSearchChoice_->OnClick.Add([=](UI::EventParams &e) {
System_PostUIMessage(UIMessage::GAMESETTINGS_SEARCH, "");
return UI::EVENT_DONE;
});
clearSearchChoice_ = searchSettings->Add(new Choice(se->T("Clear filter")));
clearSearchChoice_->OnClick.Add([=](UI::EventParams &e) {
System_PostUIMessage(UIMessage::GAMESETTINGS_SEARCH, "");
return UI::EVENT_DONE;
});
noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5))));
noSearchResults_ = searchSettings->Add(new TextView(se->T("No settings matched '%1'"), new LinearLayoutParams(Margins(20, 5))));
}, true);
ApplySearchFilter();
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "ppsspp_config.h"
#include <functional>
#include "Common/UI/UIScreen.h"
#include "Common/System/System.h"
@ -11,7 +12,7 @@ class TabbedUIDialogScreenWithGameBackground : public UIDialogScreenWithGameBack
public:
TabbedUIDialogScreenWithGameBackground(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {}
UI::LinearLayout *AddTab(const char *tag, std::string_view title, bool isSearch = false);
void AddTab(const char *tag, std::string_view title, std::function<void(UI::LinearLayout *)> createCallback, bool isSearch = false);
void CreateViews() override;
protected: