diff --git a/Core/Config.cpp b/Core/Config.cpp index ebbcb085a6..71759454f1 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -220,10 +220,10 @@ static int GameBrowserViewFromGridView(int legacyGridView, GameBrowserViewMode d return (int)(legacyGridView ? GameBrowserViewMode::GRID : GameBrowserViewMode::LIST); } -// Recent, Games and Homebrew switch everyone to the large list, ignoring the old setting. Remote keeps it. -static int DefaultGameBrowserView1() { return (int)GameBrowserViewMode::LARGE_LIST; } -static int DefaultGameBrowserView2() { return (int)GameBrowserViewMode::LARGE_LIST; } -static int DefaultGameBrowserView3() { return (int)GameBrowserViewMode::LARGE_LIST; } +// Recent, Games and Homebrew switch everyone to the list, ignoring the old setting. Remote keeps it. +static int DefaultGameBrowserView1() { return (int)GameBrowserViewMode::LIST; } +static int DefaultGameBrowserView2() { return (int)GameBrowserViewMode::LIST; } +static int DefaultGameBrowserView3() { return (int)GameBrowserViewMode::LIST; } static int DefaultGameBrowserView4() { return GameBrowserViewFromGridView(g_Config.iLegacyGridView4, GameBrowserViewMode::LIST); } static float DefaultGameGridScale() { @@ -417,6 +417,7 @@ static constexpr 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("GameListScale", SETTING(g_Config, fGameListScale), &DefaultGameGridScale, CfgFlag::DEFAULT), 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), diff --git a/Core/Config.h b/Core/Config.h index 3f33db4837..9548d8df4b 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -468,6 +468,7 @@ public: bool bShowRegionOnGameIcon; bool bShowIDOnGameIcon; float fGameGridScale; + float fGameListScale; int iBackgroundAnimation; // enum BackgroundAnimation bool bTransparentBackground; int iSettingsCurrentTab; diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 0bad547770..29ba2bc524 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -320,6 +320,5 @@ enum class RemoteISOShareType : int { enum class GameBrowserViewMode : int { GRID = 0, - LIST = 1, - LARGE_LIST = 2, // XMB-style, with full size icons and the ICON1.PMF video. + LIST = 1, // XMB-style, with full size icons and the ICON1.PMF video. Old configs may have 2 (the large list) here. }; diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index 13dd326f6c..83d6ae0a84 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -52,7 +52,7 @@ #include "Core/Util/DarwinFileSystemServices.h" // For the browser // Folders get bigger lines too, though not as big as the games. -static constexpr float LARGE_LIST_FOLDER_H = 50.0f; +static constexpr float LIST_FOLDER_H = 50.0f; 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) : LinearLayout(ORIENT_VERTICAL, layoutParams), viewMode_(viewMode), browseFlags_(browseFlags), portrait_(portrait), lastText_(lastText), lastLink_(lastLink), screenManager_(screenManager), token_(token) { @@ -104,23 +104,25 @@ bool GameBrowser::Touch(const TouchInput &input) { return LinearLayout::Touch(input); } +float *GameBrowserIconScale(GameBrowserViewMode viewMode) { + return viewMode == GameBrowserViewMode::GRID ? &g_Config.fGameGridScale : &g_Config.fGameListScale; +} + // Draw notices the change and refreshes every browser. -static void StepIconSize(bool bigger) { +void StepGameBrowserIconScale(GameBrowserViewMode viewMode, bool bigger) { + float *scale = GameBrowserIconScale(viewMode); if (bigger) { - g_Config.fGameGridScale = std::min(g_Config.fGameGridScale * 1.25f, MAX_GAME_GRID_SCALE); + *scale = std::min(*scale * 1.25f, MAX_GAME_GRID_SCALE); } else { - g_Config.fGameGridScale = std::max(g_Config.fGameGridScale / 1.25f, MIN_GAME_GRID_SCALE); + *scale = std::max(*scale / 1.25f, MIN_GAME_GRID_SCALE); } } bool GameBrowser::Key(const KeyInput &input) { // Ctrl+wheel and Ctrl+Plus/Minus (Cmd on Apple platforms) change the icon size, like zooming in a - // file manager. The plain list doesn't scale. + // file manager. const bool zoomMod = (input.flags & KeyInputFlags::DOWN) && (input.flags & KEY_MOD_SHORTCUT); if (zoomMod && mouseHover_ && (input.keyCode == NKCODE_EXT_MOUSEWHEEL_UP || input.keyCode == NKCODE_EXT_MOUSEWHEEL_DOWN)) { - if (ViewMode() == GameBrowserViewMode::LIST) { - return false; - } // A touchpad sends a stream of small deltas, so add them up and step once per notch's worth. int delta = (input.flags & KeyInputFlags::HAS_WHEEL_DELTA) ? input.Delta() : WHEEL_DELTA_PER_NOTCH; // Zoom by the fingers' direction (up is bigger), whatever the natural scrolling setting. @@ -135,26 +137,26 @@ bool GameBrowser::Key(const KeyInput &input) { lastWheelZoomTime_ = now; wheelZoomAccum_ += delta; while (wheelZoomAccum_ >= WHEEL_DELTA_PER_NOTCH) { - StepIconSize(true); + StepGameBrowserIconScale(ViewMode(), true); wheelZoomAccum_ -= WHEEL_DELTA_PER_NOTCH; } while (wheelZoomAccum_ <= -WHEEL_DELTA_PER_NOTCH) { - StepIconSize(false); + StepGameBrowserIconScale(ViewMode(), false); wheelZoomAccum_ += WHEEL_DELTA_PER_NOTCH; } return true; } - if (zoomMod && ViewMode() != GameBrowserViewMode::LIST) { + if (zoomMod) { // Plus is shifted on most layouts, so accept the key it shares (Equals on US layouts) too. switch (input.keyCode) { case NKCODE_PLUS: case NKCODE_EQUALS: case NKCODE_NUMPAD_ADD: - StepIconSize(true); + StepGameBrowserIconScale(ViewMode(), true); return true; case NKCODE_MINUS: case NKCODE_NUMPAD_SUBTRACT: - StepIconSize(false); + StepGameBrowserIconScale(ViewMode(), false); return true; default: break; @@ -200,10 +202,8 @@ void GameBrowser::SetSearchFilter(const std::string &filter, bool setKeyboardFoc } GameBrowserViewMode GameBrowser::ViewMode() const { - if (*viewMode_ < (int)GameBrowserViewMode::GRID || *viewMode_ > (int)GameBrowserViewMode::LARGE_LIST) { - return GameBrowserViewMode::GRID; - } - return (GameBrowserViewMode)*viewMode_; + // Anything else is the list, including 2 (the old large list). + return *viewMode_ == (int)GameBrowserViewMode::GRID ? GameBrowserViewMode::GRID : GameBrowserViewMode::LIST; } void GameBrowser::LayoutChange(UI::EventParams &e) { @@ -305,7 +305,7 @@ void GameBrowser::Update() { void GameBrowser::Draw(UIContext &dc) { using namespace UI; - if (lastScale_ != g_Config.fGameGridScale || lastViewMode_ != ViewMode()) { + if (lastScale_ != *GameBrowserIconScale(ViewMode()) || lastViewMode_ != ViewMode()) { refreshPending_ = true; // Keep the focus on the same game, as a keyboard zoom leaves it there. if (gameList_ && focusPath_.empty()) { @@ -385,8 +385,8 @@ static bool IsValidPBP(const Path &path, bool allowHomebrew) { void GameBrowser::Refresh() { using namespace UI; - lastScale_ = g_Config.fGameGridScale; lastViewMode_ = ViewMode(); + lastScale_ = *GameBrowserIconScale(lastViewMode_); const bool gridStyle = lastViewMode_ == GameBrowserViewMode::GRID; // Kill all the contents @@ -472,7 +472,6 @@ void GameBrowser::Refresh() { ChoiceStrip *layoutChoice = topBar->Add(new ChoiceStrip(ORIENT_HORIZONTAL)); layoutChoice->AddChoice(ImageID("I_GRID")); - layoutChoice->AddChoice(ImageID("I_LINES")); layoutChoice->AddChoice(ImageID("I_LARGE_LIST")); layoutChoice->SetSelection((int)lastViewMode_, false); layoutChoice->ApplyRoundCorners(); @@ -739,7 +738,7 @@ void GameBrowser::PathChanged() { void GameBrowser::GridSettingsClick(UI::EventParams &e) { auto sy = GetI18NCategory(I18NCat::SYSTEM); - auto gridSettings = new GridSettingsPopupScreen(sy->T("Games list settings")); + auto gridSettings = new GridSettingsPopupScreen(sy->T("Games list settings"), ViewMode()); gridSettings->OnRecentChanged.Handle(this, &GameBrowser::OnRecentClear); if (e.v) gridSettings->SetPopupOrigin(e.v); diff --git a/UI/GameBrowser.h b/UI/GameBrowser.h index fb532751f9..b610f754d7 100644 --- a/UI/GameBrowser.h +++ b/UI/GameBrowser.h @@ -12,6 +12,10 @@ constexpr float MIN_GAME_GRID_SCALE = 0.8f; constexpr float MAX_GAME_GRID_SCALE = 3.0f; +// The icon size setting for a view mode (grid and list have one each). +float *GameBrowserIconScale(GameBrowserViewMode viewMode); +void StepGameBrowserIconScale(GameBrowserViewMode viewMode, bool bigger); + enum GameBrowserFlags { FLAG_HOMEBREWSTOREBUTTON = 1 }; diff --git a/UI/GameButton.cpp b/UI/GameButton.cpp index 6c33ff09a8..8a971b84e6 100644 --- a/UI/GameButton.cpp +++ b/UI/GameButton.cpp @@ -32,21 +32,13 @@ #include "UI/GamePacker.h" -// Where the text starts in the list modes. -static float ListTextX(GameBrowserViewMode viewMode) { - if (viewMode == GameBrowserViewMode::LARGE_LIST) { - return LARGE_LIST_LEFT_PAD + LARGE_LIST_ICON_W * g_Config.fGameGridScale + 20.0f; - } - return 150.0f; +// Where the text starts in the list. +static float ListTextX() { + return LIST_LEFT_PAD + LIST_ICON_W * g_Config.fGameListScale + 20.0f; } -// Space to the right of the text in the list modes, for the info button. -static float ListTextRightMargin(GameBrowserViewMode viewMode) { - if (viewMode == GameBrowserViewMode::LARGE_LIST) { - return LARGE_LIST_INFO_SIZE + LARGE_LIST_PAD * 2; - } - return 0.0f; -} +// Space to the right of the text in the list, for the info button. +static constexpr float LIST_TEXT_RIGHT_MARGIN = LIST_INFO_SIZE + LIST_PAD * 2; void GameButton::UpdateVideo(const std::shared_ptr &ginfo, bool wantVideo) { @@ -114,18 +106,14 @@ void GameButton::GetContentDimensions(const UIContext &dc, float &w, float &h) c w = 144 * g_Config.fGameGridScale; h = 80 * g_Config.fGameGridScale; break; - case GameBrowserViewMode::LARGE_LIST: + case GameBrowserViewMode::LIST: w = 500; if (type_ == GameButtonType::Dir) { h = UI::ITEM_HEIGHT; } else { - h = LARGE_LIST_ICON_H * g_Config.fGameGridScale + LARGE_LIST_PAD * 2; + h = LIST_ICON_H * g_Config.fGameListScale + LIST_PAD * 2; } break; - default: // List - w = 500; - h = 56; - break; } } @@ -141,7 +129,7 @@ static const ImageID regionIcons[(int)GameRegion::COUNT] = { void GameButton::Draw(UIContext &dc) { // Like the XMB, only the selected game plays its video. Only keyboard/gamepad focus selects, since with // touch or the mouse, getting a video to play without launching the game was too fiddly. - const bool wantVideo = viewMode_ == GameBrowserViewMode::LARGE_LIST && HasFocus() && pmf_player_available(); + const bool wantVideo = viewMode_ == GameBrowserViewMode::LIST && HasFocus() && pmf_player_available(); std::shared_ptr ginfo; @@ -220,14 +208,13 @@ void GameButton::Draw(UIContext &dc) { // Some types we just draw a default icon for. Bounds iconBounds = bounds_; - iconBounds.w = viewMode_ == GameBrowserViewMode::GRID ? bounds_.w : 144; - if (viewMode_ == GameBrowserViewMode::LARGE_LIST) { - iconBounds.x += LARGE_LIST_LEFT_PAD; - iconBounds.y += LARGE_LIST_PAD; - iconBounds.w = LARGE_LIST_ICON_W * g_Config.fGameGridScale; - iconBounds.h = LARGE_LIST_ICON_H * g_Config.fGameGridScale; + if (viewMode_ == GameBrowserViewMode::LIST) { + iconBounds.x += LIST_LEFT_PAD; + iconBounds.y += LIST_PAD; + iconBounds.w = LIST_ICON_W * g_Config.fGameListScale; + iconBounds.h = LIST_ICON_H * g_Config.fGameListScale; } - const float textX = ListTextX(viewMode_); + const float textX = ListTextX(); int iconYOffset = 0; if (viewMode_ == GameBrowserViewMode::GRID && down_) { @@ -257,10 +244,6 @@ void GameButton::Draw(UIContext &dc) { iconBounds.w = nw; } - if (viewMode_ == GameBrowserViewMode::LIST) { - iconBounds.x += 4; - } - if (iconYOffset) { // Button pressed, move the icon down a bit and reduce the shadow. dropsize = 3; @@ -339,8 +322,6 @@ void GameButton::Draw(UIContext &dc) { dc.PopScissor(); } } else { - // The two list view modes, compat and large. - Bounds bounds = bounds_; std::string_view rightText = g_Config.bShowIDOnGameIcon ? std::string_view(id_version) : std::string_view(); @@ -349,23 +330,13 @@ void GameButton::Draw(UIContext &dc) { dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text, &tw, &th, 0); if (imageIcon.isValid()) { - const float textX = ListTextX(viewMode_); - if (viewMode_ == GameBrowserViewMode::LARGE_LIST) { - float scale = g_Config.fGameGridScale; - if (type_ == GameButtonType::Dir) { - // Dirs are fixed height - scale = 1.0f; - } else { - scale = g_Config.fGameGridScale * 0.88f; - } - dc.Draw()->DrawImage(imageIcon, bounds.x + LARGE_LIST_LEFT_PAD + LARGE_LIST_ICON_W * g_Config.fGameGridScale * 0.5f, bounds.centerY(), scale, style.fgColor, ALIGN_CENTER); - } else { - dc.Draw()->DrawImage(imageIcon, bounds.x + 72, bounds.centerY(), 0.88f, style.fgColor, ALIGN_CENTER); - } + // Dirs are fixed height. + const float scale = type_ == GameButtonType::Dir ? 1.0f : g_Config.fGameListScale * 0.88f; + dc.Draw()->DrawImage(imageIcon, bounds.x + LIST_LEFT_PAD + LIST_ICON_W * g_Config.fGameListScale * 0.5f, bounds.centerY(), scale, style.fgColor, ALIGN_CENTER); } float tx = textX; - int availableWidth = bounds.w - textX - ListTextRightMargin(viewMode_); + int availableWidth = bounds.w - textX - LIST_TEXT_RIGHT_MARGIN; if (!rightText.empty()) { float vw, vh; dc.MeasureText(dc.GetFontStyle(), 0.7f, 0.7f, rightText, &vw, &vh, 0); @@ -393,10 +364,8 @@ void GameButton::Draw(UIContext &dc) { if (gearImage) { if (viewMode_ == GameBrowserViewMode::GRID) { dc.Draw()->DrawImage(ImageID("I_GEAR_SMALL"), bounds_.x, iconBounds.y2() - gearImage->h * g_Config.fGameGridScale, g_Config.fGameGridScale); - } else if (viewMode_ == GameBrowserViewMode::LARGE_LIST) { - dc.Draw()->DrawImage(ImageID("I_GEAR_SMALL"), bounds_.x + LARGE_LIST_LEFT_PAD, iconBounds.y2() - gearImage->h * g_Config.fGameGridScale, g_Config.fGameGridScale); } else { - dc.Draw()->DrawImage(ImageID("I_GEAR_SMALL"), bounds_.x + 4, iconBounds.y, 1.0f); + dc.Draw()->DrawImage(ImageID("I_GEAR_SMALL"), bounds_.x + LIST_LEFT_PAD, iconBounds.y2() - gearImage->h * g_Config.fGameListScale, g_Config.fGameListScale); } } } @@ -408,11 +377,9 @@ void GameButton::Draw(UIContext &dc) { if (viewMode_ == GameBrowserViewMode::GRID) { dc.Draw()->DrawImage(regionIcons[regionIndex], bounds_.x + bounds_.w - (regionImage->w + 5) * g_Config.fGameGridScale, iconBounds.y2() - (regionImage->h + 5) * g_Config.fGameGridScale, g_Config.fGameGridScale); - } else if (viewMode_ == GameBrowserViewMode::LARGE_LIST) { - dc.Draw()->DrawImage(regionIcons[regionIndex], bounds_.x + LARGE_LIST_LEFT_PAD + (LARGE_LIST_ICON_W - regionImage->w - 5) * g_Config.fGameGridScale, - iconBounds.y2() - (regionImage->h + 5) * g_Config.fGameGridScale, g_Config.fGameGridScale); } else { - dc.Draw()->DrawImage(regionIcons[regionIndex], bounds_.x + 4, iconBounds.y2() - regionImage->h - 5, 1.0f); + dc.Draw()->DrawImage(regionIcons[regionIndex], bounds_.x + LIST_LEFT_PAD + (LIST_ICON_W - regionImage->w - 5) * g_Config.fGameListScale, + iconBounds.y2() - (regionImage->h + 5) * g_Config.fGameListScale, g_Config.fGameListScale); } } } @@ -453,7 +420,7 @@ void GameButton::Draw(UIContext &dc) { if (GamePacker::IsPacking(gamePath_) && GamePacker::GetStatus(&packStatus)) { auto ga = GetI18NCategory(I18NCat::GAME); dc.FillRect(Drawable(0xD0505050), iconBounds); - const float scale = viewMode_ == GameBrowserViewMode::GRID || viewMode_ == GameBrowserViewMode::LARGE_LIST ? 0.8f * g_Config.fGameGridScale : 0.6f; + const float scale = 0.8f * (viewMode_ == GameBrowserViewMode::GRID ? g_Config.fGameGridScale : g_Config.fGameListScale); dc.SetFontStyle(dc.GetTheme().uiFont); dc.SetFontScale(scale, scale); const std::string text = std::string(ga->T("Compressing...")) + StringFromFormat("\n%d%%", (int)(packStatus.progress * 100.0f)); diff --git a/UI/GameButton.h b/UI/GameButton.h index 3a691f91aa..83491315ec 100644 --- a/UI/GameButton.h +++ b/UI/GameButton.h @@ -33,12 +33,12 @@ class GameInfo; -// Icon dimensions in the large list, and its padding around the icon. -static constexpr float LARGE_LIST_ICON_W = 144.0f; -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; +// Icon dimensions in the list, and its padding around the icon. +static constexpr float LIST_ICON_W = 144.0f; +static constexpr float LIST_ICON_H = 80.0f; +static constexpr float LIST_PAD = 6.0f; +static constexpr float LIST_LEFT_PAD = 11.0f; +static constexpr float LIST_INFO_SIZE = 64.0f; enum class GameButtonType { Game, @@ -212,12 +212,12 @@ private: void UpdateVideo(const std::shared_ptr &ginfo, bool wantVideo); - // The large list has room for an info button on each line, doing the same as a long press. + // The list has room for an info button on each line, doing the same as a long press. bool HasInfoButton() const { - return viewMode_ == GameBrowserViewMode::LARGE_LIST && type_ == GameButtonType::Game; + return viewMode_ == GameBrowserViewMode::LIST && type_ == GameButtonType::Game; } Bounds InfoButtonBounds() const { - return Bounds(bounds_.x2() - LARGE_LIST_INFO_SIZE - LARGE_LIST_PAD, bounds_.centerY() - LARGE_LIST_INFO_SIZE * 0.5f, LARGE_LIST_INFO_SIZE, LARGE_LIST_INFO_SIZE); + return Bounds(bounds_.x2() - LIST_INFO_SIZE - LIST_PAD, bounds_.centerY() - LIST_INFO_SIZE * 0.5f, LIST_INFO_SIZE, LIST_INFO_SIZE); } // Returns true if the info button took the input. bool TouchInfoButton(const TouchInput &input) { @@ -244,7 +244,7 @@ private: const Path gamePath_; std::string title_; - // The ICON1.PMF video, played in place of the icon in the large list, like the XMB does. + // The ICON1.PMF video, played in place of the icon in the list, like the XMB does. std::unique_ptr video_; Instant videoStart_; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 507f40a33e..5143713fc2 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1049,11 +1049,11 @@ void GridSettingsPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { ChoiceGroup *iconSizeGroup = groupList->Add(new ChoiceGroup(sy->T("Icon size"))); iconSizeGroup->Add(new Choice(sy->T("Increase size")))->OnClick.Add([this](UI::EventParams &e) { - g_Config.fGameGridScale = std::min(g_Config.fGameGridScale * 1.25f, MAX_GAME_GRID_SCALE); + StepGameBrowserIconScale(viewMode_, true); screenManager()->RecreateAllViews(); }); iconSizeGroup->Add(new Choice(sy->T("Decrease size")))->OnClick.Add([this](UI::EventParams &e) { - g_Config.fGameGridScale = std::max(g_Config.fGameGridScale / 1.25f, MIN_GAME_GRID_SCALE); + StepGameBrowserIconScale(viewMode_, false); screenManager()->RecreateAllViews(); }); diff --git a/UI/MainScreen.h b/UI/MainScreen.h index 5724b2c06c..67c1b29288 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -122,11 +122,15 @@ private: class GridSettingsPopupScreen : public UI::PopupScreen { public: - GridSettingsPopupScreen(std::string_view label) : PopupScreen(label) {} + // The icon size buttons change the size for viewMode. + GridSettingsPopupScreen(std::string_view label, GameBrowserViewMode viewMode) : PopupScreen(label), viewMode_(viewMode) {} void CreatePopupContents(UI::ViewGroup *parent) override; UI::Event OnRecentChanged; const char *tag() const override { return "GridSettings"; } + +private: + GameBrowserViewMode viewMode_; }; void LaunchBuyGold(ScreenManager *screenManager);