From 965b07c527e63d442ade1f099fd452b2e43a2cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 25 Oct 2026 10:22:00 +0100 Subject: [PATCH] A lot more round corner fixes and layout fixes. --- Common/UI/View.h | 2 +- Common/UI/ViewGroup.cpp | 9 +++++++++ Common/UI/ViewGroup.h | 3 ++- UI/BaseScreens.h | 1 - UI/ControlMappingScreen.cpp | 28 +++++++++++++------------ UI/DeveloperToolsScreen.cpp | 8 ++++---- UI/FirmwareScreen.cpp | 6 +++--- UI/GameSettingsScreen.cpp | 36 +++++++++++++++++---------------- UI/MainScreen.cpp | 5 +++-- UI/MainScreen.h | 2 +- UI/MiscScreens.cpp | 9 +++------ UI/MiscViews.cpp | 8 ++++++-- UI/MiscViews.h | 1 + UI/PauseScreen.cpp | 6 +++--- UI/RemoteISOScreen.cpp | 4 ++-- UI/RetroAchievementScreens.cpp | 2 +- UI/SavedataScreen.cpp | 5 +++-- UI/SimpleDialogScreen.cpp | 4 +++- UI/TiltAnalogSettingsScreen.cpp | 2 ++ UI/TouchControlLayoutScreen.cpp | 24 +++++++++++++--------- 20 files changed, 96 insertions(+), 69 deletions(-) diff --git a/Common/UI/View.h b/Common/UI/View.h index e81608c1f9..768bd38414 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -436,7 +436,7 @@ public: virtual bool SubviewFocused(View *view) { return false; } virtual bool CanMoveFocus(FocusMove dir) const { return true; } - virtual void SetRoundCorners(RoundCorners corners) { roundCorners_ = corners; } + virtual void SetRoundCorners(RoundCorners corners = RoundCorners::All) { roundCorners_ = corners; } virtual RoundCorners GetRoundCorners() const { return roundCorners_; } void SetPopupStyle(bool popupStyle) { popupStyle_ = popupStyle; } diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index 390277aa69..9133e8db28 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -836,6 +836,15 @@ void LinearLayout::Layout() { // Applies rounding to the corners of the child views, based on their position in the layout and the orientation. Masked by the outerCorners. // Ignores invisible views. void LinearLayout::ApplyRoundCorners(RoundCorners outerCorners) { + // Easy case first: There's spacing, just apply round corners to all subviews. + if (spacing_ > 0.0f) { + for (View *view : views_) { + view->SetRoundCorners(outerCorners); + } + return; + } + + // Harder: There's no space, so only the first and last view will get rounded corners. bool seenVisible = false; View *lastVisible = nullptr; for (View *view : views_) { diff --git a/Common/UI/ViewGroup.h b/Common/UI/ViewGroup.h index 5c6144c679..8e12d33e68 100644 --- a/Common/UI/ViewGroup.h +++ b/Common/UI/ViewGroup.h @@ -230,6 +230,7 @@ public: } // Applies rounding to the corners of the child views, based on their position in the layout and the orientation. Masked by the outerCorners. + // Note that if the view's spacing is not 0.0f, all views will get the rounded corners since they will appear separate. void ApplyRoundCorners(RoundCorners outerCorners = RoundCorners::All); std::string DescribeLog() const override { return (orientation_ == ORIENT_HORIZONTAL ? "LinearLayoutHoriz: " : "LinearLayoutVert: ") + View::DescribeLog(); } @@ -258,7 +259,7 @@ public: // They have no margins: put them in a ChoiceGroupList, or another layout that spaces them out. class ChoiceGroup : public LinearLayout { public: - ChoiceGroup(std::string_view title, LayoutParams *layoutParams = nullptr); + ChoiceGroup(std::string_view title = "", LayoutParams *layoutParams = nullptr); void Draw(UIContext &dc) override; diff --git a/UI/BaseScreens.h b/UI/BaseScreens.h index c9dd203d38..cb977d091a 100644 --- a/UI/BaseScreens.h +++ b/UI/BaseScreens.h @@ -30,6 +30,5 @@ protected: bool UseImmersiveMode() const override; void sendMessage(UIMessage message, const char *value) override; - void AddStandardBack(UI::ViewGroup *parent); Path gamePath_; }; diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 4207f59168..05ec47eb09 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -237,8 +237,7 @@ void ControlMappingScreen::CreateSettingsViews(UI::ViewGroup *parent) { groups->SetPadding(Margins(0, 12, 0, 0)); groups->SetSpacing(12.0f); - ChoiceGroup *resetChoices = groups->Add(new ChoiceGroup("")); - + ChoiceGroup *resetChoices = groups->Add(new ChoiceGroup()); resetChoices->Add(new Choice(km->T("Clear All")))->OnClick.Add([](UI::EventParams &) { KeyMap::ClearAllMappings(); }); @@ -246,7 +245,7 @@ void ControlMappingScreen::CreateSettingsViews(UI::ViewGroup *parent) { KeyMap::RestoreDefault(); }); - ChoiceGroup *moreChoices = groups->Add(new ChoiceGroup("")); + ChoiceGroup *moreChoices = groups->Add(new ChoiceGroup()); std::string sysName = System_GetProperty(SYSPROP_NAME); // If there's a builtin controller, restore to default should suffice. No need to conf the controller on top. @@ -540,6 +539,7 @@ void AnalogCalibrationScreen::CreateSettingsViews(UI::ViewGroup *scrollContents) auto co = GetI18NCategory(I18NCat::CONTROLS); ChoiceGroupList *groups = scrollContents->Add(new ChoiceGroupList()); + groups->SetSpacing(12.0f); ChoiceGroup *analogSettings = groups->Add(new ChoiceGroup(co->T("Analog Settings"))); @@ -568,7 +568,7 @@ void AnalogCalibrationScreen::CreateSettingsViews(UI::ViewGroup *scrollContents) static const char *responseCurves[] = { "Linear", "Aggressive", "Relaxed", "Wide" }; deadzoneSettings->Add(new PopupMultiChoice(&g_Config.iAnalogResponseCurve, co->T("Response curve"), responseCurves, 0, ARRAY_SIZE(responseCurves), I18NCat::CONTROLS, screenManager())); - groups->Add(new ChoiceGroup(""))->Add(new Choice(co->T("Reset to defaults")))->OnClick.Handle(this, &AnalogCalibrationScreen::OnResetToDefaults); + groups->Add(new ChoiceGroup())->Add(new Choice(co->T("Reset to defaults")))->OnClick.Handle(this, &AnalogCalibrationScreen::OnResetToDefaults); } void AnalogCalibrationScreen::CreateContentViews(UI::ViewGroup *parent) { @@ -908,28 +908,30 @@ void VisualMappingScreen::CreateViews() { using namespace UI; auto km = GetI18NCategory(I18NCat::KEYMAPPING); + auto di = GetI18NCategory(I18NCat::DIALOG); root_ = new LinearLayout(ORIENT_HORIZONTAL); constexpr float leftColumnWidth = 200.0f; - LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(leftColumnWidth, FILL_PARENT, Margins(10, 0, 0, 10))); - leftColumn->Add(new Choice(km->T("Bind All")))->OnClick.Handle(this, &VisualMappingScreen::OnBindAll); - leftColumn->Add(new CheckBox(&replace_, km->T("Replace"), "")); + LinearLayout *leftColumn = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(leftColumnWidth, FILL_PARENT, Margins(10, 10, 0, 10)))); - leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f))); - AddStandardBack(leftColumn); + ChoiceGroup *actions = leftColumn->Add(new ChoiceGroup()); + + actions->Add(new Choice(km->T("Bind All")))->OnClick.Handle(this, &VisualMappingScreen::OnBindAll); + actions->Add(new CheckBox(&replace_, km->T("Replace"), "")); + + Choice *backButton = leftColumn->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"))); + backButton->OnClick.Handle(this, &UIScreen::OnBack); + backButton->SetRoundCorners(); // TODO: Properly use layout instead of querying bounds. Bounds bounds = GetLayoutBounds(*screenManager()->getUIContext()); // Account for left side. bounds.w -= leftColumnWidth + 10.0f; - AnchorLayout *rightColumn = new AnchorLayout(new LinearLayoutParams(bounds.w, FILL_PARENT, 1.0f)); + AnchorLayout *rightColumn = root_->Add(new AnchorLayout(new LinearLayoutParams(bounds.w, FILL_PARENT, 1.0f))); psp_ = rightColumn->Add(new MockPSP(new AnchorLayoutParams(bounds.centerX(), bounds.centerY(), NONE, NONE, Centering::Both))); psp_->ButtonClick.Handle(this, &VisualMappingScreen::OnMapButton); - - root_->Add(leftColumn); - root_->Add(rightColumn); } bool VisualMappingScreen::key(const KeyInput &key) { diff --git a/UI/DeveloperToolsScreen.cpp b/UI/DeveloperToolsScreen.cpp index 8a36a73f3e..ab2288dc5c 100644 --- a/UI/DeveloperToolsScreen.cpp +++ b/UI/DeveloperToolsScreen.cpp @@ -255,7 +255,7 @@ void DeveloperToolsScreen::CreateTestsTab(UI::LinearLayout *list) { using namespace UI; auto dev = GetI18NCategory(I18NCat::DEVELOPER); - ChoiceGroup *tests = list->Add(new ChoiceGroup("")); + ChoiceGroup *tests = list->Add(new ChoiceGroup()); tests->Add(new Choice(dev->T("Touchscreen Test")))->OnClick.Add([this](UI::EventParams &e) { screenManager()->push(new TouchTestScreen(gamePath_)); // Handle touchscreen test event @@ -297,7 +297,7 @@ void DeveloperToolsScreen::CreateHLETab(UI::LinearLayout *list) { using namespace UI; auto dev = GetI18NCategory(I18NCat::DEVELOPER); - ChoiceGroup *atracSettings = list->Add(new ChoiceGroup("")); + ChoiceGroup *atracSettings = list->Add(new ChoiceGroup()); atracSettings->Add(new CheckBox(&g_Config.bUseOldAtrac, dev->T("Use the old sceAtrac implementation"))); ChoiceGroup *disableHLE = list->Add(new ChoiceGroup(dev->T("Disable HLE"))); @@ -388,7 +388,7 @@ void DeveloperToolsScreen::CreateMIPSTracerTab(UI::LinearLayout *list) { void DeveloperToolsScreen::CreateAudioTab(UI::LinearLayout *list) { using namespace UI; auto dev = GetI18NCategory(I18NCat::DEVELOPER); - ChoiceGroup *audioSettings = list->Add(new ChoiceGroup("")); + ChoiceGroup *audioSettings = list->Add(new ChoiceGroup()); audioSettings->Add(new CheckBox(&g_Config.bForceFfmpegForAudioDec, dev->T("Use FFMPEG for all compressed audio"))); } @@ -396,7 +396,7 @@ void DeveloperToolsScreen::CreateUITab(UI::LinearLayout *list) { using namespace UI; auto dev = GetI18NCategory(I18NCat::DEVELOPER); UIContext *uiContext = screenManager()->getUIContext(); - ChoiceGroup *atlasGroup = list->Add(new ChoiceGroup("")); + ChoiceGroup *atlasGroup = list->Add(new ChoiceGroup()); atlasGroup->Add(new Choice(dev->T("Reload UI atlas")))->OnClick.Add([uiContext](UI::EventParams &) { uiContext->InvalidateAtlas(); }); diff --git a/UI/FirmwareScreen.cpp b/UI/FirmwareScreen.cpp index 5dc760f947..4ea87f0d99 100644 --- a/UI/FirmwareScreen.cpp +++ b/UI/FirmwareScreen.cpp @@ -119,14 +119,14 @@ void FirmwareScreen::CreateSettingsViews(UI::ViewGroup *parent) { sy->T("XMBUnsupportedVersion", "Only firmware 6.61 can boot the XMB so far"))); } - ChoiceGroup *launchGroup = groups->Add(new ChoiceGroup("")); + ChoiceGroup *launchGroup = groups->Add(new ChoiceGroup()); Choice *launch = launchGroup->Add(new Choice(sy->T("Launch XMB"), ImageID("I_PLAY"))); - ChoiceGroup *settings = groups->Add(new ChoiceGroup("")); + ChoiceGroup *settings = groups->Add(new ChoiceGroup()); settings->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."))); - ChoiceGroup *actions = groups->Add(new ChoiceGroup("")); + ChoiceGroup *actions = groups->Add(new ChoiceGroup()); launch->OnClick.Add([this](UI::EventParams &) { LaunchVSH(); }); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0066033e07..943098de4f 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -650,7 +650,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { auto di = GetI18NCategory(I18NCat::DIALOG); #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) - ChoiceGroup *systemIntegrationSettings = audioSettings->Add(new ChoiceGroup("")); // Don't need a title. + ChoiceGroup *systemIntegrationSettings = audioSettings->Add(new ChoiceGroup()); // Don't need a title. #if PPSSPP_PLATFORM(IOS) CheckBox *respectSilentMode = systemIntegrationSettings->Add(new CheckBox(&g_Config.bAudioRespectSilentMode, a->T("Respect silent mode"))); respectSilentMode->OnClick.Add([=](EventParams &e) { @@ -705,7 +705,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { g_BackgroundAudio.SFX().Play(UI::UISound::ACHIEVEMENT_UNLOCKED, achievementVolume); }); - ChoiceGroup *uiSoundSettings = audioSettings->Add(new ChoiceGroup("")); + ChoiceGroup *uiSoundSettings = audioSettings->Add(new ChoiceGroup()); uiSoundSettings->Add(new CheckBox(&g_Config.bUISound, a->T("UI sound"))); PopupSliderChoice *uiVolume = uiSoundSettings->Add(new PopupSliderChoice(&g_Config.iUIVolume, 0, VOLUMEHI_FULL, Config::GetDefaultValueInt(&g_Config.iUIVolume), a->T("UI volume"), screenManager())); @@ -785,8 +785,6 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { const bool isWindows = false; if (sdlAudio) { audioBackendSettings->Add(new CheckBox(&g_Config.bAutoSwitchAudioDevice, a->T("Use new audio devices automatically"))); - } else { - audioBackendSettings->Add(new ItemHeader(a->T("Audio backend"))); } #if PPSSPP_PLATFORM(ANDROID) @@ -1887,22 +1885,26 @@ void GestureMappingScreen::CreateGestureTab(UI::LinearLayout *vert, int zoneInde flags |= TopBarFlags::Portrait; } vert->Add(new TopBar(*screenManager()->getUIContext(), flags, ApplySafeSubstitutions("%1: %2", co->T("Gesture"), di->T(zoneIndex == 0 ? "Left side" : "Right side")))); - vert->Add(new CheckBox(&zone.bGestureControlEnabled, co->T("Enable gesture control"))); - vert->Add(new ItemHeader(co->T("Swipe"))); - vert->Add(new PopupMultiChoice(&zone.iSwipeUp, mc->T("Swipe Up"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); - vert->Add(new PopupMultiChoice(&zone.iSwipeDown, mc->T("Swipe Down"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); - vert->Add(new PopupMultiChoice(&zone.iSwipeLeft, mc->T("Swipe Left"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); - vert->Add(new PopupMultiChoice(&zone.iSwipeRight, mc->T("Swipe Right"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); - vert->Add(new PopupSliderChoiceFloat(&zone.fSwipeSensitivity, 0.01f, 2.0f, 1.0f, co->T("Swipe sensitivity"), 0.01f, screenManager(), "x"))->SetEnabledPtr(&zone.bGestureControlEnabled); - vert->Add(new PopupSliderChoiceFloat(&zone.fSwipeSmoothing, 0.0f, 0.95f, 0.3f, co->T("Swipe smoothing"), 0.05f, screenManager(), "x"))->SetEnabledPtr(&zone.bGestureControlEnabled); + ChoiceGroupList *list = vert->Add(new ChoiceGroupList()); - vert->Add(new ItemHeader(co->T("Double tap"))); - vert->Add(new PopupMultiChoice(&zone.iDoubleTapGesture, mc->T("Double tap button"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager())); + list->Add(new CheckBox(&zone.bGestureControlEnabled, co->T("Enable gesture control")))->SetRoundCorners(); - vert->Add(new ItemHeader(co->T("Analog Stick"))); - vert->Add(new CheckBox(&zone.bAnalogGesture, co->T("Enable analog stick gesture"))); - vert->Add(new PopupSliderChoiceFloat(&zone.fAnalogGestureSensitivity, 0.01f, 5.0f, 1.0f, co->T("Sensitivity"), 0.01f, screenManager(), "x"))->SetEnabledPtr(&zone.bAnalogGesture); + ChoiceGroup *swipeGroup = list->Add(new ChoiceGroup(co->T("Swipe"))); + + swipeGroup->Add(new PopupMultiChoice(&zone.iSwipeUp, mc->T("Swipe Up"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); + swipeGroup->Add(new PopupMultiChoice(&zone.iSwipeDown, mc->T("Swipe Down"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); + swipeGroup->Add(new PopupMultiChoice(&zone.iSwipeLeft, mc->T("Swipe Left"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); + swipeGroup->Add(new PopupMultiChoice(&zone.iSwipeRight, mc->T("Swipe Right"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&zone.bGestureControlEnabled); + swipeGroup->Add(new PopupSliderChoiceFloat(&zone.fSwipeSensitivity, 0.01f, 2.0f, 1.0f, co->T("Swipe sensitivity"), 0.01f, screenManager(), "x"))->SetEnabledPtr(&zone.bGestureControlEnabled); + swipeGroup->Add(new PopupSliderChoiceFloat(&zone.fSwipeSmoothing, 0.0f, 0.95f, 0.3f, co->T("Swipe smoothing"), 0.05f, screenManager(), "x"))->SetEnabledPtr(&zone.bGestureControlEnabled); + + ChoiceGroup *doubleTapGroup = list->Add(new ChoiceGroup(co->T("Double tap"))); + doubleTapGroup->Add(new PopupMultiChoice(&zone.iDoubleTapGesture, mc->T("Double tap button"), gestureButton, 0, ARRAY_SIZE(gestureButton), I18NCat::MAPPABLECONTROLS, screenManager())); + + ChoiceGroup *analogGroup = list->Add(new ChoiceGroup(co->T("Analog Stick"))); + analogGroup->Add(new CheckBox(&zone.bAnalogGesture, co->T("Enable analog stick gesture"))); + analogGroup->Add(new PopupSliderChoiceFloat(&zone.fAnalogGestureSensitivity, 0.01f, 5.0f, 1.0f, co->T("Sensitivity"), 0.01f, screenManager(), "x"))->SetEnabledPtr(&zone.bAnalogGesture); } RestoreSettingsScreen::RestoreSettingsScreen(std::string_view title) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index da8f804543..1a2fbce057 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -345,7 +345,7 @@ private: const bool portrait_; }; -void MainScreen::CreateMainButtons(UI::ViewGroup *parent, bool portrait) { +void MainScreen::CreateMainButtons(UI::LinearLayout *parent, bool portrait) { using namespace UI; auto mm = GetI18NCategory(I18NCat::MAINMENU); auto di = GetI18NCategory(I18NCat::DIALOG); @@ -368,13 +368,14 @@ void MainScreen::CreateMainButtons(UI::ViewGroup *parent, bool portrait) { gold->SetImageScale(0.6f); // for the left icon. gold->SetShine(true); } + parent->ApplyRoundCorners(); return; } else { ChoiceGroupList *buttons = parent->Add(new ChoiceGroupList()); buttons->SetPadding(Margins(0)); buttons->SetSpacing(12.0f); - ChoiceGroup *mainButtons = buttons->Add(new ChoiceGroup("")); + ChoiceGroup *mainButtons = buttons->Add(new ChoiceGroup()); if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { mainButtons->Add(new Choice(mm->T("Load", "Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); diff --git a/UI/MainScreen.h b/UI/MainScreen.h index bf6f6dc4f3..18e132917a 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -59,7 +59,7 @@ protected: void CreateViews() override; void CreateRecentTab(); GameBrowser *CreateBrowserTab(const Path &path, std::string_view title, std::string_view howToTitle, std::string_view howToUri, BrowseFlags browseFlags, int *viewMode, float *scrollPos); - void CreateMainButtons(UI::ViewGroup *parent, bool vertical); + void CreateMainButtons(UI::LinearLayout *parent, bool vertical); void DrawBackground(UIContext &dc) override; void update() override; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 7f35973118..c91f302eb0 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -169,12 +169,6 @@ void UIBaseScreen::sendMessage(UIMessage message, const char *value) { HandleCommonMessages(message, value, screenManager(), this); } -void UIBaseDialogScreen::AddStandardBack(UI::ViewGroup *parent) { - using namespace UI; - auto di = GetI18NCategory(I18NCat::DIALOG); - parent->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(190, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); -} - PromptScreen::PromptScreen(const Path &gamePath, std::string_view message, std::string_view yesButtonText, std::string_view noButtonText, std::function callback) : UIBaseDialogScreen(gamePath), message_(message), callback_(callback) { yesButtonText_ = yesButtonText; @@ -609,6 +603,9 @@ void CreditsScreen::CreateDialogViews(UI::ViewGroup *parent) { right->Add(new Spacer(0.0f, new LinearLayoutParams(1.0f))); } + left->ApplyRoundCorners(); + right->ApplyRoundCorners(); + int rightYOffset = 0; if (!System_GetPropertyBool(SYSPROP_APP_GOLD)) { ScreenManager *sm = screenManager(); diff --git a/UI/MiscViews.cpp b/UI/MiscViews.cpp index ce6624967f..3aa57bf0e2 100644 --- a/UI/MiscViews.cpp +++ b/UI/MiscViews.cpp @@ -61,6 +61,7 @@ TopBar::TopBar(const UIContext &ctx, TopBarFlags flags, std::string_view title, backButton_->OnClick.Add([](UI::EventParams &e) { e.bubbleResult = DR_BACK; }); + backButton_->SetRoundCorners(); } else { Add(new Spacer(4.0f)); } @@ -78,6 +79,7 @@ TopBar::TopBar(const UIContext &ctx, TopBarFlags flags, std::string_view title, contextMenuButton_->OnClick.Add([this](UI::EventParams &e) { this->OnContextMenuClick.Trigger(e); }); + contextMenuButton_->SetRoundCorners(); } } @@ -299,7 +301,7 @@ void GameInfoBGView::Draw(UIContext &dc) { SettingHint::SettingHint(std::string_view text, UI::View *setting) : UI::TextView(text, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT)), setting_(setting) { SetTextSize(UI::TextSize::Tiny); - SetPadding(UI::Margins(14, 0, 12, 8)); + SetPadding(UI::Margins(12, 0, 12, 8)); SetAlign(FLAG_WRAP_TEXT); } @@ -307,7 +309,9 @@ void SettingHint::Draw(UIContext &dc) { const bool enabled = setting_ ? setting_->IsEnabled() : true; const UI::Style &style = enabled ? dc.GetTheme().itemStyle : dc.GetTheme().itemDisabledStyle; SetTextColor(style.fgColor); // bit hacky but works - dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); + if (setting_) { + dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); + } UI::TextView::Draw(dc); } diff --git a/UI/MiscViews.h b/UI/MiscViews.h index 50310bcf8c..bc719c6199 100644 --- a/UI/MiscViews.h +++ b/UI/MiscViews.h @@ -92,6 +92,7 @@ protected: class SettingHint : public UI::TextView { public: + // If setting is null, it's a "global hint", used outside of ChoiceGroups, usually after one. SettingHint(std::string_view text, UI::View *setting); std::string DescribeText() const override { return setting_ ? setting_->DescribeText() : ""; } // So that descriptions show up in searches under their parent views void Draw(UIContext &dc) override; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 56da81bb44..aed72a1238 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -714,7 +714,7 @@ void GamePauseScreen::CreateViews() { LinearLayout *rightColumnItems = new ChoiceGroupList(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); buttonColumn->Add(rightColumnItems); - ChoiceGroup *topGroup = rightColumnItems->Add(new ChoiceGroup("")); + ChoiceGroup *topGroup = rightColumnItems->Add(new ChoiceGroup()); if (__KernelIsRunningVSH()) { // The XMB notices discs coming and going by itself, like a PSP's. if (__UmdIsInserted()) { @@ -743,7 +743,7 @@ void GamePauseScreen::CreateViews() { topGroup->SetVisibility(V_GONE); } - ChoiceGroup *mainGroup = rightColumnItems->Add(new ChoiceGroup("")); + ChoiceGroup *mainGroup = rightColumnItems->Add(new ChoiceGroup()); if (g_paramSFO.IsValid() && g_Config.HasGameConfig(g_paramSFO.GetDiscID())) { mainGroup->Add(new Choice(pa->T("Game Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); auto pa = GetI18NCategory(I18NCat::PAUSE); @@ -804,7 +804,7 @@ void GamePauseScreen::CreateViews() { exitRow->Add(continueChoice); continueChoice->ReplaceLayoutParams(new UI::LinearLayoutParams(1.0f, Gravity::G_VCENTER)); } else { - rightColumnItems->Add(new ChoiceGroup(""))->Add(exit); + rightColumnItems->Add(new ChoiceGroup())->Add(exit); } exit->OnClick.Handle(this, &GamePauseScreen::OnExit); diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index c28d4f0291..b72846cee6 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -403,7 +403,7 @@ void RemoteISOScreen::CreateSettingsTab(UI::ViewGroup *remoteisoSettings) { g_Config.iRemoteISOShareType = (int)RemoteISOShareType::RECENT; } - ChoiceGroup *remoteSettings = remoteisoSettings->Add(new ChoiceGroup("")); + ChoiceGroup *remoteSettings = remoteisoSettings->Add(new ChoiceGroup()); UI::Choice *remoteServer = new PopupTextInputChoice(GetRequesterToken(), &g_Config.sLastRemoteISOServer, ri->T("Remote Server"), "", 255, screenManager()); remoteSettings->Add(remoteServer); @@ -421,7 +421,7 @@ void RemoteISOScreen::CreateSettingsTab(UI::ViewGroup *remoteisoSettings) { remoteSettings->Add(remoteSubdir); remoteSubdir->SetEnabledPtr(&g_Config.bRemoteISOManual); - ChoiceGroup *serverSettings = remoteisoSettings->Add(new ChoiceGroup("")); + ChoiceGroup *serverSettings = remoteisoSettings->Add(new ChoiceGroup()); PopupSliderChoice *portChoice = new PopupSliderChoice(&g_Config.iRemoteISOPort, 0, 65535, 0, ri->T("Local Server Port", "Local Server Port"), 100, screenManager()); serverSettings->Add(portChoice); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 8bf03d1cec..2b5395b4d3 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -496,7 +496,7 @@ void RetroAchievementsSettingsScreen::CreateDeveloperToolsTab(UI::ViewGroup *vie using namespace UI; viewGroup->Add(new PaneTitleBar(Path(), sy->T("Developer Tools"), "/docs/reference/retro-achievements/")); - ChoiceGroup *devSettings = viewGroup->Add(new ChoiceGroupList())->Add(new ChoiceGroup("")); + ChoiceGroup *devSettings = viewGroup->Add(new ChoiceGroupList())->Add(new ChoiceGroup()); #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION devSettings->Add(new CheckBox(&g_Config.bAchievementsEnableRAIntegration, ac->T("Enable RAIntegration (for achievement development)")))->SetEnabledPtr(&g_Config.bAchievementsEnable); #endif diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 230874aa7d..0e0977e8dc 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -666,8 +666,9 @@ void SavedataScreen::CreateExtraButtons(UI::ViewGroup *verticalLayout, int margi using namespace UI; if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { auto di = GetI18NCategory(I18NCat::DIALOG); - verticalLayout->Add(new Choice(di->T("Search"), ImageID("I_SEARCH"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0, 0, margins, margins)))) - ->OnClick.Handle(this, &SavedataScreen::OnSearch); + Choice *searchButton = verticalLayout->Add(new Choice(di->T("Search"), ImageID("I_SEARCH"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0, 0, margins, margins)))); + searchButton->OnClick.Handle(this, &SavedataScreen::OnSearch); + searchButton->SetRoundCorners(); } } diff --git a/UI/SimpleDialogScreen.cpp b/UI/SimpleDialogScreen.cpp index d3867598dd..6223efe844 100644 --- a/UI/SimpleDialogScreen.cpp +++ b/UI/SimpleDialogScreen.cpp @@ -156,7 +156,9 @@ void UITwoPaneBaseDialogScreen::CreateViews() { if (flags_ & TwoPaneFlags::NoTopbarInLandscape) { // We still need a back button. - settingsPane->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK")))->OnClick.Handle(this, &UIScreen::OnBack); + Choice *backButton = settingsPane->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"))); + backButton->OnClick.Handle(this, &UIScreen::OnBack); + backButton->SetRoundCorners(); settingsPane->Add(new Spacer(8.0f)); } CreateSettingsViews(settingsPane); diff --git a/UI/TiltAnalogSettingsScreen.cpp b/UI/TiltAnalogSettingsScreen.cpp index e84234529c..e8a724923a 100644 --- a/UI/TiltAnalogSettingsScreen.cpp +++ b/UI/TiltAnalogSettingsScreen.cpp @@ -97,6 +97,8 @@ void TiltAnalogSettingsScreen::CreateSettingsViews(UI::ViewGroup *settings) { GamepadUpdateOpacity(1.0f); ChoiceGroupList *groups = settings->Add(new ChoiceGroupList()); + groups->SetSpacing(12.0f); + auto enabledFunc = [=]() -> bool { return g_Config.iTiltInputType != 0; }; diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index c4b778f865..cd845f2f4a 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -638,7 +638,11 @@ void TouchControlLayoutScreen::CreateViews() { ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(leftColumnWidth, FILL_PARENT))); leftColumnScroll->SetAlignOpposite(true); - LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(Margins(12.0f, 0.0f)))); + + ChoiceGroupList *leftColumn = leftColumnScroll->Add(new ChoiceGroupList()); + + // More compact spacing since this is not a full on settings view. + leftColumn->SetSpacing(12.0f); mode_ = new ChoiceStrip(ORIENT_VERTICAL); mode_->AddChoice(di->T("Move"), ImageID("I_MOVE")); @@ -650,21 +654,23 @@ void TouchControlLayoutScreen::CreateViews() { layoutView_->mode_ = mode; } }); - - CheckBox *snap = new CheckBox(&g_Config.bTouchSnapToGrid, di->T("Snap")); - PopupSliderChoice *gridSize = new PopupSliderChoice(&g_Config.iTouchSnapGridSize, 2, 256, 64, di->T("Grid"), screenManager(), ""); - gridSize->SetEnabledPtr(&g_Config.bTouchSnapToGrid); + mode_->ApplyRoundCorners(); leftColumn->Add(mode_); leftColumn->Add(new Choice(co->T("Customize")))->OnClick.Add([this](UI::EventParams &e) { screenManager()->push(new TouchControlVisibilityScreen(gamePath_)); }); - leftColumn->Add(snap); - leftColumn->Add(gridSize); + + ChoiceGroup *gridControls = leftColumn->Add(new ChoiceGroup()); + CheckBox *snap = gridControls->Add(new CheckBox(&g_Config.bTouchSnapToGrid, di->T("Snap"))); + PopupSliderChoice *gridSize = gridControls->Add(new PopupSliderChoice(&g_Config.iTouchSnapGridSize, 2, 256, 64, di->T("Grid"), screenManager(), "")); + gridSize->SetEnabledPtr(&g_Config.bTouchSnapToGrid); + leftColumn->Add(new Choice(di->T("Reset")))->OnClick.Handle(this, &TouchControlLayoutScreen::OnReset); - leftColumn->Add(new Spacer(12.0f)); leftColumn->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK")))->OnClick.Handle(this, &UIScreen::OnBack); - leftColumn->Add(new Spacer(0.0f)); + + leftColumn->ApplyRoundCorners(); + leftColumnScroll->SetShadows(false); LinearLayout* rightColumn = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f, Margins(0.0f, 12.0f, 12.0f, 12.0f))));