From 734d56a1d3f147a5429d9f98213238c900fcf21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 26 Oct 2026 22:29:03 +0100 Subject: [PATCH] Tweaks to RetroAchievements screen --- Common/UI/View.cpp | 11 ++++++-- Common/UI/View.h | 4 +++ UI/RetroAchievementScreens.cpp | 43 +++++++++++++++++++++++--------- UI/SettingsPagesDialogScreen.cpp | 10 ++++---- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 28b01f8631..be4a31ee52 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -584,9 +584,16 @@ void InfoItem::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz void InfoItem::Draw(UIContext &dc) { Item::Draw(dc); - UI::Style style = HasFocus() ? dc.GetTheme().itemFocusedStyle : dc.GetTheme().infoStyle; + UI::Style style; + if (HasFocus()) { + style = dc.GetTheme().itemFocusedStyle; + } else if (showBG_) { + style = dc.GetTheme().itemStyle; + } else { + style = dc.GetTheme().infoStyle; + } - dc.FillRect(style.background, bounds_); + dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); int paddingX = 12; Bounds padBounds = bounds_.Expand(-paddingX, 0); diff --git a/Common/UI/View.h b/Common/UI/View.h index 0eef740735..d8d4e04aef 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -880,12 +880,16 @@ public: void SetRightText(std::string_view text) { rightText_ = text; } + void SetShowBG(bool showBG) { + showBG_ = showBG; + } protected: void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; private: std::string text_; std::string rightText_; + bool showBG_ = false; }; class AbstractChoiceWithValueDisplay : public Choice { diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index c693a1e38f..ea151e9fd4 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -387,29 +387,40 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) viewGroup->Add(new PaneTitleBar(Path(), sy->T("RetroAchievements"), "/docs/reference/retro-achievements/")); + ChoiceGroupList *groups = viewGroup->Add(new ChoiceGroupList()); + if (!g_Config.bAchievementsEnable) { viewGroup->Add(new NoticeView(NoticeLevel::INFO, ac->T("Achievements are disabled"), "", new LinearLayoutParams(Margins(5)))); } else if (Achievements::IsLoggedIn()) { const rc_client_user_t *info = rc_client_get_user_info(Achievements::GetClient()); + ChoiceGroup *group = groups->Add(new ChoiceGroup()); + + // Hm, we should show a proper player "badge" with the icon and all here. + // In the future, RetroAchievements will support display names. Prepare for that. if (strcmp(info->display_name, info->username) != 0) { - viewGroup->Add(new InfoItem(ac->T("Name"), info->display_name)); + group->Add(new InfoItem(ac->T("Name"), info->display_name))->SetShowBG(true); } - viewGroup->Add(new InfoItem(di->T("Username"), info->username)); + group->Add(new InfoItem(di->T("Username"), info->username))->SetShowBG(true); + // viewGroup->Add(new InfoItem(ac->T("Unread messages"), info.numUnreadMessages)); - viewGroup->Add(new Choice(di->T("Log out")))->OnClick.Add([](UI::EventParams &) -> void { + group->Add(new Choice(di->T("Log out")))->OnClick.Add([](UI::EventParams &) -> void { Achievements::Logout(); }); } else { std::string errorMessage; + + if (Achievements::LoginProblems(&errorMessage)) { viewGroup->Add(new NoticeView(NoticeLevel::WARN, ac->T("Failed logging in to RetroAchievements"), errorMessage)); - viewGroup->Add(new Choice(di->T("Log out")))->OnClick.Add([](UI::EventParams &) -> void { + ChoiceGroup *actions = groups->Add(new ChoiceGroup()); + actions->Add(new Choice(di->T("Log out")))->OnClick.Add([](UI::EventParams &) -> void { Achievements::Logout(); }); } else if (System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) { - viewGroup->Add(new Choice(di->T("Log in")))->OnClick.Add([this](UI::EventParams &) -> void { + ChoiceGroup *actions = groups->Add(new ChoiceGroup()); + actions->Add(new Choice(di->T("Log in")))->OnClick.Add([this](UI::EventParams &) -> void { auto di = GetI18NCategory(I18NCat::DIALOG); std::string title = StringFromFormat("RetroAchievements: %s", di->T_cstr("Log in")); System_AskUsernamePassword(GetRequesterToken(), title, g_Config.sAchievementsUserName, [](std::string_view value, int) { @@ -422,9 +433,11 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) }); } else { // Hack up a temporary quick login-form-ish-thing - viewGroup->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sAchievementsUserName, di->T("Username"), "", 128, screenManager())); - viewGroup->Add(new PopupTextInputChoice(GetRequesterToken(), &password_, di->T("Password"), "", 128, screenManager()))->SetPasswordDisplay(); - Choice *loginButton = viewGroup->Add(new Choice(di->T("Log in"))); + ChoiceGroup *data = groups->Add(new ChoiceGroup()); + data->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sAchievementsUserName, di->T("Username"), "", 128, screenManager())); + data->Add(new PopupTextInputChoice(GetRequesterToken(), &password_, di->T("Password"), "", 128, screenManager()))->SetPasswordDisplay(); + ChoiceGroup *actions = groups->Add(new ChoiceGroup()); + Choice *loginButton = actions->Add(new Choice(di->T("Log in"))); loginButton->OnClick.Add([this](UI::EventParams &) -> void { if (!g_Config.sAchievementsUserName.empty() && !password_.empty()) { Achievements::LoginAsync(g_Config.sAchievementsUserName.c_str(), password_.c_str()); @@ -436,13 +449,15 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) return !g_Config.sAchievementsUserName.empty() && !password_.empty(); }); } - viewGroup->Add(new Choice(ac->T("Register on www.retroachievements.org")))->OnClick.Add([](UI::EventParams &) -> void { + ChoiceGroup *reg = groups->Add(new ChoiceGroup()); + Choice *regLink = reg->Add(new Choice(ac->T("Register on www.retroachievements.org"))); + regLink->OnClick.Add([](UI::EventParams &) -> void { System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://retroachievements.org/createaccount.php"); }); + regLink->SetIconRight(ImageID("I_LINK_OUT")); } using namespace UI; - ChoiceGroupList *groups = viewGroup->Add(new ChoiceGroupList()); ChoiceGroup *settingsGroup = groups->Add(new ChoiceGroup(di->T("Settings"))); settingsGroup->Add(new CheckBox(&g_Config.bAchievementsEnable, ac->T("Achievements enabled")))->OnClick.Add([this](UI::EventParams &e) -> void { Achievements::UpdateSettings(); @@ -452,12 +467,16 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) settingsGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects")))->SetEnabledPtr(&g_Config.bAchievementsEnable); ChoiceGroup *linksGroup = groups->Add(new ChoiceGroup(di->T("Links"))); - linksGroup->Add(new Choice(ac->T("RetroAchievements website"), ImageID("I_LINK_OUT")))->OnClick.Add([](UI::EventParams &) -> void { + Choice *webSite = linksGroup->Add(new Choice(ac->T("RetroAchievements website"))); + webSite->OnClick.Add([](UI::EventParams &) -> void { System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.retroachievements.org/"); }); - linksGroup->Add(new Choice(ac->T("How to use RetroAchievements"), ImageID("I_LINK_OUT")))->OnClick.Add([](UI::EventParams &) -> void { + webSite->SetIconRight(ImageID("I_LINK_OUT")); + Choice *howToUse = linksGroup->Add(new Choice(ac->T("How to use RetroAchievements"))); + howToUse->OnClick.Add([](UI::EventParams &) -> void { System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/docs/reference/retro-achievements"); }); + howToUse->SetIconRight(ImageID("I_LINK_OUT")); } void RetroAchievementsSettingsScreen::CreateCustomizeTab(UI::ViewGroup *viewGroup) { diff --git a/UI/SettingsPagesDialogScreen.cpp b/UI/SettingsPagesDialogScreen.cpp index 4403d0d9d2..a41e4b5bfc 100644 --- a/UI/SettingsPagesDialogScreen.cpp +++ b/UI/SettingsPagesDialogScreen.cpp @@ -151,15 +151,14 @@ void SettingsPagesDialogScreen::CreateSettingsTabContents(int settingsTab, UI::L void SettingsPagesDialogScreen::CreateNavBar(UI::ViewGroup *parent, int settingsTab, const std::vector &titles, const std::string &helpTag) { using namespace UI; const SettingsTab &tab = settingsTabs_[settingsTab]; - // Tall enough for the ITEM_HEIGHT buttons inside the padding, so they're square. - const Margins barPadding(12, 8, 12, 8); - LinearLayout *bar = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT + barPadding.vert(), Margins(0, 0, 8, 0)))); + const Margins barPadding(12, 0, 8, 0); + LinearLayout *bar = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT, Margins(0, 8)))); bar->SetPadding(barPadding); - bar->SetSpacing(0.0f); + bar->SetSpacing(8.0f); // When stacked in portrait, there's no other back button, so it's always there, and leaves the screen from the root page. if (stacked_ || !searchText_.empty() || !pagePaths_[tab.tag].empty()) { - Choice *backButton = bar->Add(new Choice(ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(ITEM_HEIGHT, ITEM_HEIGHT))); + Choice *backButton = bar->Add(new Choice(ImageID("I_CHEVRON_LEFT"), new LinearLayoutParams(ITEM_HEIGHT, ITEM_HEIGHT))); backButton->SetRoundCorners(RoundCorners::All); backButton->OnClick.Add([this, settingsTab](UI::EventParams &) { if (!GoBack(settingsTab)) { @@ -167,6 +166,7 @@ void SettingsPagesDialogScreen::CreateNavBar(UI::ViewGroup *parent, int settings } }); } + // Portrait has no room for the whole path, and the back button goes up it. int firstShownTitle = stacked_ ? (int)titles.size() - 1 : 0; for (int i = firstShownTitle; i < (int)titles.size(); i++) {