diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuzu/main.cpp | 397 | ||||
| -rw-r--r-- | src/yuzu/main.h | 6 | ||||
| -rw-r--r-- | src/yuzu/main.ui | 9 |
3 files changed, 175 insertions, 237 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 5058c3e4e..88e84e8f7 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -952,164 +952,80 @@ void GMainWindow::InitializeRecentFileMenuActions() { | |||
| 952 | UpdateRecentFiles(); | 952 | UpdateRecentFiles(); |
| 953 | } | 953 | } |
| 954 | 954 | ||
| 955 | void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name) { | ||
| 956 | static const QString main_window = QStringLiteral("Main Window"); | ||
| 957 | action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name)); | ||
| 958 | action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name)); | ||
| 959 | |||
| 960 | this->addAction(action); | ||
| 961 | } | ||
| 962 | |||
| 955 | void GMainWindow::InitializeHotkeys() { | 963 | void GMainWindow::InitializeHotkeys() { |
| 956 | hotkey_registry.LoadHotkeys(); | 964 | hotkey_registry.LoadHotkeys(); |
| 957 | 965 | ||
| 958 | const QString main_window = QStringLiteral("Main Window"); | 966 | LinkActionShortcut(ui->action_Load_File, QStringLiteral("Load File")); |
| 959 | const QString load_file = QStringLiteral("Load File"); | 967 | LinkActionShortcut(ui->action_Load_Amiibo, QStringLiteral("Load Amiibo")); |
| 960 | const QString load_amiibo = QStringLiteral("Load Amiibo"); | 968 | LinkActionShortcut(ui->action_Exit, QStringLiteral("Exit yuzu")); |
| 961 | const QString exit_yuzu = QStringLiteral("Exit yuzu"); | 969 | LinkActionShortcut(ui->action_Restart, QStringLiteral("Restart Emulation")); |
| 962 | const QString restart_emulation = QStringLiteral("Restart Emulation"); | 970 | LinkActionShortcut(ui->action_Pause, QStringLiteral("Continue/Pause Emulation")); |
| 963 | const QString stop_emulation = QStringLiteral("Stop Emulation"); | 971 | LinkActionShortcut(ui->action_Stop, QStringLiteral("Stop Emulation")); |
| 964 | const QString toggle_filter_bar = QStringLiteral("Toggle Filter Bar"); | 972 | LinkActionShortcut(ui->action_Show_Filter_Bar, QStringLiteral("Toggle Filter Bar")); |
| 965 | const QString toggle_status_bar = QStringLiteral("Toggle Status Bar"); | 973 | LinkActionShortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar")); |
| 966 | const QString fullscreen = QStringLiteral("Fullscreen"); | 974 | LinkActionShortcut(ui->action_Fullscreen, QStringLiteral("Fullscreen")); |
| 967 | const QString capture_screenshot = QStringLiteral("Capture Screenshot"); | 975 | LinkActionShortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot")); |
| 968 | const QString tas_start_stop = QStringLiteral("TAS Start/Stop"); | 976 | LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop")); |
| 969 | const QString tas_record = QStringLiteral("TAS Record"); | 977 | LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record")); |
| 970 | const QString tas_reset = QStringLiteral("TAS Reset"); | 978 | LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset")); |
| 971 | 979 | ||
| 972 | ui->action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file)); | 980 | static const QString main_window = QStringLiteral("Main Window"); |
| 973 | ui->action_Load_File->setShortcutContext( | 981 | const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { |
| 974 | hotkey_registry.GetShortcutContext(main_window, load_file)); | 982 | const QShortcut* hotkey = hotkey_registry.GetHotkey(main_window, action_name, this); |
| 975 | 983 | connect(hotkey, &QShortcut::activated, this, function); | |
| 976 | ui->action_Load_Amiibo->setShortcut(hotkey_registry.GetKeySequence(main_window, load_amiibo)); | 984 | }; |
| 977 | ui->action_Load_Amiibo->setShortcutContext( | 985 | |
| 978 | hotkey_registry.GetShortcutContext(main_window, load_amiibo)); | 986 | connect_shortcut(QStringLiteral("Exit Fullscreen"), [&] { |
| 979 | 987 | if (emulation_running && ui->action_Fullscreen->isChecked()) { | |
| 980 | ui->action_Exit->setShortcut(hotkey_registry.GetKeySequence(main_window, exit_yuzu)); | 988 | ui->action_Fullscreen->setChecked(false); |
| 981 | ui->action_Exit->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, exit_yuzu)); | 989 | ToggleFullscreen(); |
| 982 | 990 | } | |
| 983 | ui->action_Restart->setShortcut(hotkey_registry.GetKeySequence(main_window, restart_emulation)); | 991 | }); |
| 984 | ui->action_Restart->setShortcutContext( | 992 | connect_shortcut(QStringLiteral("Toggle Speed Limit"), [&] { |
| 985 | hotkey_registry.GetShortcutContext(main_window, restart_emulation)); | 993 | Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue()); |
| 986 | 994 | UpdateStatusBar(); | |
| 987 | ui->action_Stop->setShortcut(hotkey_registry.GetKeySequence(main_window, stop_emulation)); | 995 | }); |
| 988 | ui->action_Stop->setShortcutContext( | ||
| 989 | hotkey_registry.GetShortcutContext(main_window, stop_emulation)); | ||
| 990 | |||
| 991 | ui->action_Show_Filter_Bar->setShortcut( | ||
| 992 | hotkey_registry.GetKeySequence(main_window, toggle_filter_bar)); | ||
| 993 | ui->action_Show_Filter_Bar->setShortcutContext( | ||
| 994 | hotkey_registry.GetShortcutContext(main_window, toggle_filter_bar)); | ||
| 995 | |||
| 996 | ui->action_Show_Status_Bar->setShortcut( | ||
| 997 | hotkey_registry.GetKeySequence(main_window, toggle_status_bar)); | ||
| 998 | ui->action_Show_Status_Bar->setShortcutContext( | ||
| 999 | hotkey_registry.GetShortcutContext(main_window, toggle_status_bar)); | ||
| 1000 | |||
| 1001 | ui->action_Capture_Screenshot->setShortcut( | ||
| 1002 | hotkey_registry.GetKeySequence(main_window, capture_screenshot)); | ||
| 1003 | ui->action_Capture_Screenshot->setShortcutContext( | ||
| 1004 | hotkey_registry.GetShortcutContext(main_window, capture_screenshot)); | ||
| 1005 | |||
| 1006 | ui->action_Fullscreen->setShortcut( | ||
| 1007 | hotkey_registry.GetHotkey(main_window, fullscreen, this)->key()); | ||
| 1008 | ui->action_Fullscreen->setShortcutContext( | ||
| 1009 | hotkey_registry.GetShortcutContext(main_window, fullscreen)); | ||
| 1010 | |||
| 1011 | ui->action_TAS_Start->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_start_stop)); | ||
| 1012 | ui->action_TAS_Start->setShortcutContext( | ||
| 1013 | hotkey_registry.GetShortcutContext(main_window, tas_start_stop)); | ||
| 1014 | |||
| 1015 | ui->action_TAS_Record->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_record)); | ||
| 1016 | ui->action_TAS_Record->setShortcutContext( | ||
| 1017 | hotkey_registry.GetShortcutContext(main_window, tas_record)); | ||
| 1018 | |||
| 1019 | ui->action_TAS_Reset->setShortcut(hotkey_registry.GetKeySequence(main_window, tas_reset)); | ||
| 1020 | ui->action_TAS_Reset->setShortcutContext( | ||
| 1021 | hotkey_registry.GetShortcutContext(main_window, tas_reset)); | ||
| 1022 | |||
| 1023 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this), | ||
| 1024 | &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile); | ||
| 1025 | connect( | ||
| 1026 | hotkey_registry.GetHotkey(main_window, QStringLiteral("Continue/Pause Emulation"), this), | ||
| 1027 | &QShortcut::activated, this, [&] { | ||
| 1028 | if (emulation_running) { | ||
| 1029 | if (emu_thread->IsRunning()) { | ||
| 1030 | OnPauseGame(); | ||
| 1031 | } else { | ||
| 1032 | OnStartGame(); | ||
| 1033 | } | ||
| 1034 | } | ||
| 1035 | }); | ||
| 1036 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this), | ||
| 1037 | &QShortcut::activated, this, [this] { | ||
| 1038 | if (!system->IsPoweredOn()) { | ||
| 1039 | return; | ||
| 1040 | } | ||
| 1041 | BootGame(game_path); | ||
| 1042 | }); | ||
| 1043 | connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window), | ||
| 1044 | &QShortcut::activated, ui->action_Fullscreen, &QAction::trigger); | ||
| 1045 | connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window), | ||
| 1046 | &QShortcut::activatedAmbiguously, ui->action_Fullscreen, &QAction::trigger); | ||
| 1047 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this), | ||
| 1048 | &QShortcut::activated, this, [&] { | ||
| 1049 | if (emulation_running && ui->action_Fullscreen->isChecked()) { | ||
| 1050 | ui->action_Fullscreen->setChecked(false); | ||
| 1051 | ToggleFullscreen(); | ||
| 1052 | } | ||
| 1053 | }); | ||
| 1054 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), | ||
| 1055 | &QShortcut::activated, this, [&] { | ||
| 1056 | Settings::values.use_speed_limit.SetValue( | ||
| 1057 | !Settings::values.use_speed_limit.GetValue()); | ||
| 1058 | UpdateStatusBar(); | ||
| 1059 | }); | ||
| 1060 | constexpr u16 SPEED_LIMIT_STEP = 5; | 996 | constexpr u16 SPEED_LIMIT_STEP = 5; |
| 1061 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), | 997 | connect_shortcut(QStringLiteral("Increase Speed Limit"), [&] { |
| 1062 | &QShortcut::activated, this, [&] { | 998 | if (Settings::values.speed_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) { |
| 1063 | if (Settings::values.speed_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) { | 999 | Settings::values.speed_limit.SetValue(SPEED_LIMIT_STEP + |
| 1064 | Settings::values.speed_limit.SetValue(SPEED_LIMIT_STEP + | 1000 | Settings::values.speed_limit.GetValue()); |
| 1065 | Settings::values.speed_limit.GetValue()); | 1001 | UpdateStatusBar(); |
| 1066 | UpdateStatusBar(); | 1002 | } |
| 1067 | } | 1003 | }); |
| 1068 | }); | 1004 | connect_shortcut(QStringLiteral("Decrease Speed Limit"), [&] { |
| 1069 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), | 1005 | if (Settings::values.speed_limit.GetValue() > SPEED_LIMIT_STEP) { |
| 1070 | &QShortcut::activated, this, [&] { | 1006 | Settings::values.speed_limit.SetValue(Settings::values.speed_limit.GetValue() - |
| 1071 | if (Settings::values.speed_limit.GetValue() > SPEED_LIMIT_STEP) { | 1007 | SPEED_LIMIT_STEP); |
| 1072 | Settings::values.speed_limit.SetValue(Settings::values.speed_limit.GetValue() - | 1008 | UpdateStatusBar(); |
| 1073 | SPEED_LIMIT_STEP); | 1009 | } |
| 1074 | UpdateStatusBar(); | 1010 | }); |
| 1075 | } | 1011 | connect_shortcut(QStringLiteral("Change Docked Mode"), [&] { |
| 1076 | }); | 1012 | Settings::values.use_docked_mode.SetValue(!Settings::values.use_docked_mode.GetValue()); |
| 1077 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load Amiibo"), this), | 1013 | OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(), |
| 1078 | &QShortcut::activated, this, [&] { | 1014 | Settings::values.use_docked_mode.GetValue(), *system); |
| 1079 | if (ui->action_Load_Amiibo->isEnabled()) { | 1015 | dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); |
| 1080 | OnLoadAmiibo(); | 1016 | }); |
| 1081 | } | 1017 | connect_shortcut(QStringLiteral("Mute Audio"), |
| 1082 | }); | 1018 | [] { Settings::values.audio_muted = !Settings::values.audio_muted; }); |
| 1083 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Capture Screenshot"), this), | 1019 | connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] { |
| 1084 | &QShortcut::activated, this, [&] { | 1020 | Settings::values.disable_fps_limit.SetValue(!Settings::values.disable_fps_limit.GetValue()); |
| 1085 | if (emu_thread != nullptr && emu_thread->IsRunning()) { | 1021 | }); |
| 1086 | OnCaptureScreenshot(); | 1022 | connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] { |
| 1087 | } | 1023 | Settings::values.mouse_panning = !Settings::values.mouse_panning; |
| 1088 | }); | 1024 | if (Settings::values.mouse_panning) { |
| 1089 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this), | 1025 | render_window->installEventFilter(render_window); |
| 1090 | &QShortcut::activated, this, [&] { | 1026 | render_window->setAttribute(Qt::WA_Hover, true); |
| 1091 | Settings::values.use_docked_mode.SetValue( | 1027 | } |
| 1092 | !Settings::values.use_docked_mode.GetValue()); | 1028 | }); |
| 1093 | OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(), | ||
| 1094 | Settings::values.use_docked_mode.GetValue(), *system); | ||
| 1095 | dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); | ||
| 1096 | }); | ||
| 1097 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this), | ||
| 1098 | &QShortcut::activated, this, | ||
| 1099 | [] { Settings::values.audio_muted = !Settings::values.audio_muted; }); | ||
| 1100 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Framerate Limit"), this), | ||
| 1101 | &QShortcut::activated, this, [] { | ||
| 1102 | Settings::values.disable_fps_limit.SetValue( | ||
| 1103 | !Settings::values.disable_fps_limit.GetValue()); | ||
| 1104 | }); | ||
| 1105 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this), | ||
| 1106 | &QShortcut::activated, this, [&] { | ||
| 1107 | Settings::values.mouse_panning = !Settings::values.mouse_panning; | ||
| 1108 | if (Settings::values.mouse_panning) { | ||
| 1109 | render_window->installEventFilter(render_window); | ||
| 1110 | render_window->setAttribute(Qt::WA_Hover, true); | ||
| 1111 | } | ||
| 1112 | }); | ||
| 1113 | } | 1029 | } |
| 1114 | 1030 | ||
| 1115 | void GMainWindow::SetDefaultUIGeometry() { | 1031 | void GMainWindow::SetDefaultUIGeometry() { |
| @@ -1164,7 +1080,8 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { | |||
| 1164 | (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { | 1080 | (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { |
| 1165 | auto_paused = true; | 1081 | auto_paused = true; |
| 1166 | OnPauseGame(); | 1082 | OnPauseGame(); |
| 1167 | } else if (ui->action_Start->isEnabled() && auto_paused && state == Qt::ApplicationActive) { | 1083 | } else if (emulation_running && !emu_thread->IsRunning() && auto_paused && |
| 1084 | state == Qt::ApplicationActive) { | ||
| 1168 | auto_paused = false; | 1085 | auto_paused = false; |
| 1169 | OnStartGame(); | 1086 | OnStartGame(); |
| 1170 | } | 1087 | } |
| @@ -1208,64 +1125,86 @@ void GMainWindow::ConnectWidgetEvents() { | |||
| 1208 | } | 1125 | } |
| 1209 | 1126 | ||
| 1210 | void GMainWindow::ConnectMenuEvents() { | 1127 | void GMainWindow::ConnectMenuEvents() { |
| 1128 | const auto connect_menu = [&]<typename Fn>(QAction* action, const Fn& event_fn) { | ||
| 1129 | connect(action, &QAction::triggered, this, event_fn); | ||
| 1130 | // Add actions to this window so that hiding menus in fullscreen won't disable them | ||
| 1131 | addAction(action); | ||
| 1132 | // Add actions to the render window so that they work outside of single window mode | ||
| 1133 | render_window->addAction(action); | ||
| 1134 | }; | ||
| 1135 | |||
| 1211 | // File | 1136 | // File |
| 1212 | connect(ui->action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); | 1137 | connect_menu(ui->action_Load_File, &GMainWindow::OnMenuLoadFile); |
| 1213 | connect(ui->action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder); | 1138 | connect_menu(ui->action_Load_Folder, &GMainWindow::OnMenuLoadFolder); |
| 1214 | connect(ui->action_Install_File_NAND, &QAction::triggered, this, | 1139 | connect_menu(ui->action_Install_File_NAND, &GMainWindow::OnMenuInstallToNAND); |
| 1215 | &GMainWindow::OnMenuInstallToNAND); | 1140 | connect_menu(ui->action_Exit, &QMainWindow::close); |
| 1216 | connect(ui->action_Exit, &QAction::triggered, this, &QMainWindow::close); | 1141 | connect_menu(ui->action_Load_Amiibo, &GMainWindow::OnLoadAmiibo); |
| 1217 | connect(ui->action_Load_Amiibo, &QAction::triggered, this, &GMainWindow::OnLoadAmiibo); | ||
| 1218 | 1142 | ||
| 1219 | // Emulation | 1143 | // Emulation |
| 1220 | connect(ui->action_Start, &QAction::triggered, this, &GMainWindow::OnStartGame); | 1144 | connect_menu(ui->action_Pause, &GMainWindow::OnPauseContinueGame); |
| 1221 | connect(ui->action_Pause, &QAction::triggered, this, &GMainWindow::OnPauseGame); | 1145 | connect_menu(ui->action_Stop, &GMainWindow::OnStopGame); |
| 1222 | connect(ui->action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame); | 1146 | connect_menu(ui->action_Report_Compatibility, &GMainWindow::OnMenuReportCompatibility); |
| 1223 | connect(ui->action_Report_Compatibility, &QAction::triggered, this, | 1147 | connect_menu(ui->action_Open_Mods_Page, &GMainWindow::OnOpenModsPage); |
| 1224 | &GMainWindow::OnMenuReportCompatibility); | 1148 | connect_menu(ui->action_Open_Quickstart_Guide, &GMainWindow::OnOpenQuickstartGuide); |
| 1225 | connect(ui->action_Open_Mods_Page, &QAction::triggered, this, &GMainWindow::OnOpenModsPage); | 1149 | connect_menu(ui->action_Open_FAQ, &GMainWindow::OnOpenFAQ); |
| 1226 | connect(ui->action_Open_Quickstart_Guide, &QAction::triggered, this, | 1150 | connect_menu(ui->action_Restart, &GMainWindow::OnRestartGame); |
| 1227 | &GMainWindow::OnOpenQuickstartGuide); | 1151 | connect_menu(ui->action_Configure, &GMainWindow::OnConfigure); |
| 1228 | connect(ui->action_Open_FAQ, &QAction::triggered, this, &GMainWindow::OnOpenFAQ); | 1152 | connect_menu(ui->action_Configure_Current_Game, &GMainWindow::OnConfigurePerGame); |
| 1229 | connect(ui->action_Restart, &QAction::triggered, this, | ||
| 1230 | [this] { BootGame(QString(game_path)); }); | ||
| 1231 | connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); | ||
| 1232 | connect(ui->action_Configure_Current_Game, &QAction::triggered, this, | ||
| 1233 | &GMainWindow::OnConfigurePerGame); | ||
| 1234 | 1153 | ||
| 1235 | // View | 1154 | // View |
| 1236 | connect(ui->action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); | 1155 | connect_menu(ui->action_Fullscreen, &GMainWindow::ToggleFullscreen); |
| 1237 | connect(ui->action_Single_Window_Mode, &QAction::triggered, this, | 1156 | connect_menu(ui->action_Single_Window_Mode, &GMainWindow::ToggleWindowMode); |
| 1238 | &GMainWindow::ToggleWindowMode); | 1157 | connect_menu(ui->action_Display_Dock_Widget_Headers, &GMainWindow::OnDisplayTitleBars); |
| 1239 | connect(ui->action_Display_Dock_Widget_Headers, &QAction::triggered, this, | 1158 | connect_menu(ui->action_Show_Filter_Bar, &GMainWindow::OnToggleFilterBar); |
| 1240 | &GMainWindow::OnDisplayTitleBars); | 1159 | |
| 1241 | connect(ui->action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar); | ||
| 1242 | connect(ui->action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); | 1160 | connect(ui->action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); |
| 1243 | 1161 | ||
| 1244 | connect(ui->action_Reset_Window_Size_720, &QAction::triggered, this, | 1162 | connect_menu(ui->action_Reset_Window_Size_720, &GMainWindow::ResetWindowSize720); |
| 1245 | &GMainWindow::ResetWindowSize720); | 1163 | connect_menu(ui->action_Reset_Window_Size_900, &GMainWindow::ResetWindowSize900); |
| 1246 | connect(ui->action_Reset_Window_Size_900, &QAction::triggered, this, | 1164 | connect_menu(ui->action_Reset_Window_Size_1080, &GMainWindow::ResetWindowSize1080); |
| 1247 | &GMainWindow::ResetWindowSize900); | 1165 | ui->menu_Reset_Window_Size->addActions({ui->action_Reset_Window_Size_720, |
| 1248 | connect(ui->action_Reset_Window_Size_1080, &QAction::triggered, this, | 1166 | ui->action_Reset_Window_Size_900, |
| 1249 | &GMainWindow::ResetWindowSize1080); | 1167 | ui->action_Reset_Window_Size_1080}); |
| 1250 | ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_720); | ||
| 1251 | ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_900); | ||
| 1252 | ui->menu_Reset_Window_Size->addAction(ui->action_Reset_Window_Size_1080); | ||
| 1253 | 1168 | ||
| 1254 | // Tools | 1169 | // Tools |
| 1255 | connect(ui->action_Rederive, &QAction::triggered, this, | 1170 | connect_menu(ui->action_Rederive, std::bind(&GMainWindow::OnReinitializeKeys, this, |
| 1256 | std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); | 1171 | ReinitializeKeyBehavior::Warning)); |
| 1257 | connect(ui->action_Capture_Screenshot, &QAction::triggered, this, | 1172 | connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); |
| 1258 | &GMainWindow::OnCaptureScreenshot); | ||
| 1259 | 1173 | ||
| 1260 | // TAS | 1174 | // TAS |
| 1261 | connect(ui->action_TAS_Start, &QAction::triggered, this, &GMainWindow::OnTasStartStop); | 1175 | connect_menu(ui->action_TAS_Start, &GMainWindow::OnTasStartStop); |
| 1262 | connect(ui->action_TAS_Record, &QAction::triggered, this, &GMainWindow::OnTasRecord); | 1176 | connect_menu(ui->action_TAS_Record, &GMainWindow::OnTasRecord); |
| 1263 | connect(ui->action_TAS_Reset, &QAction::triggered, this, &GMainWindow::OnTasReset); | 1177 | connect_menu(ui->action_TAS_Reset, &GMainWindow::OnTasReset); |
| 1264 | connect(ui->action_Configure_Tas, &QAction::triggered, this, &GMainWindow::OnConfigureTas); | 1178 | connect_menu(ui->action_Configure_Tas, &GMainWindow::OnConfigureTas); |
| 1265 | 1179 | ||
| 1266 | // Help | 1180 | // Help |
| 1267 | connect(ui->action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder); | 1181 | connect_menu(ui->action_Open_yuzu_Folder, &GMainWindow::OnOpenYuzuFolder); |
| 1268 | connect(ui->action_About, &QAction::triggered, this, &GMainWindow::OnAbout); | 1182 | connect_menu(ui->action_About, &GMainWindow::OnAbout); |
| 1183 | } | ||
| 1184 | |||
| 1185 | void GMainWindow::UpdateMenuState() { | ||
| 1186 | const bool is_paused = emu_thread == nullptr || !emu_thread->IsRunning(); | ||
| 1187 | |||
| 1188 | const std::array running_actions{ | ||
| 1189 | ui->action_Stop, | ||
| 1190 | ui->action_Restart, | ||
| 1191 | ui->action_Configure_Current_Game, | ||
| 1192 | ui->action_Report_Compatibility, | ||
| 1193 | ui->action_Load_Amiibo, | ||
| 1194 | ui->action_Pause, | ||
| 1195 | }; | ||
| 1196 | |||
| 1197 | for (QAction* action : running_actions) { | ||
| 1198 | action->setEnabled(emulation_running); | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | ui->action_Capture_Screenshot->setEnabled(emulation_running && !is_paused); | ||
| 1202 | |||
| 1203 | if (emulation_running && is_paused) { | ||
| 1204 | ui->action_Pause->setText(tr("&Continue")); | ||
| 1205 | } else { | ||
| 1206 | ui->action_Pause->setText(tr("&Pause")); | ||
| 1207 | } | ||
| 1269 | } | 1208 | } |
| 1270 | 1209 | ||
| 1271 | void GMainWindow::OnDisplayTitleBars(bool show) { | 1210 | void GMainWindow::OnDisplayTitleBars(bool show) { |
| @@ -1558,15 +1497,8 @@ void GMainWindow::ShutdownGame() { | |||
| 1558 | disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); | 1497 | disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); |
| 1559 | 1498 | ||
| 1560 | // Update the GUI | 1499 | // Update the GUI |
| 1561 | ui->action_Start->setEnabled(false); | 1500 | UpdateMenuState(); |
| 1562 | ui->action_Start->setText(tr("Start")); | 1501 | |
| 1563 | ui->action_Pause->setEnabled(false); | ||
| 1564 | ui->action_Stop->setEnabled(false); | ||
| 1565 | ui->action_Restart->setEnabled(false); | ||
| 1566 | ui->action_Configure_Current_Game->setEnabled(false); | ||
| 1567 | ui->action_Report_Compatibility->setEnabled(false); | ||
| 1568 | ui->action_Load_Amiibo->setEnabled(false); | ||
| 1569 | ui->action_Capture_Screenshot->setEnabled(false); | ||
| 1570 | render_window->hide(); | 1502 | render_window->hide(); |
| 1571 | loading_screen->hide(); | 1503 | loading_screen->hide(); |
| 1572 | loading_screen->Clear(); | 1504 | loading_screen->Clear(); |
| @@ -2498,32 +2430,36 @@ void GMainWindow::OnStartGame() { | |||
| 2498 | 2430 | ||
| 2499 | connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); | 2431 | connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); |
| 2500 | 2432 | ||
| 2501 | ui->action_Start->setEnabled(false); | 2433 | UpdateMenuState(); |
| 2502 | ui->action_Start->setText(tr("&Continue")); | ||
| 2503 | |||
| 2504 | ui->action_Pause->setEnabled(true); | ||
| 2505 | ui->action_Stop->setEnabled(true); | ||
| 2506 | ui->action_Restart->setEnabled(true); | ||
| 2507 | ui->action_Configure_Current_Game->setEnabled(true); | ||
| 2508 | ui->action_Report_Compatibility->setEnabled(true); | ||
| 2509 | OnTasStateChanged(); | 2434 | OnTasStateChanged(); |
| 2510 | 2435 | ||
| 2511 | discord_rpc->Update(); | 2436 | discord_rpc->Update(); |
| 2512 | ui->action_Load_Amiibo->setEnabled(true); | 2437 | } |
| 2513 | ui->action_Capture_Screenshot->setEnabled(true); | 2438 | |
| 2439 | void GMainWindow::OnRestartGame() { | ||
| 2440 | if (!system->IsPoweredOn()) { | ||
| 2441 | return; | ||
| 2442 | } | ||
| 2443 | // Make a copy since BootGame edits game_path | ||
| 2444 | BootGame(QString(game_path)); | ||
| 2514 | } | 2445 | } |
| 2515 | 2446 | ||
| 2516 | void GMainWindow::OnPauseGame() { | 2447 | void GMainWindow::OnPauseGame() { |
| 2517 | emu_thread->SetRunning(false); | 2448 | emu_thread->SetRunning(false); |
| 2518 | 2449 | UpdateMenuState(); | |
| 2519 | ui->action_Start->setEnabled(true); | ||
| 2520 | ui->action_Pause->setEnabled(false); | ||
| 2521 | ui->action_Stop->setEnabled(true); | ||
| 2522 | ui->action_Capture_Screenshot->setEnabled(false); | ||
| 2523 | |||
| 2524 | AllowOSSleep(); | 2450 | AllowOSSleep(); |
| 2525 | } | 2451 | } |
| 2526 | 2452 | ||
| 2453 | void GMainWindow::OnPauseContinueGame() { | ||
| 2454 | if (emulation_running) { | ||
| 2455 | if (emu_thread->IsRunning()) { | ||
| 2456 | OnPauseGame(); | ||
| 2457 | } else { | ||
| 2458 | OnStartGame(); | ||
| 2459 | } | ||
| 2460 | } | ||
| 2461 | } | ||
| 2462 | |||
| 2527 | void GMainWindow::OnStopGame() { | 2463 | void GMainWindow::OnStopGame() { |
| 2528 | if (system->GetExitLock() && !ConfirmForceLockedExit()) { | 2464 | if (system->GetExitLock() && !ConfirmForceLockedExit()) { |
| 2529 | return; | 2465 | return; |
| @@ -2882,6 +2818,10 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file | |||
| 2882 | } | 2818 | } |
| 2883 | 2819 | ||
| 2884 | void GMainWindow::OnLoadAmiibo() { | 2820 | void GMainWindow::OnLoadAmiibo() { |
| 2821 | if (emu_thread == nullptr || !emu_thread->IsRunning()) { | ||
| 2822 | return; | ||
| 2823 | } | ||
| 2824 | |||
| 2885 | const QString extensions{QStringLiteral("*.bin")}; | 2825 | const QString extensions{QStringLiteral("*.bin")}; |
| 2886 | const QString file_filter = tr("Amiibo File (%1);; All Files (*.*)").arg(extensions); | 2826 | const QString file_filter = tr("Amiibo File (%1);; All Files (*.*)").arg(extensions); |
| 2887 | const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), {}, file_filter); | 2827 | const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), {}, file_filter); |
| @@ -2945,6 +2885,10 @@ void GMainWindow::OnToggleFilterBar() { | |||
| 2945 | } | 2885 | } |
| 2946 | 2886 | ||
| 2947 | void GMainWindow::OnCaptureScreenshot() { | 2887 | void GMainWindow::OnCaptureScreenshot() { |
| 2888 | if (emu_thread == nullptr || !emu_thread->IsRunning()) { | ||
| 2889 | return; | ||
| 2890 | } | ||
| 2891 | |||
| 2948 | const u64 title_id = system->GetCurrentProcessProgramID(); | 2892 | const u64 title_id = system->GetCurrentProcessProgramID(); |
| 2949 | const auto screenshot_path = | 2893 | const auto screenshot_path = |
| 2950 | QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)); | 2894 | QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)); |
| @@ -3593,9 +3537,6 @@ void GMainWindow::OnLanguageChanged(const QString& locale) { | |||
| 3593 | LoadTranslation(); | 3537 | LoadTranslation(); |
| 3594 | ui->retranslateUi(this); | 3538 | ui->retranslateUi(this); |
| 3595 | UpdateWindowTitle(); | 3539 | UpdateWindowTitle(); |
| 3596 | |||
| 3597 | if (emulation_running) | ||
| 3598 | ui->action_Start->setText(tr("&Continue")); | ||
| 3599 | } | 3540 | } |
| 3600 | 3541 | ||
| 3601 | void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { | 3542 | void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 556cbbaf7..0fd41ed4f 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -191,6 +191,7 @@ private: | |||
| 191 | 191 | ||
| 192 | void ConnectWidgetEvents(); | 192 | void ConnectWidgetEvents(); |
| 193 | void ConnectMenuEvents(); | 193 | void ConnectMenuEvents(); |
| 194 | void UpdateMenuState(); | ||
| 194 | 195 | ||
| 195 | void PreventOSSleep(); | 196 | void PreventOSSleep(); |
| 196 | void AllowOSSleep(); | 197 | void AllowOSSleep(); |
| @@ -240,7 +241,9 @@ private: | |||
| 240 | 241 | ||
| 241 | private slots: | 242 | private slots: |
| 242 | void OnStartGame(); | 243 | void OnStartGame(); |
| 244 | void OnRestartGame(); | ||
| 243 | void OnPauseGame(); | 245 | void OnPauseGame(); |
| 246 | void OnPauseContinueGame(); | ||
| 244 | void OnStopGame(); | 247 | void OnStopGame(); |
| 245 | void OnMenuReportCompatibility(); | 248 | void OnMenuReportCompatibility(); |
| 246 | void OnOpenModsPage(); | 249 | void OnOpenModsPage(); |
| @@ -294,6 +297,9 @@ private slots: | |||
| 294 | void OnMouseActivity(); | 297 | void OnMouseActivity(); |
| 295 | 298 | ||
| 296 | private: | 299 | private: |
| 300 | /// Updates an action's shortcut and text to reflect an updated hotkey from the hotkey registry. | ||
| 301 | void LinkActionShortcut(QAction* action, const QString& action_name); | ||
| 302 | |||
| 297 | void RemoveBaseContent(u64 program_id, const QString& entry_type); | 303 | void RemoveBaseContent(u64 program_id, const QString& entry_type); |
| 298 | void RemoveUpdateContent(u64 program_id, const QString& entry_type); | 304 | void RemoveUpdateContent(u64 program_id, const QString& entry_type); |
| 299 | void RemoveAddOnContent(u64 program_id, const QString& entry_type); | 305 | void RemoveAddOnContent(u64 program_id, const QString& entry_type); |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index c58aa2866..5719b2ee4 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -66,7 +66,6 @@ | |||
| 66 | <property name="title"> | 66 | <property name="title"> |
| 67 | <string>&Emulation</string> | 67 | <string>&Emulation</string> |
| 68 | </property> | 68 | </property> |
| 69 | <addaction name="action_Start"/> | ||
| 70 | <addaction name="action_Pause"/> | 69 | <addaction name="action_Pause"/> |
| 71 | <addaction name="action_Stop"/> | 70 | <addaction name="action_Stop"/> |
| 72 | <addaction name="action_Restart"/> | 71 | <addaction name="action_Restart"/> |
| @@ -180,14 +179,6 @@ | |||
| 180 | <string>E&xit</string> | 179 | <string>E&xit</string> |
| 181 | </property> | 180 | </property> |
| 182 | </action> | 181 | </action> |
| 183 | <action name="action_Start"> | ||
| 184 | <property name="enabled"> | ||
| 185 | <bool>false</bool> | ||
| 186 | </property> | ||
| 187 | <property name="text"> | ||
| 188 | <string>&Start</string> | ||
| 189 | </property> | ||
| 190 | </action> | ||
| 191 | <action name="action_Pause"> | 182 | <action name="action_Pause"> |
| 192 | <property name="enabled"> | 183 | <property name="enabled"> |
| 193 | <bool>false</bool> | 184 | <bool>false</bool> |