pcsx2/pcsx2-qt/MainWindow.h

311 lines
10 KiB
C
Raw Normal View History

// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
2021-12-13 12:12:54 +00:00
#pragma once
2022-10-15 09:03:52 +00:00
#include "common/WindowInfo.h"
#include <QtWidgets/QLabel>
2021-12-13 12:12:54 +00:00
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
2022-04-06 10:49:00 +00:00
#include <functional>
2021-12-13 12:12:54 +00:00
#include <optional>
#include "Tools/InputRecording/InputRecordingViewer.h"
#include "Settings/ControllerSettingsWindow.h"
#include "Settings/SettingsWindow.h"
#include "Debugger/DebuggerWindow.h"
2021-12-13 12:12:54 +00:00
#include "ui_MainWindow.h"
class QProgressBar;
2022-04-04 11:27:23 +00:00
class AutoUpdaterDialog;
2021-12-13 12:12:54 +00:00
class DisplayWidget;
class DisplayContainer;
class GameListWidget;
class ControllerSettingsWindow;
2021-12-13 12:12:54 +00:00
class EmuThread;
namespace Achievements
{
enum class LoginRequestReason;
}
2021-12-13 12:12:54 +00:00
namespace GameList
{
struct Entry;
}
2022-06-28 13:34:45 +00:00
enum class CDVD_SourceType : uint8_t;
2021-12-13 12:12:54 +00:00
class MainWindow final : public QMainWindow
{
Q_OBJECT
public:
/// This class is a scoped lock on the VM, which prevents it from running while
/// the object exists. Its purpose is to be used for blocking/modal popup boxes,
/// where the VM needs to exit fullscreen temporarily.
class VMLock
{
public:
VMLock(VMLock&& lock);
VMLock(const VMLock&) = delete;
~VMLock();
VMLock& operator=(VMLock&& lock);
VMLock& operator=(const VMLock&) = delete;
/// Returns the parent widget, which can be used for any popup dialogs.
__fi QWidget* getDialogParent() const { return m_dialog_parent; }
/// Cancels any pending unpause/fullscreen transition.
/// Call when you're going to destroy the VM anyway.
void cancelResume();
private:
VMLock(QWidget* dialog_parent, bool was_paused, bool was_exclusive_fullscreen);
friend MainWindow;
QWidget* m_dialog_parent;
bool m_was_paused;
bool m_was_fullscreen;
};
/// Default filter for opening a file.
static const char* OPEN_FILE_FILTER;
/// Default filter for opening a disc image.
static const char* DISC_IMAGE_FILTER;
2021-12-13 12:12:54 +00:00
public:
MainWindow();
2021-12-13 12:12:54 +00:00
~MainWindow();
void initialize();
void connectVMThreadSignals(EmuThread* thread);
2022-04-04 11:27:23 +00:00
void startupUpdateCheck();
2022-09-07 07:44:10 +00:00
void resetSettings(bool ui);
2021-12-13 12:12:54 +00:00
/// Locks the VM by pausing it, while a popup dialog is displayed.
VMLock pauseAndLockVM();
2022-07-03 13:30:03 +00:00
/// Accessors for the status bar widgets, updated by the emulation thread.
__fi QLabel* getStatusVerboseWidget() const { return m_status_verbose_widget; }
__fi QLabel* getStatusRendererWidget() const { return m_status_renderer_widget; }
__fi QLabel* getStatusResolutionWidget() const { return m_status_resolution_widget; }
__fi QLabel* getStatusFPSWidget() const { return m_status_fps_widget; }
__fi QLabel* getStatusVPSWidget() const { return m_status_vps_widget; }
/// Rescans a single file. NOTE: Happens on UI thread.
void rescanFile(const std::string& path);
2023-02-01 11:53:31 +00:00
void openDebugger();
2021-12-13 12:12:54 +00:00
public Q_SLOTS:
void checkForUpdates(bool display_message, bool force_check);
2021-12-13 12:12:54 +00:00
void refreshGameList(bool invalidate_cache);
void cancelGameListRefresh();
2021-12-13 12:12:54 +00:00
void reportError(const QString& title, const QString& message);
bool confirmMessage(const QString& title, const QString& message);
2022-04-06 10:49:00 +00:00
void runOnUIThread(const std::function<void()>& func);
void requestReset();
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool default_save_to_state = true);
void requestExit(bool allow_confirm = true);
void checkForSettingChanges();
2022-10-15 09:03:52 +00:00
std::optional<WindowInfo> getWindowInfo();
2021-12-13 12:12:54 +00:00
private Q_SLOTS:
2022-04-04 11:27:23 +00:00
void onUpdateCheckComplete();
std::optional<WindowInfo> acquireRenderWindow(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
2021-12-13 12:12:54 +00:00
void displayResizeRequested(qint32 width, qint32 height);
void mouseModeRequested(bool relative_mode, bool hide_cursor);
void releaseRenderWindow();
2021-12-13 12:12:54 +00:00
void focusDisplayWidget();
void onGameListRefreshComplete();
void onGameListRefreshProgress(const QString& status, int current, int total);
void onGameListSelectionChanged();
void onGameListEntryActivated();
void onGameListEntryContextMenuRequested(const QPoint& point);
void onStartFileActionTriggered();
2022-06-28 13:34:45 +00:00
void onStartDiscActionTriggered();
2021-12-13 12:12:54 +00:00
void onStartBIOSActionTriggered();
void onChangeDiscFromFileActionTriggered();
void onChangeDiscFromGameListActionTriggered();
void onChangeDiscFromDeviceActionTriggered();
2022-06-28 14:00:51 +00:00
void onRemoveDiscActionTriggered();
2021-12-13 12:12:54 +00:00
void onChangeDiscMenuAboutToShow();
void onChangeDiscMenuAboutToHide();
void onLoadStateMenuAboutToShow();
void onSaveStateMenuAboutToShow();
2023-09-04 11:34:57 +00:00
void onStartFullscreenUITriggered();
void onFullscreenUIStateChange(bool running);
2021-12-13 12:12:54 +00:00
void onViewToolbarActionToggled(bool checked);
void onViewLockToolbarActionToggled(bool checked);
void onViewStatusBarActionToggled(bool checked);
void onViewGameListActionTriggered();
void onViewGameGridActionTriggered();
void onViewSystemDisplayTriggered();
void onViewGamePropertiesActionTriggered();
void onGitHubRepositoryActionTriggered();
void onSupportForumsActionTriggered();
void onDiscordServerActionTriggered();
void onAboutActionTriggered();
void onToolsOpenDataDirectoryTriggered();
2022-09-03 11:29:02 +00:00
void onToolsCoverDownloaderTriggered();
void onToolsEditCheatsPatchesTriggered(bool cheats);
void updateTheme();
void reloadThemeSpecificImages();
2023-06-19 12:03:10 +00:00
void updateLanguage();
void onScreenshotActionTriggered();
void onSaveGSDumpActionTriggered();
2022-05-24 12:22:15 +00:00
void onBlockDumpActionToggled(bool checked);
void onShowAdvancedSettingsToggled(bool checked);
2022-12-18 13:05:00 +00:00
void onToolsVideoCaptureToggled(bool checked);
void onSettingsTriggeredFromToolbar();
2021-12-13 12:12:54 +00:00
// Input Recording
void onInputRecNewActionTriggered();
void onInputRecPlayActionTriggered();
void onInputRecStopActionTriggered();
void onInputRecOpenSettingsTriggered();
void onInputRecOpenViewer();
2021-12-13 12:12:54 +00:00
void onVMStarting();
void onVMStarted();
void onVMPaused();
void onVMResumed();
void onVMStopped();
void onGameChanged(const QString& title, const QString& elf_override, const QString& disc_path,
const QString& serial, quint32 disc_crc, quint32 crc);
2021-12-13 12:12:54 +00:00
2023-07-06 13:18:30 +00:00
void onCaptureStarted(const QString& filename);
void onCaptureStopped();
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
2023-09-17 10:19:51 +00:00
void onAchievementsLoginSucceeded(const QString& display_name, quint32 points, quint32 sc_points, quint32 unread_messages);
void onAchievementsHardcoreModeChanged(bool enabled);
2021-12-13 12:12:54 +00:00
protected:
void showEvent(QShowEvent* event) override;
2022-03-04 08:04:05 +00:00
void closeEvent(QCloseEvent* event) override;
void changeEvent(QEvent* event) override;
2022-05-26 07:49:40 +00:00
void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent* event) override;
2024-01-11 09:38:28 +00:00
void moveEvent(QMoveEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
2021-12-13 12:12:54 +00:00
#ifdef _WIN32
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
#endif
2021-12-13 12:12:54 +00:00
private:
void setupAdditionalUi();
void connectSignals();
void createRendererSwitchMenu();
2022-09-07 07:44:10 +00:00
void recreate();
void recreateSettings();
void destroySubWindows();
2021-12-13 12:12:54 +00:00
void registerForDeviceNotifications();
void unregisterForDeviceNotifications();
2021-12-13 12:12:54 +00:00
void saveStateToConfig();
void restoreStateFromConfig();
void updateEmulationActions(bool starting, bool running, bool stopping);
void updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen);
void updateGameDependentActions();
void updateStatusBarWidgetVisibility();
2021-12-13 12:12:54 +00:00
void updateWindowTitle();
2022-06-28 12:16:45 +00:00
void updateWindowState(bool force_visible = false);
2021-12-13 12:12:54 +00:00
void setProgressBar(int current, int total);
void clearProgressBar();
bool isShowingGameList() const;
2022-05-06 11:03:16 +00:00
bool isRenderingFullscreen() const;
bool isRenderingToMain() const;
bool shouldHideMouseCursor() const;
2022-07-09 09:14:48 +00:00
bool shouldHideMainWindow() const;
2021-12-13 12:12:54 +00:00
void switchToGameListView();
void switchToEmulationView();
bool shouldAbortForMemcardBusy(const VMLock& lock);
2022-07-09 06:59:13 +00:00
QWidget* getContentParent();
2021-12-13 12:12:54 +00:00
QWidget* getDisplayContainer() const;
void saveDisplayWindowGeometryToConfig();
void restoreDisplayWindowGeometryFromConfig();
void createDisplayWidget(bool fullscreen, bool render_to_main);
2022-07-09 06:59:13 +00:00
void destroyDisplayWidget(bool show_game_list);
void updateDisplayWidgetCursor();
2021-12-13 12:12:54 +00:00
SettingsWindow* getSettingsWindow();
2022-02-15 14:29:18 +00:00
void doSettings(const char* category = nullptr);
2021-12-13 12:12:54 +00:00
InputRecordingViewer* getInputRecordingViewer();
void updateInputRecordingActions(bool started);
DebuggerWindow* getDebuggerWindow();
void doControllerSettings(ControllerSettingsWindow::Category category = ControllerSettingsWindow::Category::Count);
2021-12-13 12:12:54 +00:00
2022-06-28 13:34:45 +00:00
QString getDiscDevicePath(const QString& title);
void startGameListEntry(
const GameList::Entry* entry, std::optional<s32> save_slot = std::nullopt, std::optional<bool> fast_boot = std::nullopt);
2021-12-13 12:12:54 +00:00
void setGameListEntryCoverImage(const GameList::Entry* entry);
void clearGameListEntryPlayTime(const GameList::Entry* entry);
2021-12-13 12:12:54 +00:00
2022-05-07 12:56:44 +00:00
std::optional<bool> promptForResumeState(const QString& save_state_path);
2021-12-13 12:12:54 +00:00
void loadSaveStateSlot(s32 slot);
void loadSaveStateFile(const QString& filename, const QString& state_filename);
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
2022-06-28 13:34:45 +00:00
void doStartFile(std::optional<CDVD_SourceType> source, const QString& path);
void doDiscChange(CDVD_SourceType source, const QString& path);
2021-12-13 12:12:54 +00:00
Ui::MainWindow m_ui;
GameListWidget* m_game_list_widget = nullptr;
DisplayWidget* m_display_widget = nullptr;
DisplayContainer* m_display_container = nullptr;
2023-10-15 05:44:11 +00:00
SettingsWindow* m_settings_window = nullptr;
ControllerSettingsWindow* m_controller_settings_window = nullptr;
InputRecordingViewer* m_input_recording_viewer = nullptr;
2022-04-04 11:27:23 +00:00
AutoUpdaterDialog* m_auto_updater_dialog = nullptr;
2021-12-13 12:12:54 +00:00
DebuggerWindow* m_debugger_window = nullptr;
2021-12-13 12:12:54 +00:00
QProgressBar* m_status_progress_widget = nullptr;
2022-07-03 13:30:03 +00:00
QLabel* m_status_verbose_widget = nullptr;
QLabel* m_status_renderer_widget = nullptr;
QLabel* m_status_fps_widget = nullptr;
2022-07-03 13:30:03 +00:00
QLabel* m_status_vps_widget = nullptr;
QLabel* m_status_resolution_widget = nullptr;
2021-12-13 12:12:54 +00:00
QMenu* m_settings_toolbar_menu = nullptr;
bool m_display_created = false;
bool m_relative_mouse_mode = false;
bool m_hide_mouse_cursor = false;
2022-05-06 11:03:16 +00:00
bool m_was_paused_on_surface_loss = false;
bool m_was_disc_change_request = false;
2022-06-29 02:44:10 +00:00
bool m_is_closing = false;
bool m_is_temporarily_windowed = false;
QString m_last_fps_status;
#ifdef _WIN32
void* m_device_notification_handle = nullptr;
#endif
2021-12-13 12:12:54 +00:00
};
extern MainWindow* g_main_window;