From 4797f1381ccc6858445db3aa9120eeceee76a2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 24 Oct 2026 01:45:00 +0200 Subject: [PATCH] UI: Use ChoiceGroup on the pause menu and the firmware screen's actions Co-Authored-By: Claude Opus 5.5 (1M context) --- UI/FirmwareScreen.cpp | 21 +++++++++++---------- UI/PauseScreen.cpp | 37 +++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/UI/FirmwareScreen.cpp b/UI/FirmwareScreen.cpp index 444036bb2a..089f44d1d6 100644 --- a/UI/FirmwareScreen.cpp +++ b/UI/FirmwareScreen.cpp @@ -113,30 +113,31 @@ void FirmwareScreen::CreateSettingsViews(UI::ViewGroup *parent) { // that has flash0 mounted is worse - so while a game is running, this screen is read-only. const bool gameRunning = PSP_IsInited(); - Choice *launch = parent->Add(new Choice(sy->T("Launch XMB"), ImageID("I_PLAY"))); - launch->OnClick.Add([this](UI::EventParams &) { - LaunchVSH(); - }); - launch->SetEnabled(!gameRunning && info_.hasVsh && FirmwareVersionSupportsVSH(info_.version)); - if (info_.hasVsh && !FirmwareVersionSupportsVSH(info_.version)) { parent->Add(new NoticeView(NoticeLevel::WARN, sy->T("XMB unsupported"), sy->T("XMBUnsupportedVersion", "Only firmware 6.61 can boot the XMB so far"))); } + ChoiceGroup *actions = parent->Add(new ChoiceGroup("")); + Choice *launch = actions->Add(new Choice(sy->T("Launch XMB"), ImageID("I_PLAY"))); + launch->OnClick.Add([this](UI::EventParams &) { + LaunchVSH(); + }); + launch->SetEnabled(!gameRunning && info_.hasVsh && FirmwareVersionSupportsVSH(info_.version)); + if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { - Choice *install = parent->Add(new Choice(iz->T("Install PSP firmware update"), ImageID("I_FOLDER_UPLOAD"))); + Choice *install = actions->Add(new Choice(iz->T("Install PSP firmware update"), ImageID("I_FOLDER_UPLOAD"))); install->OnClick.Add([this](UI::EventParams &) { BrowseForUpdater(); }); install->SetEnabled(!gameRunning); } - parent->Add(new CheckBox(&g_Config.bAutoUpgradeFirmware, sy->T("Install or upgrade firmware from game discs"), + actions->Add(new CheckBox(&g_Config.bAutoUpgradeFirmware, sy->T("Install or upgrade firmware from game discs"), sy->T("AutoUpgradeFirmwareDesc", "Most game discs carry a firmware updater. Install it when there's no firmware yet, or when the disc's is newer."))); if (info_.anythingInstalled) { - Choice *erase = parent->Add(new Choice(sy->T("Uninstall firmware"), ImageID("I_TRASHCAN"))); + Choice *erase = actions->Add(new Choice(sy->T("Uninstall firmware"), ImageID("I_TRASHCAN"))); erase->OnClick.Add([this](UI::EventParams &) { AskToErase(); }); @@ -144,7 +145,7 @@ void FirmwareScreen::CreateSettingsViews(UI::ViewGroup *parent) { } if (System_GetPropertyBool(SYSPROP_HAS_OPEN_DIRECTORY)) { - parent->Add(new Choice(sy->T("Show firmware folder")))->OnClick.Add([this](UI::EventParams &) { + actions->Add(new Choice(sy->T("Show firmware folder")))->OnClick.Add([this](UI::EventParams &) { System_LaunchUrl(LaunchUrlType::LOCAL_FOLDER, nandRoot_.ToString()); }); } diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 6a551370c1..e8542136ce 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -715,63 +715,68 @@ void GamePauseScreen::CreateViews() { buttonColumn->Add(rightColumnItems); rightColumnItems->SetSpacing(0.0f); + ChoiceGroup *topGroup = rightColumnItems->Add(new ChoiceGroup("")); if (__KernelIsRunningVSH()) { // The XMB notices discs coming and going by itself, like a PSP's. if (__UmdIsInserted()) { - rightColumnItems->Add(new Choice(pa->T("Eject UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { + topGroup->Add(new Choice(pa->T("Eject UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { __UmdEject(); RecreateViews(); }); } else { - rightColumnItems->Add(new Choice(pa->T("Insert UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { + topGroup->Add(new Choice(pa->T("Insert UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { screenManager()->push(new UmdReplaceScreen(true)); }); } } else if (getUMDReplacePermit()) { - rightColumnItems->Add(new Choice(pa->T("Switch UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { + topGroup->Add(new Choice(pa->T("Switch UMD"), ImageID("I_UMD")))->OnClick.Add([this](UI::EventParams &) { screenManager()->push(new UmdReplaceScreen()); }); } if (!portrait) { - Choice *continueChoice = rightColumnItems->Add(new Choice(pa->T("Continue"), ImageID("I_PLAY"))); + Choice *continueChoice = topGroup->Add(new Choice(pa->T("Continue"), ImageID("I_PLAY"))); root_->SetDefaultFocusView(continueChoice); continueChoice->OnClick.Handle(this, &UIScreen::OnBack); - rightColumnItems->Add(new Spacer(20.0)); } + if (topGroup->GetNumSubviews() == 0) { + topGroup->SetVisibility(V_GONE); + } + + ChoiceGroup *mainGroup = rightColumnItems->Add(new ChoiceGroup("")); if (g_paramSFO.IsValid() && g_Config.HasGameConfig(g_paramSFO.GetDiscID())) { - rightColumnItems->Add(new Choice(pa->T("Game Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); + mainGroup->Add(new Choice(pa->T("Game Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); auto pa = GetI18NCategory(I18NCat::PAUSE); if (g_Config.HasGameConfig(g_paramSFO.GetValueString("DISC_ID"))) { - Choice *delGameConfig = rightColumnItems->Add(new Choice(pa->T("Delete Game Config"), ImageID("I_TRASHCAN"))); + Choice *delGameConfig = mainGroup->Add(new Choice(pa->T("Delete Game Config"), ImageID("I_TRASHCAN"))); delGameConfig->OnClick.Handle(this, &GamePauseScreen::OnDeleteConfig); delGameConfig->SetEnabled(!bootPending_); } } else if (PSP_CoreParameter().fileType != IdentifiedFileType::PPSSPP_GE_DUMP) { - rightColumnItems->Add(new Choice(pa->T("Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); - Choice *createGameConfig = rightColumnItems->Add(new Choice(pa->T("Create Game Config"), ImageID("I_GEAR_STAR"))); + mainGroup->Add(new Choice(pa->T("Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); + Choice *createGameConfig = mainGroup->Add(new Choice(pa->T("Create Game Config"), ImageID("I_GEAR_STAR"))); createGameConfig->OnClick.Handle(this, &GamePauseScreen::OnCreateConfig); createGameConfig->SetEnabled(!bootPending_); } if (g_Config.bAchievementsEnable && Achievements::HasAchievementsOrLeaderboards()) { - rightColumnItems->Add(new Choice(ac->T("Achievements"), ImageID("I_ACHIEVEMENT")))->OnClick.Add([this](UI::EventParams &e) { + mainGroup->Add(new Choice(ac->T("Achievements"), ImageID("I_ACHIEVEMENT")))->OnClick.Add([this](UI::EventParams &e) { screenManager()->push(new RetroAchievementsListScreen(gamePath_)); }); } - rightColumnItems->Add(new Choice(gr->T("Display layout & effects"), ImageID("I_DISPLAY")))->OnClick.Add([this](UI::EventParams &) -> void { + mainGroup->Add(new Choice(gr->T("Display layout & effects"), ImageID("I_DISPLAY")))->OnClick.Add([this](UI::EventParams &) -> void { screenManager()->push(new DisplayLayoutScreen(gamePath_)); }); if (g_Config.bShowTouchControls) { - rightColumnItems->Add(new Choice(co->T("Edit touch control layout"), ImageID("I_CONTROLLER")))->OnClick.Add([this](UI::EventParams &) -> void { + mainGroup->Add(new Choice(co->T("Edit touch control layout"), ImageID("I_CONTROLLER")))->OnClick.Add([this](UI::EventParams &) -> void { screenManager()->push(new TouchControlLayoutScreen(gamePath_)); }); } if (g_Config.bEnableCheats && PSP_CoreParameter().fileType != IdentifiedFileType::PPSSPP_GE_DUMP) { - rightColumnItems->Add(new Choice(pa->T("Cheats"), ImageID("I_CHEAT")))->OnClick.Add([this](UI::EventParams &e) { + mainGroup->Add(new Choice(pa->T("Cheats"), ImageID("I_CHEAT")))->OnClick.Add([this](UI::EventParams &e) { screenManager()->push(new CwCheatScreen(gamePath_)); }); } @@ -779,9 +784,8 @@ void GamePauseScreen::CreateViews() { // TODO, also might be nice to show overall compat rating here? // Based on their platform or even cpu/gpu/config. Would add an API for it. if (!portrait) { - AddExtraOptions(rightColumnItems); + AddExtraOptions(mainGroup); } - rightColumnItems->Add(new Spacer(20.0)); Choice *exit; if (g_Config.bPauseMenuExitsEmulator) { auto di = GetI18NCategory(I18NCat::DIALOG); @@ -791,6 +795,7 @@ void GamePauseScreen::CreateViews() { } if (portrait) { + rightColumnItems->Add(new Spacer(20.0)); UI::LinearLayout *exitRow = new UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(0, 0, 0, 0))); rightColumnItems->Add(exitRow); exitRow->Add(exit); @@ -801,7 +806,7 @@ void GamePauseScreen::CreateViews() { exitRow->Add(continueChoice); continueChoice->ReplaceLayoutParams(new UI::LinearLayoutParams(1.0f, Gravity::G_VCENTER)); } else { - rightColumnItems->Add(exit); + rightColumnItems->Add(new ChoiceGroup(""))->Add(exit); } exit->OnClick.Handle(this, &GamePauseScreen::OnExit);