From bca75c73815d39efeadc4175eba5c1aa983a45ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 3 Nov 2026 19:22:58 +0100 Subject: [PATCH] Some popup stylin' --- Common/UI/PopupScreens.cpp | 27 +++++++++++---------------- Common/UI/View.cpp | 11 +++++------ Common/UI/ViewGroup.cpp | 9 ++++++++- Common/UI/ViewGroup.h | 7 +++++++ UI/GameButton.cpp | 2 ++ UI/MainScreen.cpp | 29 ++++++++++++++--------------- 6 files changed, 47 insertions(+), 38 deletions(-) diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index 9c49c9f7a0..5f02810e5d 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -153,6 +153,7 @@ void PopupScreen::CreateViews() { using namespace UI; UIContext &dc = *screenManager()->getUIContext(); + // This places the actual popup in the center of the screen. AnchorLayout *anchor = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); anchor->Overflow(false); root_ = anchor; @@ -184,16 +185,16 @@ void PopupScreen::CreateViews() { (layoutBounds.w - RootMargins().horiz()) * 0.5, y, NONE, NONE, vCentering | Centering::Horizontal); } - box_ = new LinearLayout(ORIENT_VERTICAL, anchorParams); + // Box is the actual popup shape. + box_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, anchorParams)); - root_->Add(box_); box_->SetBG(dc.GetTheme().popupStyle.background); box_->SetHasDropShadow(hasDropShadow_); box_->SetRadiusFactor(1.44f); // Since we scale a bit, make the dropshadow bleed past the edges. box_->SetDropShadowExpand(std::max(g_display.dp_xres, g_display.dp_yres)); box_->SetSpacing(0.0f); - box_->SetPadding(Margins(8)); + box_->SetPadding(Margins(12)); if (!title_.empty()) { View *title = new PopupHeader(title_); @@ -214,21 +215,19 @@ void PopupScreen::CreateViews() { if (ShowButtons() && !button1_.empty()) { // And the two buttons at the bottom. LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(200, WRAP_CONTENT)); - buttonRow->SetSpacing(0); - Margins buttonMargins(5, 5); - + buttonRow->SetSpacing(8); // Adjust button order to the platform default. if (System_GetPropertyBool(SYSPROP_OK_BUTTON_LEFT)) { - defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f, buttonMargins))); + defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f))); defaultButton_->OnClick.Handle(this, &UIScreen::OnOK); if (!button2_.empty()) { - buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &UIScreen::OnCancel); + buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &UIScreen::OnCancel); } } else { if (!button2_.empty()) { - buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &UIScreen::OnCancel); + buttonRow->Add(new Choice(button2_, button2Image_, new LinearLayoutParams(1.0f)))->OnClick.Handle(this, &UIScreen::OnCancel); } - defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f, buttonMargins))); + defaultButton_ = buttonRow->Add(new Choice(button1_, button1Image_, new LinearLayoutParams(1.0f))); defaultButton_->OnClick.Handle(this, &UIScreen::OnOK); } @@ -256,12 +255,8 @@ void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) { } void MessagePopupScreen::OnCompleted(DialogResult result) { - if (result == DR_OK) { - if (callback_) - callback_(true); - } else { - if (callback_) - callback_(false); + if (callback_) { + callback_(result == DR_OK); } } diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 060691c2da..d9901f28f2 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -714,22 +714,21 @@ void BorderView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec hor } void PopupHeader::Draw(UIContext &dc) { - const float paddingHorizontal = 12; - const float availableWidth = bounds_.w - paddingHorizontal * 2; + const float availableWidth = bounds_.w; float tw, th; - dc.SetFontStyle(dc.GetTheme().uiFont); + dc.SetFontStyle(dc.GetTheme().uiFontBig); dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0); float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; - float tx = paddingHorizontal; + float tx = 0; if (availableWidth < tw) { float overageRatio = 1.5f * availableWidth * 1.0f / tw; tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth; Bounds tb = bounds_; - tb.x = bounds_.x + paddingHorizontal; - tb.w = bounds_.w - paddingHorizontal * 2; + tb.x = bounds_.x; + tb.w = bounds_.w; dc.PushScissor(tb); } diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index c0de3143c2..f35ed4b6d7 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -885,7 +885,14 @@ ChoiceGroup::ChoiceGroup(std::string_view title, LayoutParams *layoutParams) ChoiceGroupList::ChoiceGroupList(LayoutParams *layoutParams) : LinearLayoutList(ORIENT_VERTICAL, layoutParams ? layoutParams : new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)) { - SetPadding(Margins(12, 12, 8, 12)); + SetPadding(Margins(12, 12, 12, 12)); + SetSpacing(24.0f); +} + +PopupChoiceGroupList::PopupChoiceGroupList(LayoutParams *layoutParams) + : LinearLayoutList(ORIENT_VERTICAL, layoutParams ? layoutParams : new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)) { + // Padding is already present in the popup itself. Just add a little more. + SetPadding(Margins(0)); SetSpacing(24.0f); } diff --git a/Common/UI/ViewGroup.h b/Common/UI/ViewGroup.h index bb4726219f..78084527c3 100644 --- a/Common/UI/ViewGroup.h +++ b/Common/UI/ViewGroup.h @@ -276,6 +276,13 @@ public: ChoiceGroupList(LayoutParams *layoutParams = nullptr); }; +// A vertical list that spaces out the ChoiceGroups in it and keeps them off its edges. +// This one is adjusted for popups (i.e. smaller margins and spacing). +class PopupChoiceGroupList : public LinearLayoutList { +public: + PopupChoiceGroupList(LayoutParams *layoutParams = nullptr); +}; + // GridLayout is a little different from the Android layout. This one has fixed size // rows and columns, filled row by row. Items are not allowed to deviate from the set sizes. struct GridLayoutSettings { diff --git a/UI/GameButton.cpp b/UI/GameButton.cpp index 567ad237af..56a0675833 100644 --- a/UI/GameButton.cpp +++ b/UI/GameButton.cpp @@ -342,6 +342,8 @@ 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(); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index c8548bbbc4..be16799532 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1037,29 +1037,28 @@ void GridSettingsPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { auto sy = GetI18NCategory(I18NCat::SYSTEM); auto mm = GetI18NCategory(I18NCat::MAINMENU); - ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f)); - LinearLayout *items = new LinearLayoutList(ORIENT_VERTICAL); - items->SetSpacing(0.0f); + ScrollView *scroll = parent->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f))); + + PopupChoiceGroupList *groupList = scroll->Add(new PopupChoiceGroupList()); + + ChoiceGroup *group = groupList->Add(new ChoiceGroup()); // Same order as GameBrowserViewMode. static const char *defaultTabs[] = { "Recent", "Games", "Homebrew & Demos" }; - items->Add(new PopupMultiChoice(&g_Config.iDefaultTab, sy->T("Default tab"), defaultTabs, 0, ARRAY_SIZE(defaultTabs), I18NCat::MAINMENU, screenManager())); + group->Add(new PopupMultiChoice(&g_Config.iDefaultTab, sy->T("Default tab"), defaultTabs, 0, ARRAY_SIZE(defaultTabs), I18NCat::MAINMENU, screenManager())); - items->Add(new ItemHeader(sy->T("Icon size"))); - items->Add(new Choice(sy->T("Increase size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridPlusClick); - items->Add(new Choice(sy->T("Decrease size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridMinusClick); + ChoiceGroup *iconSizeGroup = groupList->Add(new ChoiceGroup(sy->T("Icon size"))); + iconSizeGroup->Add(new Choice(sy->T("Increase size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridPlusClick); + iconSizeGroup->Add(new Choice(sy->T("Decrease size")))->OnClick.Handle(this, &GridSettingsPopupScreen::GridMinusClick); - items->Add(new ItemHeader(sy->T("Display Extra Info"))); - items->Add(new CheckBox(&g_Config.bShowIDOnGameIcon, sy->T("Show ID"))); - items->Add(new CheckBox(&g_Config.bShowRegionOnGameIcon, sy->T("Show region flag"))); + ChoiceGroup *extraInfoGroup = groupList->Add(new ChoiceGroup(sy->T("Display Extra Info"))); + extraInfoGroup->Add(new CheckBox(&g_Config.bShowIDOnGameIcon, sy->T("Show ID"))); + extraInfoGroup->Add(new CheckBox(&g_Config.bShowRegionOnGameIcon, sy->T("Show region flag"))); if (g_Config.iMaxRecent > 0) { - items->Add(new ItemHeader(sy->T("Clear Recent"))); - items->Add(new Choice(sy->T("Clear Recent Games List")))->OnClick.Handle(this, &GridSettingsPopupScreen::OnRecentClearClick); + ChoiceGroup *recentGroup = groupList->Add(new ChoiceGroup(sy->T("Clear Recent"))); + recentGroup->Add(new Choice(sy->T("Clear Recent Games List")))->OnClick.Handle(this, &GridSettingsPopupScreen::OnRecentClearClick); } - - scroll->Add(items); - parent->Add(scroll); } void GridSettingsPopupScreen::GridPlusClick(UI::EventParams &e) {