diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/shared_translation.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 86 | ||||
| -rw-r--r-- | src/yuzu/main.h | 13 | ||||
| -rw-r--r-- | src/yuzu/uisettings.h | 5 |
5 files changed, 75 insertions, 32 deletions
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 1de093447..bc47d1688 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -129,7 +129,7 @@ const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{ | |||
| 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(""), 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..9e65525ca 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 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 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 5427758c1..26fa3e191 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -209,7 +209,7 @@ void GMainWindow::ShowTelemetryCallout() { | |||
| 209 | tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous " | 209 | tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous " |
| 210 | "data is collected</a> to help improve yuzu. " | 210 | "data is collected</a> to help improve yuzu. " |
| 211 | "<br/><br/>Would you like to share your usage data with us?"); | 211 | "<br/><br/>Would you like to share your usage data with us?"); |
| 212 | if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { | 212 | if (!question(this, tr("Telemetry"), telemetry_message)) { |
| 213 | Settings::values.enable_telemetry = false; | 213 | Settings::values.enable_telemetry = false; |
| 214 | system->ApplySettings(); | 214 | system->ApplySettings(); |
| 215 | } | 215 | } |
| @@ -2418,9 +2418,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT | |||
| 2418 | } | 2418 | } |
| 2419 | }(); | 2419 | }(); |
| 2420 | 2420 | ||
| 2421 | if (QMessageBox::question(this, tr("Remove Entry"), entry_question, | 2421 | if (!question(this, tr("Remove Entry"), entry_question, QMessageBox::Yes | QMessageBox::No, |
| 2422 | QMessageBox::Yes | QMessageBox::No, | 2422 | QMessageBox::No)) { |
| 2423 | QMessageBox::No) != QMessageBox::Yes) { | ||
| 2424 | return; | 2423 | return; |
| 2425 | } | 2424 | } |
| 2426 | 2425 | ||
| @@ -2519,8 +2518,8 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ | |||
| 2519 | } | 2518 | } |
| 2520 | }(); | 2519 | }(); |
| 2521 | 2520 | ||
| 2522 | if (QMessageBox::question(this, tr("Remove File"), question, QMessageBox::Yes | QMessageBox::No, | 2521 | if (!GMainWindow::question(this, tr("Remove File"), question, |
| 2523 | QMessageBox::No) != QMessageBox::Yes) { | 2522 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { |
| 2524 | return; | 2523 | return; |
| 2525 | } | 2524 | } |
| 2526 | 2525 | ||
| @@ -3426,8 +3425,25 @@ void GMainWindow::OnPauseContinueGame() { | |||
| 3426 | } | 3425 | } |
| 3427 | 3426 | ||
| 3428 | void GMainWindow::OnStopGame() { | 3427 | void GMainWindow::OnStopGame() { |
| 3429 | if (system->GetExitLocked() && !ConfirmForceLockedExit()) { | 3428 | // Open (or not) the right confirm dialog based on current setting and game exit lock |
| 3430 | return; | 3429 | if (UISettings::values.confirm_before_stopping.GetValue() == UISettings::AskStopIndex::Always) { |
| 3430 | if (system->GetExitLocked()) { | ||
| 3431 | if (!ConfirmForceLockedExit()) { | ||
| 3432 | return; | ||
| 3433 | } | ||
| 3434 | } else { | ||
| 3435 | if (!ConfirmChangeGame()) { | ||
| 3436 | return; | ||
| 3437 | } | ||
| 3438 | } | ||
| 3439 | } else { | ||
| 3440 | if (UISettings::values.confirm_before_stopping.GetValue() == | ||
| 3441 | UISettings::AskStopIndex::Game && | ||
| 3442 | system->GetExitLocked()) { | ||
| 3443 | if (!ConfirmForceLockedExit()) { | ||
| 3444 | return; | ||
| 3445 | } | ||
| 3446 | } | ||
| 3431 | } | 3447 | } |
| 3432 | 3448 | ||
| 3433 | play_time_manager->Stop(); | 3449 | play_time_manager->Stop(); |
| @@ -3817,22 +3833,11 @@ void GMainWindow::OnTasRecord() { | |||
| 3817 | const bool is_recording = input_subsystem->GetTas()->Record(); | 3833 | const bool is_recording = input_subsystem->GetTas()->Record(); |
| 3818 | if (!is_recording) { | 3834 | if (!is_recording) { |
| 3819 | is_tas_recording_dialog_active = true; | 3835 | is_tas_recording_dialog_active = true; |
| 3820 | ControllerNavigation* controller_navigation = | 3836 | |
| 3821 | new ControllerNavigation(system->HIDCore(), this); | 3837 | bool answer = question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"), |
| 3822 | // Use QMessageBox instead of question so we can link controller navigation | 3838 | QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); |
| 3823 | QMessageBox* box_dialog = new QMessageBox(); | 3839 | |
| 3824 | box_dialog->setWindowTitle(tr("TAS Recording")); | 3840 | input_subsystem->GetTas()->SaveRecording(answer); |
| 3825 | box_dialog->setText(tr("Overwrite file of player 1?")); | ||
| 3826 | box_dialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No); | ||
| 3827 | box_dialog->setDefaultButton(QMessageBox::Yes); | ||
| 3828 | connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, | ||
| 3829 | [box_dialog](Qt::Key key) { | ||
| 3830 | QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); | ||
| 3831 | QCoreApplication::postEvent(box_dialog, event); | ||
| 3832 | }); | ||
| 3833 | int res = box_dialog->exec(); | ||
| 3834 | controller_navigation->UnloadController(); | ||
| 3835 | input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes); | ||
| 3836 | is_tas_recording_dialog_active = false; | 3841 | is_tas_recording_dialog_active = false; |
| 3837 | } | 3842 | } |
| 3838 | OnTasStateChanged(); | 3843 | OnTasStateChanged(); |
| @@ -4073,6 +4078,27 @@ void GMainWindow::OnLoadAmiibo() { | |||
| 4073 | LoadAmiibo(filename); | 4078 | LoadAmiibo(filename); |
| 4074 | } | 4079 | } |
| 4075 | 4080 | ||
| 4081 | bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text, | ||
| 4082 | QMessageBox::StandardButtons buttons, | ||
| 4083 | QMessageBox::StandardButton defaultButton) { | ||
| 4084 | ControllerNavigation* controller_navigation = new ControllerNavigation(system->HIDCore(), this); | ||
| 4085 | |||
| 4086 | QMessageBox* box_dialog = new QMessageBox(parent); | ||
| 4087 | box_dialog->setWindowTitle(title); | ||
| 4088 | box_dialog->setText(text); | ||
| 4089 | box_dialog->setStandardButtons(buttons); | ||
| 4090 | box_dialog->setDefaultButton(defaultButton); | ||
| 4091 | connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, | ||
| 4092 | [box_dialog](Qt::Key key) { | ||
| 4093 | QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); | ||
| 4094 | QCoreApplication::postEvent(box_dialog, event); | ||
| 4095 | }); | ||
| 4096 | int res = box_dialog->exec(); | ||
| 4097 | |||
| 4098 | controller_navigation->UnloadController(); | ||
| 4099 | return res == QMessageBox::Yes; | ||
| 4100 | } | ||
| 4101 | |||
| 4076 | void GMainWindow::LoadAmiibo(const QString& filename) { | 4102 | void GMainWindow::LoadAmiibo(const QString& filename) { |
| 4077 | auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); | 4103 | auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); |
| 4078 | const QString title = tr("Error loading Amiibo data"); | 4104 | const QString title = tr("Error loading Amiibo data"); |
| @@ -4806,8 +4832,7 @@ bool GMainWindow::ConfirmClose() { | |||
| 4806 | return true; | 4832 | return true; |
| 4807 | } | 4833 | } |
| 4808 | const auto text = tr("Are you sure you want to close yuzu?"); | 4834 | const auto text = tr("Are you sure you want to close yuzu?"); |
| 4809 | const auto answer = QMessageBox::question(this, tr("yuzu"), text); | 4835 | return question(this, tr("yuzu"), text); |
| 4810 | return answer != QMessageBox::No; | ||
| 4811 | } | 4836 | } |
| 4812 | 4837 | ||
| 4813 | void GMainWindow::closeEvent(QCloseEvent* event) { | 4838 | void GMainWindow::closeEvent(QCloseEvent* event) { |
| @@ -4900,11 +4925,11 @@ bool GMainWindow::ConfirmChangeGame() { | |||
| 4900 | if (emu_thread == nullptr) | 4925 | if (emu_thread == nullptr) |
| 4901 | return true; | 4926 | return true; |
| 4902 | 4927 | ||
| 4903 | const auto answer = QMessageBox::question( | 4928 | // Use custom question to link controller navigation |
| 4929 | return question( | ||
| 4904 | this, tr("yuzu"), | 4930 | this, tr("yuzu"), |
| 4905 | tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), | 4931 | tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), |
| 4906 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | 4932 | QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); |
| 4907 | return answer != QMessageBox::No; | ||
| 4908 | } | 4933 | } |
| 4909 | 4934 | ||
| 4910 | bool GMainWindow::ConfirmForceLockedExit() { | 4935 | bool GMainWindow::ConfirmForceLockedExit() { |
| @@ -4914,8 +4939,7 @@ bool GMainWindow::ConfirmForceLockedExit() { | |||
| 4914 | const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" | 4939 | const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" |
| 4915 | "Would you like to bypass this and exit anyway?"); | 4940 | "Would you like to bypass this and exit anyway?"); |
| 4916 | 4941 | ||
| 4917 | const auto answer = QMessageBox::question(this, tr("yuzu"), text); | 4942 | return question(this, tr("yuzu"), text); |
| 4918 | return answer != QMessageBox::No; | ||
| 4919 | } | 4943 | } |
| 4920 | 4944 | ||
| 4921 | void GMainWindow::RequestGameExit() { | 4945 | void GMainWindow::RequestGameExit() { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 2346eb3bd..711c53a32 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> |
| @@ -431,6 +433,17 @@ private: | |||
| 431 | const std::string& command, const std::string& arguments, | 433 | const std::string& command, const std::string& arguments, |
| 432 | const std::string& categories, const std::string& keywords); | 434 | const std::string& categories, const std::string& keywords); |
| 433 | 435 | ||
| 436 | /** | ||
| 437 | * Mimic the behavior of QMessageBox::question but link controller navigation to the dialog | ||
| 438 | * The only difference is that it returns a boolean. | ||
| 439 | * | ||
| 440 | * @returns true if buttons contains QMessageBox::Yes and the user clicks on the "Yes" button. | ||
| 441 | */ | ||
| 442 | bool question(QWidget* parent, const QString& title, const QString& text, | ||
| 443 | QMessageBox::StandardButtons buttons = | ||
| 444 | QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), | ||
| 445 | QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); | ||
| 446 | |||
| 434 | std::unique_ptr<Ui::MainWindow> ui; | 447 | std::unique_ptr<Ui::MainWindow> ui; |
| 435 | 448 | ||
| 436 | std::unique_ptr<Core::System> system; | 449 | std::unique_ptr<Core::System> system; |
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 975008159..1216c4efa 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h | |||
| @@ -56,6 +56,8 @@ enum class Theme { | |||
| 56 | MidnightBlueColorful, | 56 | MidnightBlueColorful, |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | enum AskStopIndex : int { Always, Game, Never }; | ||
| 60 | |||
| 59 | using Themes = std::array<std::pair<const char*, const char*>, 6>; | 61 | using Themes = std::array<std::pair<const char*, const char*>, 6>; |
| 60 | extern const Themes themes; | 62 | extern const Themes themes; |
| 61 | 63 | ||
| @@ -94,6 +96,9 @@ 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 | Setting<bool> confirm_before_stopping{ | ||
| 100 | linkage, true, "confirmStop", Category::UiGeneral, Settings::Specialization::Default, | ||
| 101 | true, true}; | ||
| 97 | Setting<bool> first_start{linkage, true, "firstStart", Category::Ui}; | 102 | Setting<bool> first_start{linkage, true, "firstStart", Category::Ui}; |
| 98 | Setting<bool> pause_when_in_background{linkage, | 103 | Setting<bool> pause_when_in_background{linkage, |
| 99 | false, | 104 | false, |