diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d292507d..7beb196d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ add_executable(obliteration WIN32 MACOSX_BUNDLE ansi_escape.cpp app_data.cpp core.cpp + display_settings.cpp game_graphic_settings.cpp game_models.cpp game_settings.cpp diff --git a/src/display_settings.cpp b/src/display_settings.cpp new file mode 100644 index 00000000..2922e1f8 --- /dev/null +++ b/src/display_settings.cpp @@ -0,0 +1,10 @@ +#include "display_settings.hpp" + +DisplaySettings::DisplaySettings(QWidget *parent) : + QWidget(parent) +{ +} + +DisplaySettings::~DisplaySettings() +{ +} diff --git a/src/display_settings.hpp b/src/display_settings.hpp new file mode 100644 index 00000000..5b77ecf2 --- /dev/null +++ b/src/display_settings.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +class DisplaySettings final : public QWidget { +public: + DisplaySettings(QWidget *parent = nullptr); + ~DisplaySettings() override; +}; diff --git a/src/launch_settings.cpp b/src/launch_settings.cpp index 40641b47..fed51332 100644 --- a/src/launch_settings.cpp +++ b/src/launch_settings.cpp @@ -1,19 +1,32 @@ #include "launch_settings.hpp" +#include "display_settings.hpp" +#include "game_models.hpp" +#include "game_settings.hpp" +#include "game_settings_dialog.hpp" +#include "resources.hpp" +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include -LaunchSettings::LaunchSettings(QWidget *parent) : - QWidget(parent) +LaunchSettings::LaunchSettings(GameListModel *games, QWidget *parent) : + QWidget(parent), + m_display(nullptr), + m_games(nullptr), + m_profiles(nullptr) { auto layout = new QVBoxLayout(); - // Start button. - auto start = new QPushButton("Start"); - - connect(start, &QAbstractButton::clicked, [this]() { emit startClicked(); }); - - layout->addWidget(start); + layout->addWidget(buildSettings(games)); + layout->addLayout(buildActions()); setLayout(layout); } @@ -21,3 +34,94 @@ LaunchSettings::LaunchSettings(QWidget *parent) : LaunchSettings::~LaunchSettings() { } + +QWidget *LaunchSettings::buildSettings(GameListModel *games) +{ + // Tab. + auto tab = new QTabWidget(); + + // Display settings. + m_display = new DisplaySettings(); + + tab->addTab(m_display, loadIcon(":/resources/monitor.svg"), "Display"); + + // Game list. + m_games = new QTableView(); + m_games->setContextMenuPolicy(Qt::CustomContextMenu); + m_games->setSortingEnabled(true); + m_games->setWordWrap(false); + m_games->setModel(games); + m_games->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + m_games->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + m_games->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + m_games->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + connect(m_games, &QWidget::customContextMenuRequested, this, &LaunchSettings::requestGamesContextMenu); + + tab->addTab(m_games, loadIcon(":/resources/view-comfy.svg"), "Games"); + + return tab; +} + +QLayout *LaunchSettings::buildActions() +{ + auto layout = new QHBoxLayout(); + + // Profile list. + m_profiles = new QComboBox(); + + layout->addWidget(m_profiles, 1); + + // Actions bar. + auto actions = new QDialogButtonBox(); + + layout->addWidget(actions); + + // Save button. + auto save = actions->addButton("Save", QDialogButtonBox::ApplyRole); + + // Start button. + auto start = actions->addButton("Start", QDialogButtonBox::AcceptRole); + + connect(start, &QAbstractButton::clicked, [this]() { emit startClicked(); }); + + return layout; +} + +void LaunchSettings::requestGamesContextMenu(const QPoint &pos) +{ + // Get item index. + auto index = m_games->indexAt(pos); + + if (!index.isValid()) { + return; + } + + auto model = reinterpret_cast(m_games->model()); + auto game = model->get(index.row()); + + // Setup menu. + QMenu menu(this); + QAction openFolder(loadIcon(":/resources/folder-open-outline.svg"), "Open &Folder", this); + QAction settings(loadIcon(":/resources/cog-outline.svg"), "&Settings", this); + + menu.addAction(&openFolder); + menu.addAction(&settings); + + // Show menu. + auto selected = menu.exec(m_games->viewport()->mapToGlobal(pos)); + + if (!selected) { + return; + } + + if (selected == &openFolder) { + QDesktopServices::openUrl(QUrl::fromLocalFile(game->directory())); + } else if (selected == &settings) { + // Load settings then show a dialog to edit. + auto settings = GameSettings::load(game); + GameSettingsDialog dialog(game, settings.get(), this); + + dialog.exec(); + } +} diff --git a/src/launch_settings.hpp b/src/launch_settings.hpp index 27279983..77c85367 100644 --- a/src/launch_settings.hpp +++ b/src/launch_settings.hpp @@ -2,12 +2,26 @@ #include +class DisplaySettings; +class GameListModel; +class QComboBox; +class QLayout; +class QTableView; + class LaunchSettings final : public QWidget { Q_OBJECT public: - LaunchSettings(QWidget *parent = nullptr); + LaunchSettings(GameListModel *games, QWidget *parent = nullptr); ~LaunchSettings() override; - signals: void startClicked(); +private: + QWidget *buildSettings(GameListModel *games); + QLayout *buildActions(); + + void requestGamesContextMenu(const QPoint &pos); + + DisplaySettings *m_display; + QTableView *m_games; + QComboBox *m_profiles; }; diff --git a/src/main.cpp b/src/main.cpp index 02b17155..ed16e640 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,11 +17,7 @@ int main(int argc, char *argv[]) // Setup application. QCoreApplication::setOrganizationName("OBHQ"); QCoreApplication::setApplicationName("Obliteration"); - - // Dark Mode for Windows. -#ifdef _WIN32 QApplication::setStyle("Fusion"); -#endif QApplication app(argc, argv); diff --git a/src/main_window.cpp b/src/main_window.cpp index 463f14d1..0a2d4905 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -1,7 +1,5 @@ #include "main_window.hpp" #include "game_models.hpp" -#include "game_settings.hpp" -#include "game_settings_dialog.hpp" #include "launch_settings.hpp" #include "logs_viewer.hpp" #include "path.hpp" @@ -16,9 +14,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -26,8 +22,6 @@ #include #include #include -#include -#include #include #include @@ -35,10 +29,9 @@ #include MainWindow::MainWindow() : - m_tab(nullptr), - m_screen(nullptr), - m_launch(nullptr), - m_games(nullptr) + m_main(nullptr), + m_games(nullptr), + m_launch(nullptr) { setWindowTitle("Obliteration"); @@ -86,35 +79,17 @@ MainWindow::MainWindow() : helpMenu->addAction(about); // Central widget. - m_tab = new QTabWidget(this); - m_tab->setDocumentMode(true); - m_tab->tabBar()->setExpanding(true); + m_main = new QStackedWidget(); - setCentralWidget(m_tab); - - // Setup screen tab. - m_screen = new QStackedWidget(); - - m_tab->addTab(m_screen, loadIcon(":/resources/monitor.svg"), "Screen"); + setCentralWidget(m_main); // Setup launch settings. - m_launch = new LaunchSettings(); + m_games = new GameListModel(this); + m_launch = new LaunchSettings(m_games); connect(m_launch, &LaunchSettings::startClicked, this, &MainWindow::startKernel); - m_screen->addWidget(m_launch); - - // Setup game list. - m_games = new QTableView(); - m_games->setContextMenuPolicy(Qt::CustomContextMenu); - m_games->setSortingEnabled(true); - m_games->setWordWrap(false); - m_games->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - m_games->setModel(new GameListModel(this)); - - connect(m_games, &QWidget::customContextMenuRequested, this, &MainWindow::requestGamesContextMenu); - - m_tab->addTab(m_games, loadIcon(":/resources/view-comfy.svg"), "Games"); + m_main->addWidget(m_launch); // Show the window. restoreGeometry(); @@ -150,10 +125,7 @@ bool MainWindow::loadGames() progress.setValue(++step); } - // Update widgets. - m_games->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - m_games->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_games->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + m_games->sort(0); return true; } @@ -266,58 +238,8 @@ void MainWindow::aboutObliteration() QMessageBox::about(this, "About Obliteration", "Obliteration is a free and open-source software for playing your PlayStation 4 titles on PC."); } -void MainWindow::requestGamesContextMenu(const QPoint &pos) -{ - // Get item index. - auto index = m_games->indexAt(pos); - - if (!index.isValid()) { - return; - } - - auto model = reinterpret_cast(m_games->model()); - auto game = model->get(index.row()); - - // Setup menu. - QMenu menu(this); - QAction openFolder("Open &Folder", this); - QAction settings("&Settings", this); - -#ifndef __APPLE__ - openFolder.setIcon(loadIcon(":/resources/folder-open-outline.svg")); - settings.setIcon(loadIcon(":/resources/cog-outline.svg")); -#endif - - menu.addAction(&openFolder); - menu.addAction(&settings); - - // Show menu. - auto selected = menu.exec(m_games->viewport()->mapToGlobal(pos)); - - if (!selected) { - return; - } - - if (selected == &openFolder) { - QString folderPath = game->directory(); - QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath)); - } else if (selected == &settings) { - // Load settings then show a dialog to edit. - auto settings = GameSettings::load(game); - GameSettingsDialog dialog(game, settings.get(), this); - - dialog.exec(); - } -} - void MainWindow::startKernel() { - // Just switch to screen tab if currently running. - if (m_kernel) { - m_tab->setCurrentIndex(0); - return; - } - // Get full path to kernel binary. std::string kernel; @@ -416,13 +338,12 @@ bool MainWindow::loadGame(const QString &gameId) } // Add to list. - auto list = reinterpret_cast(m_games->model()); RustPtr titleId, title; titleId = param_title_id_get(param); title = param_title_get(param); - list->add(new Game(titleId.get(), title.get(), gamePath.c_str())); + m_games->add(new Game(titleId.get(), title.get(), gamePath.c_str())); } return true; diff --git a/src/main_window.hpp b/src/main_window.hpp index df737d88..74924e2d 100644 --- a/src/main_window.hpp +++ b/src/main_window.hpp @@ -5,10 +5,10 @@ #include #include +class GameListModel; class LaunchSettings; class LogsViewer; class QStackedWidget; -class QTableView; class MainWindow final : public QMainWindow { public: @@ -27,7 +27,6 @@ private slots: void viewLogs(); void reportIssue(); void aboutObliteration(); - void requestGamesContextMenu(const QPoint &pos); void startKernel(); private: @@ -35,11 +34,9 @@ private: void restoreGeometry(); bool requireEmulatorStopped(); -private: - QTabWidget *m_tab; - QStackedWidget *m_screen; + QStackedWidget *m_main; + GameListModel *m_games; LaunchSettings *m_launch; - QTableView *m_games; QPointer m_logs; RustPtr m_kernel; };