diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/settings.cpp | 5 | ||||
| -rw-r--r-- | src/common/settings.h | 5 | ||||
| -rw-r--r-- | src/common/settings_enums.h | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/configuration/shared_translation.cpp | 8 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 115 | ||||
| -rw-r--r-- | src/yuzu/main.h | 18 | ||||
| -rw-r--r-- | src/yuzu/uisettings.h | 11 |
8 files changed, 125 insertions, 43 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 3fde3cae6..98b43e49c 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -45,6 +45,7 @@ SWITCHABLE(CpuAccuracy, true); | |||
| 45 | SWITCHABLE(FullscreenMode, true); | 45 | SWITCHABLE(FullscreenMode, true); |
| 46 | SWITCHABLE(GpuAccuracy, true); | 46 | SWITCHABLE(GpuAccuracy, true); |
| 47 | SWITCHABLE(Language, true); | 47 | SWITCHABLE(Language, true); |
| 48 | SWITCHABLE(MemoryLayout, true); | ||
| 48 | SWITCHABLE(NvdecEmulation, false); | 49 | SWITCHABLE(NvdecEmulation, false); |
| 49 | SWITCHABLE(Region, true); | 50 | SWITCHABLE(Region, true); |
| 50 | SWITCHABLE(RendererBackend, true); | 51 | SWITCHABLE(RendererBackend, true); |
| @@ -61,6 +62,10 @@ SWITCHABLE(u32, false); | |||
| 61 | SWITCHABLE(u8, false); | 62 | SWITCHABLE(u8, false); |
| 62 | SWITCHABLE(u8, true); | 63 | SWITCHABLE(u8, true); |
| 63 | 64 | ||
| 65 | // Used in UISettings | ||
| 66 | // TODO see if we can move this to uisettings.cpp | ||
| 67 | SWITCHABLE(ConfirmStop, true); | ||
| 68 | |||
| 64 | #undef SETTING | 69 | #undef SETTING |
| 65 | #undef SWITCHABLE | 70 | #undef SWITCHABLE |
| 66 | #endif | 71 | #endif |
diff --git a/src/common/settings.h b/src/common/settings.h index 98ab0ec2e..236e33bee 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -67,6 +67,7 @@ SWITCHABLE(CpuAccuracy, true); | |||
| 67 | SWITCHABLE(FullscreenMode, true); | 67 | SWITCHABLE(FullscreenMode, true); |
| 68 | SWITCHABLE(GpuAccuracy, true); | 68 | SWITCHABLE(GpuAccuracy, true); |
| 69 | SWITCHABLE(Language, true); | 69 | SWITCHABLE(Language, true); |
| 70 | SWITCHABLE(MemoryLayout, true); | ||
| 70 | SWITCHABLE(NvdecEmulation, false); | 71 | SWITCHABLE(NvdecEmulation, false); |
| 71 | SWITCHABLE(Region, true); | 72 | SWITCHABLE(Region, true); |
| 72 | SWITCHABLE(RendererBackend, true); | 73 | SWITCHABLE(RendererBackend, true); |
| @@ -83,6 +84,10 @@ SWITCHABLE(u32, false); | |||
| 83 | SWITCHABLE(u8, false); | 84 | SWITCHABLE(u8, false); |
| 84 | SWITCHABLE(u8, true); | 85 | SWITCHABLE(u8, true); |
| 85 | 86 | ||
| 87 | // Used in UISettings | ||
| 88 | // TODO see if we can move this to uisettings.h | ||
| 89 | SWITCHABLE(ConfirmStop, true); | ||
| 90 | |||
| 86 | #undef SETTING | 91 | #undef SETTING |
| 87 | #undef SWITCHABLE | 92 | #undef SWITCHABLE |
| 88 | #endif | 93 | #endif |
diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 815cafe15..11429d7a8 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h | |||
| @@ -133,6 +133,8 @@ ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); | |||
| 133 | 133 | ||
| 134 | ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb); | 134 | ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb); |
| 135 | 135 | ||
| 136 | ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); | ||
| 137 | |||
| 136 | ENUM(FullscreenMode, Borderless, Exclusive); | 138 | ENUM(FullscreenMode, Borderless, Exclusive); |
| 137 | 139 | ||
| 138 | ENUM(NvdecEmulation, Off, Cpu, Gpu); | 140 | ENUM(NvdecEmulation, Off, Cpu, Gpu); |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 1de093447..d5157c502 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -128,8 +128,8 @@ const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{ | |||
| 128 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}}, | 128 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}}, |
| 129 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}}, | 129 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}}, |
| 130 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, | 130 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, |
| 131 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut, false}}, | 131 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral("R+Plus+Minus"), Qt::WindowShortcut, false}}, |
| 132 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut, false}}, | 132 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral("L+Plus+Minus"), Qt::WindowShortcut, false}}, |
| 133 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, | 133 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, |
| 134 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, | 134 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, |
| 135 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, | 135 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, |
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index a4e8af1b4..3fe448f27 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp | |||
| @@ -157,6 +157,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | |||
| 157 | INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); | 157 | INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); |
| 158 | INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); | 158 | INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); |
| 159 | INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", ""); | 159 | INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", ""); |
| 160 | INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", ""); | ||
| 160 | INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); | 161 | INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); |
| 161 | INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); | 162 | INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); |
| 162 | 163 | ||
| @@ -383,6 +384,13 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) { | |||
| 383 | translations->insert( | 384 | translations->insert( |
| 384 | {Settings::EnumMetadata<Settings::ConsoleMode>::Index(), | 385 | {Settings::EnumMetadata<Settings::ConsoleMode>::Index(), |
| 385 | {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}}); | 386 | {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}}); |
| 387 | translations->insert( | ||
| 388 | {Settings::EnumMetadata<Settings::ConfirmStop>::Index(), | ||
| 389 | { | ||
| 390 | PAIR(ConfirmStop, Ask_Always, "Always ask (Default)"), | ||
| 391 | PAIR(ConfirmStop, Ask_Based_On_Game, "Only if game specifies not to stop"), | ||
| 392 | PAIR(ConfirmStop, Ask_Never, "Never ask"), | ||
| 393 | }}); | ||
| 386 | 394 | ||
| 387 | #undef PAIR | 395 | #undef PAIR |
| 388 | #undef CTX_PAIR | 396 | #undef CTX_PAIR |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 1a6b63856..1431cf2fe 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -211,7 +211,7 @@ void GMainWindow::ShowTelemetryCallout() { | |||
| 211 | tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous " | 211 | tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous " |
| 212 | "data is collected</a> to help improve yuzu. " | 212 | "data is collected</a> to help improve yuzu. " |
| 213 | "<br/><br/>Would you like to share your usage data with us?"); | 213 | "<br/><br/>Would you like to share your usage data with us?"); |
| 214 | if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { | 214 | if (!question(this, tr("Telemetry"), telemetry_message)) { |
| 215 | Settings::values.enable_telemetry = false; | 215 | Settings::values.enable_telemetry = false; |
| 216 | system->ApplySettings(); | 216 | system->ApplySettings(); |
| 217 | } | 217 | } |
| @@ -2420,9 +2420,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT | |||
| 2420 | } | 2420 | } |
| 2421 | }(); | 2421 | }(); |
| 2422 | 2422 | ||
| 2423 | if (QMessageBox::question(this, tr("Remove Entry"), entry_question, | 2423 | if (!question(this, tr("Remove Entry"), entry_question, QMessageBox::Yes | QMessageBox::No, |
| 2424 | QMessageBox::Yes | QMessageBox::No, | 2424 | QMessageBox::No)) { |
| 2425 | QMessageBox::No) != QMessageBox::Yes) { | ||
| 2426 | return; | 2425 | return; |
| 2427 | } | 2426 | } |
| 2428 | 2427 | ||
| @@ -2521,8 +2520,8 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ | |||
| 2521 | } | 2520 | } |
| 2522 | }(); | 2521 | }(); |
| 2523 | 2522 | ||
| 2524 | if (QMessageBox::question(this, tr("Remove File"), question, QMessageBox::Yes | QMessageBox::No, | 2523 | if (!GMainWindow::question(this, tr("Remove File"), question, |
| 2525 | QMessageBox::No) != QMessageBox::Yes) { | 2524 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { |
| 2526 | return; | 2525 | return; |
| 2527 | } | 2526 | } |
| 2528 | 2527 | ||
| @@ -3409,10 +3408,13 @@ void GMainWindow::OnRestartGame() { | |||
| 3409 | if (!system->IsPoweredOn()) { | 3408 | if (!system->IsPoweredOn()) { |
| 3410 | return; | 3409 | return; |
| 3411 | } | 3410 | } |
| 3412 | // Make a copy since ShutdownGame edits game_path | 3411 | |
| 3413 | const auto current_game = QString(current_game_path); | 3412 | if (ConfirmShutdownGame()) { |
| 3414 | ShutdownGame(); | 3413 | // Make a copy since ShutdownGame edits game_path |
| 3415 | BootGame(current_game); | 3414 | const auto current_game = QString(current_game_path); |
| 3415 | ShutdownGame(); | ||
| 3416 | BootGame(current_game); | ||
| 3417 | } | ||
| 3416 | } | 3418 | } |
| 3417 | 3419 | ||
| 3418 | void GMainWindow::OnPauseGame() { | 3420 | void GMainWindow::OnPauseGame() { |
| @@ -3434,18 +3436,39 @@ void GMainWindow::OnPauseContinueGame() { | |||
| 3434 | } | 3436 | } |
| 3435 | 3437 | ||
| 3436 | void GMainWindow::OnStopGame() { | 3438 | void GMainWindow::OnStopGame() { |
| 3437 | if (system->GetExitLocked() && !ConfirmForceLockedExit()) { | 3439 | if (ConfirmShutdownGame()) { |
| 3438 | return; | 3440 | play_time_manager->Stop(); |
| 3441 | // Update game list to show new play time | ||
| 3442 | game_list->PopulateAsync(UISettings::values.game_dirs); | ||
| 3443 | if (OnShutdownBegin()) { | ||
| 3444 | OnShutdownBeginDialog(); | ||
| 3445 | } else { | ||
| 3446 | OnEmulationStopped(); | ||
| 3447 | } | ||
| 3439 | } | 3448 | } |
| 3449 | } | ||
| 3440 | 3450 | ||
| 3441 | play_time_manager->Stop(); | 3451 | bool GMainWindow::ConfirmShutdownGame() { |
| 3442 | // Update game list to show new play time | 3452 | if (UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Always) { |
| 3443 | game_list->PopulateAsync(UISettings::values.game_dirs); | 3453 | if (system->GetExitLocked()) { |
| 3444 | if (OnShutdownBegin()) { | 3454 | if (!ConfirmForceLockedExit()) { |
| 3445 | OnShutdownBeginDialog(); | 3455 | return false; |
| 3456 | } | ||
| 3457 | } else { | ||
| 3458 | if (!ConfirmChangeGame()) { | ||
| 3459 | return false; | ||
| 3460 | } | ||
| 3461 | } | ||
| 3446 | } else { | 3462 | } else { |
| 3447 | OnEmulationStopped(); | 3463 | if (UISettings::values.confirm_before_stopping.GetValue() == |
| 3464 | ConfirmStop::Ask_Based_On_Game && | ||
| 3465 | system->GetExitLocked()) { | ||
| 3466 | if (!ConfirmForceLockedExit()) { | ||
| 3467 | return false; | ||
| 3468 | } | ||
| 3469 | } | ||
| 3448 | } | 3470 | } |
| 3471 | return true; | ||
| 3449 | } | 3472 | } |
| 3450 | 3473 | ||
| 3451 | void GMainWindow::OnLoadComplete() { | 3474 | void GMainWindow::OnLoadComplete() { |
| @@ -3825,22 +3848,11 @@ void GMainWindow::OnTasRecord() { | |||
| 3825 | const bool is_recording = input_subsystem->GetTas()->Record(); | 3848 | const bool is_recording = input_subsystem->GetTas()->Record(); |
| 3826 | if (!is_recording) { | 3849 | if (!is_recording) { |
| 3827 | is_tas_recording_dialog_active = true; | 3850 | is_tas_recording_dialog_active = true; |
| 3828 | ControllerNavigation* controller_navigation = | 3851 | |
| 3829 | new ControllerNavigation(system->HIDCore(), this); | 3852 | bool answer = question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"), |
| 3830 | // Use QMessageBox instead of question so we can link controller navigation | 3853 | QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); |
| 3831 | QMessageBox* box_dialog = new QMessageBox(); | 3854 | |
| 3832 | box_dialog->setWindowTitle(tr("TAS Recording")); | 3855 | input_subsystem->GetTas()->SaveRecording(answer); |
| 3833 | box_dialog->setText(tr("Overwrite file of player 1?")); | ||
| 3834 | box_dialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No); | ||
| 3835 | box_dialog->setDefaultButton(QMessageBox::Yes); | ||
| 3836 | connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, | ||
| 3837 | [box_dialog](Qt::Key key) { | ||
| 3838 | QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); | ||
| 3839 | QCoreApplication::postEvent(box_dialog, event); | ||
| 3840 | }); | ||
| 3841 | int res = box_dialog->exec(); | ||
| 3842 | controller_navigation->UnloadController(); | ||
| 3843 | input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes); | ||
| 3844 | is_tas_recording_dialog_active = false; | 3856 | is_tas_recording_dialog_active = false; |
| 3845 | } | 3857 | } |
| 3846 | OnTasStateChanged(); | 3858 | OnTasStateChanged(); |
| @@ -4081,6 +4093,29 @@ void GMainWindow::OnLoadAmiibo() { | |||
| 4081 | LoadAmiibo(filename); | 4093 | LoadAmiibo(filename); |
| 4082 | } | 4094 | } |
| 4083 | 4095 | ||
| 4096 | bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text, | ||
| 4097 | QMessageBox::StandardButtons buttons, | ||
| 4098 | QMessageBox::StandardButton defaultButton) { | ||
| 4099 | |||
| 4100 | QMessageBox* box_dialog = new QMessageBox(parent); | ||
| 4101 | box_dialog->setWindowTitle(title); | ||
| 4102 | box_dialog->setText(text); | ||
| 4103 | box_dialog->setStandardButtons(buttons); | ||
| 4104 | box_dialog->setDefaultButton(defaultButton); | ||
| 4105 | |||
| 4106 | ControllerNavigation* controller_navigation = | ||
| 4107 | new ControllerNavigation(system->HIDCore(), box_dialog); | ||
| 4108 | connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, | ||
| 4109 | [box_dialog](Qt::Key key) { | ||
| 4110 | QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); | ||
| 4111 | QCoreApplication::postEvent(box_dialog, event); | ||
| 4112 | }); | ||
| 4113 | int res = box_dialog->exec(); | ||
| 4114 | |||
| 4115 | controller_navigation->UnloadController(); | ||
| 4116 | return res == QMessageBox::Yes; | ||
| 4117 | } | ||
| 4118 | |||
| 4084 | void GMainWindow::LoadAmiibo(const QString& filename) { | 4119 | void GMainWindow::LoadAmiibo(const QString& filename) { |
| 4085 | auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); | 4120 | auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); |
| 4086 | const QString title = tr("Error loading Amiibo data"); | 4121 | const QString title = tr("Error loading Amiibo data"); |
| @@ -4814,8 +4849,7 @@ bool GMainWindow::ConfirmClose() { | |||
| 4814 | return true; | 4849 | return true; |
| 4815 | } | 4850 | } |
| 4816 | const auto text = tr("Are you sure you want to close yuzu?"); | 4851 | const auto text = tr("Are you sure you want to close yuzu?"); |
| 4817 | const auto answer = QMessageBox::question(this, tr("yuzu"), text); | 4852 | return question(this, tr("yuzu"), text); |
| 4818 | return answer != QMessageBox::No; | ||
| 4819 | } | 4853 | } |
| 4820 | 4854 | ||
| 4821 | void GMainWindow::closeEvent(QCloseEvent* event) { | 4855 | void GMainWindow::closeEvent(QCloseEvent* event) { |
| @@ -4908,11 +4942,11 @@ bool GMainWindow::ConfirmChangeGame() { | |||
| 4908 | if (emu_thread == nullptr) | 4942 | if (emu_thread == nullptr) |
| 4909 | return true; | 4943 | return true; |
| 4910 | 4944 | ||
| 4911 | const auto answer = QMessageBox::question( | 4945 | // Use custom question to link controller navigation |
| 4946 | return question( | ||
| 4912 | this, tr("yuzu"), | 4947 | this, tr("yuzu"), |
| 4913 | tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), | 4948 | tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), |
| 4914 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | 4949 | QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); |
| 4915 | return answer != QMessageBox::No; | ||
| 4916 | } | 4950 | } |
| 4917 | 4951 | ||
| 4918 | bool GMainWindow::ConfirmForceLockedExit() { | 4952 | bool GMainWindow::ConfirmForceLockedExit() { |
| @@ -4922,8 +4956,7 @@ bool GMainWindow::ConfirmForceLockedExit() { | |||
| 4922 | const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" | 4956 | const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" |
| 4923 | "Would you like to bypass this and exit anyway?"); | 4957 | "Would you like to bypass this and exit anyway?"); |
| 4924 | 4958 | ||
| 4925 | const auto answer = QMessageBox::question(this, tr("yuzu"), text); | 4959 | return question(this, tr("yuzu"), text); |
| 4926 | return answer != QMessageBox::No; | ||
| 4927 | } | 4960 | } |
| 4928 | 4961 | ||
| 4929 | void GMainWindow::RequestGameExit() { | 4962 | void GMainWindow::RequestGameExit() { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 2346eb3bd..270a40c5f 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <optional> | 7 | #include <optional> |
| 8 | 8 | ||
| 9 | #include <QMainWindow> | 9 | #include <QMainWindow> |
| 10 | #include <QMessageBox> | ||
| 10 | #include <QTimer> | 11 | #include <QTimer> |
| 11 | #include <QTranslator> | 12 | #include <QTranslator> |
| 12 | 13 | ||
| @@ -15,6 +16,7 @@ | |||
| 15 | #include "input_common/drivers/tas_input.h" | 16 | #include "input_common/drivers/tas_input.h" |
| 16 | #include "yuzu/compatibility_list.h" | 17 | #include "yuzu/compatibility_list.h" |
| 17 | #include "yuzu/hotkeys.h" | 18 | #include "yuzu/hotkeys.h" |
| 19 | #include "yuzu/util/controller_navigation.h" | ||
| 18 | 20 | ||
| 19 | #ifdef __unix__ | 21 | #ifdef __unix__ |
| 20 | #include <QVariant> | 22 | #include <QVariant> |
| @@ -424,6 +426,11 @@ private: | |||
| 424 | bool CheckSystemArchiveDecryption(); | 426 | bool CheckSystemArchiveDecryption(); |
| 425 | bool CheckFirmwarePresence(); | 427 | bool CheckFirmwarePresence(); |
| 426 | void ConfigureFilesystemProvider(const std::string& filepath); | 428 | void ConfigureFilesystemProvider(const std::string& filepath); |
| 429 | /** | ||
| 430 | * Open (or not) the right confirm dialog based on current setting and game exit lock | ||
| 431 | * @returns true if the player confirmed or the settings do no require it | ||
| 432 | */ | ||
| 433 | bool ConfirmShutdownGame(); | ||
| 427 | 434 | ||
| 428 | QString GetTasStateDescription() const; | 435 | QString GetTasStateDescription() const; |
| 429 | bool CreateShortcut(const std::string& shortcut_path, const std::string& title, | 436 | bool CreateShortcut(const std::string& shortcut_path, const std::string& title, |
| @@ -431,6 +438,17 @@ private: | |||
| 431 | const std::string& command, const std::string& arguments, | 438 | const std::string& command, const std::string& arguments, |
| 432 | const std::string& categories, const std::string& keywords); | 439 | const std::string& categories, const std::string& keywords); |
| 433 | 440 | ||
| 441 | /** | ||
| 442 | * Mimic the behavior of QMessageBox::question but link controller navigation to the dialog | ||
| 443 | * The only difference is that it returns a boolean. | ||
| 444 | * | ||
| 445 | * @returns true if buttons contains QMessageBox::Yes and the user clicks on the "Yes" button. | ||
| 446 | */ | ||
| 447 | bool question(QWidget* parent, const QString& title, const QString& text, | ||
| 448 | QMessageBox::StandardButtons buttons = | ||
| 449 | QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), | ||
| 450 | QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); | ||
| 451 | |||
| 434 | std::unique_ptr<Ui::MainWindow> ui; | 452 | std::unique_ptr<Ui::MainWindow> ui; |
| 435 | 453 | ||
| 436 | std::unique_ptr<Core::System> system; | 454 | std::unique_ptr<Core::System> system; |
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 975008159..b62ff620c 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h | |||
| @@ -16,7 +16,9 @@ | |||
| 16 | #include "common/settings_enums.h" | 16 | #include "common/settings_enums.h" |
| 17 | 17 | ||
| 18 | using Settings::Category; | 18 | using Settings::Category; |
| 19 | using Settings::ConfirmStop; | ||
| 19 | using Settings::Setting; | 20 | using Settings::Setting; |
| 21 | using Settings::SwitchableSetting; | ||
| 20 | 22 | ||
| 21 | #ifndef CANNOT_EXPLICITLY_INSTANTIATE | 23 | #ifndef CANNOT_EXPLICITLY_INSTANTIATE |
| 22 | namespace Settings { | 24 | namespace Settings { |
| @@ -94,6 +96,15 @@ struct Values { | |||
| 94 | Setting<bool> confirm_before_closing{ | 96 | Setting<bool> confirm_before_closing{ |
| 95 | linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default, | 97 | linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default, |
| 96 | true, true}; | 98 | true, true}; |
| 99 | |||
| 100 | SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage, | ||
| 101 | ConfirmStop::Ask_Always, | ||
| 102 | "confirmStop", | ||
| 103 | Category::UiGeneral, | ||
| 104 | Settings::Specialization::Default, | ||
| 105 | true, | ||
| 106 | true}; | ||
| 107 | |||
| 97 | Setting<bool> first_start{linkage, true, "firstStart", Category::Ui}; | 108 | Setting<bool> first_start{linkage, true, "firstStart", Category::Ui}; |
| 98 | Setting<bool> pause_when_in_background{linkage, | 109 | Setting<bool> pause_when_in_background{linkage, |
| 99 | false, | 110 | false, |