diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index 6dd0407dc3..5009a5c739 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -17,15 +17,10 @@ namespace UI { PopupScreen::PopupScreen(std::string_view title, std::string_view button1, std::string_view button2) - : title_(title) { + : title_(title), button1_(button1), button2_(button2) { auto di = GetI18NCategory(I18NCat::DIALOG); - if (!button1.empty()) - button1_ = di->T(button1); - if (!button2.empty()) - button2_ = di->T(button2); - - // Auto-assign images. - if (button1 == "Delete") { + // Auto-assign images. A bit hack to have this here. + if (button1 == di->T("Delete") || button1 == di->T("Move to trash")) { button1Image_ = ImageID("I_TRASHCAN"); } diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 3e446169ca..8e5cb7870e 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -468,15 +468,14 @@ void Choice::ClickInternal() { void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { float totalW = 0.0f; float totalH = 0.0f; - int paddingLeft = 12; - int paddingRight = 12; - if (!text_.empty() && !hideTitle_) { + int paddingLeft = 12; + int paddingRight = 12; if (rightIconImage_.isValid()) { paddingRight = ITEM_HEIGHT; } - float availWidth = horiz.size - paddingLeft - paddingRight - textPadding_.horiz(); + float availWidth = horiz.size - paddingLeft - paddingRight - textPadding_.horiz() - totalW; if (availWidth < 0.0f) { // Let it have as much space as it needs. availWidth = MAX_ITEM_SIZE; @@ -488,19 +487,20 @@ void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, float textW = 0.0f, textH = 0.0f; dc.MeasureTextRect(dc.GetTheme().uiFont, scale, scale, text_, availBounds, &textW, &textH, FLAG_WRAP_TEXT); totalH = std::max(totalH, textH); + totalW += textW; if (image_.isValid()) { - paddingLeft = ITEM_HEIGHT; + totalW += 12; + totalW += totalH; } - totalW = paddingLeft + textW + paddingRight + textPadding_.horiz(); } else { if (image_.isValid()) { dc.Draw()->GetAtlas()->measureImage(image_, &w, &h); - totalW = w * imgScale_ + paddingLeft + paddingRight; + totalW = w * imgScale_ + 6; totalH = h * imgScale_; } } - w = totalW; + w = totalW + (text_.empty() ? 16 : 24); h = totalH + 16; h = std::max(h, ITEM_HEIGHT); } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 5e9ea4a3e1..32c6cea58c 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1002,9 +1002,10 @@ void EmuScreen::ProcessVKey(VirtKey virtKey) { std::string confirmExitMessage = GetConfirmExitMessage(); if (!confirmExitMessage.empty()) { auto di = GetI18NCategory(I18NCat::DIALOG); + auto mm = GetI18NCategory(I18NCat::MAINMENU); confirmExitMessage += '\n'; confirmExitMessage += di->T("Are you sure you want to exit?"); - screenManager()->push(new PromptScreen(gamePath_, confirmExitMessage, di->T("Yes"), di->T("No"), [=](bool result) { + screenManager()->push(new UI::MessagePopupScreen(mm->T("Exit"), confirmExitMessage, di->T("Yes"), di->T("No"), [=](bool result) { if (result) { System_ExitApp(); } diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 9fd0d1ad63..1f7624b313 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -394,17 +394,18 @@ void GameScreen::OnDeleteConfig(UI::EventParams &e) { auto di = GetI18NCategory(I18NCat::DIALOG); const bool trashAvailable = System_GetPropertyBool(SYSPROP_HAS_TRASH_BIN); screenManager()->push( - new PromptScreen(gamePath_, di->T("DeleteConfirmGameConfig", "Do you really want to delete the settings for this game?"), trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), - [this](bool result) { - if (result) { - std::shared_ptr info = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO); - if (!info->Ready(GameInfoFlags::PARAM_SFO)) { - return; - } - g_Config.DeleteGameConfig(info->id); - info->hasConfig = false; - RecreateViews(); + new UI::MessagePopupScreen(di->T("Delete"), di->T("DeleteConfirmGameConfig", "Do you really want to delete the settings for this game?"), + trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [this](bool result) { + if (!result) { + return; } + std::shared_ptr info = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO); + if (!info->Ready(GameInfoFlags::PARAM_SFO)) { + return; + } + g_Config.DeleteGameConfig(info->id); + info->hasConfig = false; + RecreateViews(); })); } @@ -483,7 +484,7 @@ void GameScreen::OnDeleteSaveData(UI::EventParams &e) { auto di = GetI18NCategory(I18NCat::DIALOG); Path gamePath = gamePath_; screenManager()->push( - new PromptScreen(gamePath_, di->T("DeleteConfirmAll", "Do you really want to delete all\nyour save data for this game?"), trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), + new UI::MessagePopupScreen(di->T("Delete"), di->T("DeleteConfirmAll", "Do you really want to delete all\nyour save data for this game?"), trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [gamePath](bool yes) { if (yes) { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath, GameInfoFlags::PARAM_SFO); @@ -501,6 +502,7 @@ void GameScreen::OnDeleteGame(UI::EventParams &e) { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, GameInfoFlags::PARAM_SFO); if (info->Ready(GameInfoFlags::PARAM_SFO)) { auto di = GetI18NCategory(I18NCat::DIALOG); + auto ga = GetI18NCategory(I18NCat::GAME); std::string prompt; prompt = di->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."); prompt += "\n\n" + gamePath_.ToVisualString(g_Config.memStickDirectory.c_str()); @@ -508,7 +510,7 @@ void GameScreen::OnDeleteGame(UI::EventParams &e) { Path gamePath = gamePath_; ScreenManager *sm = screenManager(); screenManager()->push( - new PromptScreen(gamePath_, prompt, trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), + new UI::MessagePopupScreen(ga->T("Delete Game"), prompt, trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [sm, gamePath](bool yes) { if (yes) { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath, GameInfoFlags::PARAM_SFO); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a6bfec6411..8ff2c35283 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1709,17 +1709,23 @@ void TriggerRestart(const char *why, bool editThenRestore, const Path &gamePath) System_RestartApp(param); } +void GameSettingsScreen::TriggerRestartOrDo(std::function callback) { + auto di = GetI18NCategory(I18NCat::DIALOG); + screenManager()->push(new UI::MessagePopupScreen(di->T("Restart"), di->T("Changing this setting requires PPSSPP to restart."), di->T("Restart"), di->T("Cancel"), [=](bool yes) { + if (yes) { + TriggerRestart("GameSettingsScreen::RenderingBackendYes", editThenRestore_, gamePath_); + } else { + callback(); + } + })); +} + void GameSettingsScreen::OnRenderingBackend(UI::EventParams &e) { // It only makes sense to show the restart prompt if the backend was actually changed. if (g_Config.iGPUBackend != (int)GetGPUBackend()) { - auto di = GetI18NCategory(I18NCat::DIALOG); - screenManager()->push(new PromptScreen(gamePath_, di->T("Changing this setting requires PPSSPP to restart."), di->T("Restart"), di->T("Cancel"), [=](bool yes) { - if (yes) { - TriggerRestart("GameSettingsScreen::RenderingBackendYes", editThenRestore_, gamePath_); - } else { - g_Config.iGPUBackend = (int)GetGPUBackend(); - } - })); + TriggerRestartOrDo([]() { + g_Config.iGPUBackend = (int)GetGPUBackend(); + }); } } @@ -1728,32 +1734,22 @@ void GameSettingsScreen::OnRenderingDevice(UI::EventParams &e) { std::string *deviceNameSetting = GPUDeviceNameSetting(); if (deviceNameSetting && *deviceNameSetting != GetGPUBackendDevice()) { auto di = GetI18NCategory(I18NCat::DIALOG); - screenManager()->push(new PromptScreen(gamePath_, di->T("Changing this setting requires PPSSPP to restart."), di->T("Restart"), di->T("Cancel"), [=](bool yes) { - // If the user ends up deciding not to restart, set the config back to the current backend - // so it doesn't get switched by accident. - if (yes) { - TriggerRestart("GameSettingsScreen::RenderingDeviceYes", editThenRestore_, gamePath_); - } else { - std::string *deviceNameSetting = GPUDeviceNameSetting(); - if (deviceNameSetting) - *deviceNameSetting = GetGPUBackendDevice(); - // Needed to redraw the setting. - RecreateViews(); - } - })); + TriggerRestartOrDo([this]() { + std::string *deviceNameSetting = GPUDeviceNameSetting(); + if (deviceNameSetting) + *deviceNameSetting = GetGPUBackendDevice(); + // Needed to redraw the setting. + RecreateViews(); + }); } } void GameSettingsScreen::OnInflightFramesChoice(UI::EventParams &e) { if (g_Config.iInflightFrames != prevInflightFrames_) { auto di = GetI18NCategory(I18NCat::DIALOG); - screenManager()->push(new PromptScreen(gamePath_, di->T("Changing this setting requires PPSSPP to restart."), di->T("Restart"), di->T("Cancel"), [=](bool yes) { - if (yes) { - TriggerRestart("GameSettingsScreen::InflightFramesYes", editThenRestore_, gamePath_); - } else { - g_Config.iInflightFrames = prevInflightFrames_; - } - })); + TriggerRestartOrDo([this]() { + g_Config.iInflightFrames = prevInflightFrames_; + }); } } diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 63e9c7683d..c87d1f674f 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -106,6 +106,8 @@ private: void OnAdhocGuides(UI::EventParams &e); + void TriggerRestartOrDo(std::function callback); + // Temporaries to convert setting types, cache enabled, etc. int iAlternateSpeedPercent1_ = 0; int iAlternateSpeedPercent2_ = 0; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 77626f7466..b363a2b546 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -606,7 +606,7 @@ void GamePauseScreen::CreateViews() { std::string confirmMessage = GetConfirmExitMessage(); if (!confirmMessage.empty()) { auto di = GetI18NCategory(I18NCat::DIALOG); - screenManager()->push(new PromptScreen(gamePath_, confirmMessage, di->T("Reset"), di->T("Cancel"), [=](bool result) { + screenManager()->push(new UI::MessagePopupScreen(di->T("Reset"), confirmMessage, di->T("Reset"), di->T("Cancel"), [=](bool result) { if (result) { System_PostUIMessage(UIMessage::REQUEST_GAME_RESET); } @@ -707,9 +707,8 @@ void GamePauseScreen::OnExit(UI::EventParams &e) { if (!confirmExitMessage.empty()) { auto di = GetI18NCategory(I18NCat::DIALOG); - confirmExitMessage += '\n'; - confirmExitMessage += di->T("Are you sure you want to exit?"); - screenManager()->push(new PromptScreen(gamePath_, confirmExitMessage, di->T("Yes"), di->T("No"), [=](bool result) { + std::string_view title = di->T("Are you sure you want to exit?"); + screenManager()->push(new UI::MessagePopupScreen(title, confirmExitMessage, di->T("Exit"), di->T("Cancel"), [=](bool result) { if (result) { if (g_Config.bPauseMenuExitsEmulator) { System_ExitApp(); @@ -766,9 +765,10 @@ void GamePauseScreen::OnCreateConfig(UI::EventParams &e) { void GamePauseScreen::OnDeleteConfig(UI::EventParams &e) { auto di = GetI18NCategory(I18NCat::DIALOG); + const bool trashAvailable = System_GetPropertyBool(SYSPROP_HAS_TRASH_BIN); screenManager()->push( - new UI::MessagePopupScreen("", di->T("DeleteConfirmGameConfig", "Do you really want to delete the settings for this game?"), - di->T("Delete"), di->T("Cancel"), [this](bool yes) { + new UI::MessagePopupScreen(di->T("Delete"), di->T("DeleteConfirmGameConfig", "Do you really want to delete the settings for this game?"), + trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [this](bool yes) { if (!yes) { return; } diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 033223027f..8c3d1ba4ed 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -169,15 +169,15 @@ public: buttonRow->SetSpacing(0); Margins buttonMargins(5, 5, 5, 13); // not sure why we need more at the bottom to make it look right - buttonRow->Add(new Button(di->T("Back"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &UIScreen::OnBack); - buttonRow->Add(new Button(di->T("Delete"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) { + buttonRow->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle(this, &UIScreen::OnBack); + buttonRow->Add(new Choice(di->T("Delete"), ImageID("I_TRASHCAN"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) { auto di = GetI18NCategory(I18NCat::DIALOG); std::shared_ptr ginfo = g_gameInfoCache->GetInfo(nullptr, savePath_, GameInfoFlags::PARAM_SFO); const bool trashAvailable = System_GetPropertyBool(SYSPROP_HAS_TRASH_BIN); std::string_view confirmMessage = di->T("Are you sure you want to delete the file?"); - screenManager()->push(new PromptScreen(gamePath_, confirmMessage, trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [=](bool result) { + screenManager()->push(new MessagePopupScreen(di->T("Delete"), confirmMessage, trashAvailable ? di->T("Move to trash") : di->T("Delete"), di->T("Cancel"), [=](bool result) { if (result) { ginfo->Delete(); TriggerFinish(DR_NO); @@ -185,7 +185,7 @@ public: })); }); if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) { - buttonRow->Add(new Button(di->T("Show in folder"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) { + buttonRow->Add(new Choice(di->T("Show in folder"), ImageID("I_FOLDER"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) { System_ShowFileInFolder(savePath_); }); }