From ce8f48980acbb50a8d2caa9a4089959c47d34a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 14 Oct 2026 11:00:00 +0200 Subject: [PATCH] Game browser: Default to the large list for Games and Homebrew, bigger folders The old GridView keys are now read as ints, so a missing key can be told apart from false. Configs without them get the new defaults, while existing ones still migrate their choice. Folders get taller lines in the large list too, though not as tall as the games. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/Config.cpp | 32 ++++++++++++++++++++++---------- Core/Config.h | 10 +++++----- UI/GameBrowser.cpp | 26 +++++++++++++++++--------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 17dd44d34a..d33e9f49de 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -195,14 +195,26 @@ static bool DefaultEnableStateUndo() { return true; } -static int GameBrowserViewFromGridView(bool gridView) { - return (int)(gridView ? GameBrowserViewMode::GRID : GameBrowserViewMode::LIST); +// The old GridView bools, read as ints so a missing key (-1) can be told apart from false. +static int LegacyGridViewFromString(const std::string &value) { + return equalsNoCase(value, "True") ? 1 : 0; } -static int DefaultGameBrowserView1() { return GameBrowserViewFromGridView(g_Config.bGridView1); } -static int DefaultGameBrowserView2() { return GameBrowserViewFromGridView(g_Config.bGridView2); } -static int DefaultGameBrowserView3() { return GameBrowserViewFromGridView(g_Config.bGridView3); } -static int DefaultGameBrowserView4() { return GameBrowserViewFromGridView(g_Config.bGridView4); } +static std::string LegacyGridViewToString(int value) { + return value == 1 ? "True" : "False"; +} + +static int GameBrowserViewFromGridView(int legacyGridView, GameBrowserViewMode defaultMode) { + if (legacyGridView < 0) { + return (int)defaultMode; + } + return (int)(legacyGridView ? GameBrowserViewMode::GRID : GameBrowserViewMode::LIST); +} + +static int DefaultGameBrowserView1() { return GameBrowserViewFromGridView(g_Config.iLegacyGridView1, GameBrowserViewMode::GRID); } +static int DefaultGameBrowserView2() { return GameBrowserViewFromGridView(g_Config.iLegacyGridView2, GameBrowserViewMode::LARGE_LIST); } +static int DefaultGameBrowserView3() { return GameBrowserViewFromGridView(g_Config.iLegacyGridView3, GameBrowserViewMode::LARGE_LIST); } +static int DefaultGameBrowserView4() { return GameBrowserViewFromGridView(g_Config.iLegacyGridView4, GameBrowserViewMode::LIST); } static float DefaultGameGridScale() { #if PPSSPP_PLATFORM(IOS) @@ -292,10 +304,10 @@ static const ConfigSetting generalSettings[] = { ConfigSetting("ShowRegionOnGameIcon", SETTING(g_Config, bShowRegionOnGameIcon), false, CfgFlag::DEFAULT), ConfigSetting("ShowIDOnGameIcon", SETTING(g_Config, bShowIDOnGameIcon), false, CfgFlag::DEFAULT), ConfigSetting("GameGridScale", SETTING(g_Config, fGameGridScale), &DefaultGameGridScale, CfgFlag::DEFAULT), - ConfigSetting("GridView1", SETTING(g_Config, bGridView1), true, CfgFlag::DONT_SAVE), - ConfigSetting("GridView2", SETTING(g_Config, bGridView2), true, CfgFlag::DONT_SAVE), - ConfigSetting("GridView3", SETTING(g_Config, bGridView3), false, CfgFlag::DONT_SAVE), - ConfigSetting("GridView4", SETTING(g_Config, bGridView4), false, CfgFlag::DONT_SAVE), + ConfigSetting("GridView1", SETTING(g_Config, iLegacyGridView1), -1, &LegacyGridViewToString, &LegacyGridViewFromString, CfgFlag::DONT_SAVE), + ConfigSetting("GridView2", SETTING(g_Config, iLegacyGridView2), -1, &LegacyGridViewToString, &LegacyGridViewFromString, CfgFlag::DONT_SAVE), + ConfigSetting("GridView3", SETTING(g_Config, iLegacyGridView3), -1, &LegacyGridViewToString, &LegacyGridViewFromString, CfgFlag::DONT_SAVE), + ConfigSetting("GridView4", SETTING(g_Config, iLegacyGridView4), -1, &LegacyGridViewToString, &LegacyGridViewFromString, CfgFlag::DONT_SAVE), // These must come after GridView*, which their defaults are taken from. ConfigSetting("GameBrowserView1", SETTING(g_Config, iGameBrowserView1), &DefaultGameBrowserView1, CfgFlag::DEFAULT), ConfigSetting("GameBrowserView2", SETTING(g_Config, iGameBrowserView2), &DefaultGameBrowserView2, CfgFlag::DEFAULT), diff --git a/Core/Config.h b/Core/Config.h index d472373c15..41831ba759 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -473,11 +473,11 @@ public: int iGameBrowserView2; int iGameBrowserView3; int iGameBrowserView4; - // Only read, to migrate to iGameBrowserView*. - bool bGridView1; - bool bGridView2; - bool bGridView3; - bool bGridView4; + // The old GridView bools, only read, to migrate to iGameBrowserView*. -1 if missing. + int iLegacyGridView1; + int iLegacyGridView2; + int iLegacyGridView3; + int iLegacyGridView4; // Right analog binding int iRightAnalogUp; diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index b7a5c00cc0..ac58ebdb5b 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -56,6 +56,8 @@ static constexpr float LARGE_LIST_ICON_H = 80.0f; static constexpr float LARGE_LIST_PAD = 6.0f; static constexpr float LARGE_LIST_LEFT_PAD = 11.0f; static constexpr float LARGE_LIST_INFO_SIZE = 64.0f; +// Folders get bigger lines too, though not as big as the games. +static constexpr float LARGE_LIST_FOLDER_H = 50.0f; // Where the text starts in the list modes. static float ListTextX(GameBrowserViewMode viewMode) { @@ -671,12 +673,18 @@ std::string GameButton::DescribeText() const { class DirButton : public UI::Button { public: - DirButton(const Path &path, bool gridStyle, UI::LayoutParams *layoutParams) - : UI::Button(path.ToString(), layoutParams), path_(path), gridStyle_(gridStyle), absolute_(false) {} - DirButton(const Path &path, const std::string &text, bool gridStyle, UI::LayoutParams *layoutParams = 0) - : UI::Button(text, layoutParams), path_(path), gridStyle_(gridStyle), absolute_(true) {} + DirButton(const Path &path, GameBrowserViewMode viewMode, UI::LayoutParams *layoutParams) + : UI::Button(path.ToString(), layoutParams), path_(path), viewMode_(viewMode), absolute_(false) {} + DirButton(const Path &path, const std::string &text, GameBrowserViewMode viewMode, UI::LayoutParams *layoutParams = 0) + : UI::Button(text, layoutParams), path_(path), viewMode_(viewMode), absolute_(true) {} void Draw(UIContext &dc) override; + void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { + UI::Button::GetContentDimensions(dc, w, h); + if (viewMode_ == GameBrowserViewMode::LARGE_LIST) { + h = std::max(h, LARGE_LIST_FOLDER_H * g_Config.fGameGridScale + LARGE_LIST_PAD * 2); + } + } const Path &GetPath() const { return path_; @@ -696,7 +704,7 @@ public: private: Path path_; - bool gridStyle_; + GameBrowserViewMode viewMode_; bool absolute_; bool pinned_ = false; }; @@ -718,7 +726,7 @@ void DirButton::Draw(UIContext &dc) { if (!IsEnabled()) style = dc.GetTheme().itemDisabledStyle; dc.FillRect(style.background, bounds_); - DrawIconWithText(dc, image, text, bounds_, gridStyle_ ? GameBrowserViewMode::GRID : GameBrowserViewMode::LIST, style); + DrawIconWithText(dc, image, text, bounds_, viewMode_, style); } GameBrowser::GameBrowser(int token, const Path &path, BrowseFlags browseFlags, bool portrait, int *viewMode, ScreenManager *screenManager, std::string_view lastText, std::string_view lastLink, UI::LayoutParams *layoutParams) @@ -1095,7 +1103,7 @@ void GameBrowser::Refresh() { if (!isGame && !isSaveData) { if (browseFlags_ & BrowseFlags::NAVIGATE) { - dirButtons.push_back(new DirButton(fileInfo[i].fullName, fileInfo[i].name, gridStyle, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); + dirButtons.push_back(new DirButton(fileInfo[i].fullName, fileInfo[i].name, lastViewMode_, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); } } else { gameButtons.push_back(new GameButton(fileInfo[i].fullName, lastViewMode_, new UI::LinearLayoutParams(gridStyle ? UI::WRAP_CONTENT : UI::FILL_PARENT, UI::WRAP_CONTENT))); @@ -1122,14 +1130,14 @@ void GameBrowser::Refresh() { if (browseFlags_ & BrowseFlags::NAVIGATE) { if (path_.CanNavigateUp()) { - gameList_->Add(new DirButton(Path(".."), gridStyle, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)))-> + gameList_->Add(new DirButton(Path(".."), lastViewMode_, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)))-> OnClick.Handle(this, &GameBrowser::NavigateClick); } // Add any pinned paths before other directories. auto pinnedPaths = GetPinnedPaths(); for (const auto &pinnedPath : pinnedPaths) { - DirButton *pinnedDir = gameList_->Add(new DirButton(pinnedPath, pinnedPath.GetFilename(), gridStyle, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); + DirButton *pinnedDir = gameList_->Add(new DirButton(pinnedPath, pinnedPath.GetFilename(), lastViewMode_, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT))); pinnedDir->OnClick.Handle(this, &GameBrowser::NavigateClick); pinnedDir->SetPinned(true); }