diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt index 85e0a61428..5ce34224ec 100644 --- a/Source/Core/DolphinQt2/CMakeLists.txt +++ b/Source/Core/DolphinQt2/CMakeLists.txt @@ -9,11 +9,13 @@ set(SRCS Host.cpp RenderWidget.cpp Resources.cpp + ToolBar.cpp GameList/GameFile.cpp GameList/GameList.cpp GameList/GameTracker.cpp GameList/GameListModel.cpp - GameList/GameListProxyModel.cpp + GameList/TableProxyModel.cpp + GameList/ListProxyModel.cpp ) list(APPEND LIBS core uicommon) diff --git a/Source/Core/DolphinQt2/GameList/GameList.cpp b/Source/Core/DolphinQt2/GameList/GameList.cpp index c7bb03327b..81be2cf69f 100644 --- a/Source/Core/DolphinQt2/GameList/GameList.cpp +++ b/Source/Core/DolphinQt2/GameList/GameList.cpp @@ -6,14 +6,16 @@ #include "Core/ConfigManager.h" #include "DolphinQt2/GameList/GameList.h" -#include "DolphinQt2/GameList/GameListProxyModel.h" +#include "DolphinQt2/GameList/ListProxyModel.h" +#include "DolphinQt2/GameList/TableProxyModel.h" GameList::GameList(QWidget* parent): QStackedWidget(parent) { m_model = new GameListModel(this); - m_proxy = new GameListProxyModel(this); - m_proxy->setSourceModel(m_model); - m_proxy->setSortCaseSensitivity(Qt::CaseInsensitive); + m_table_proxy = new TableProxyModel(this); + m_table_proxy->setSourceModel(m_model); + m_list_proxy = new ListProxyModel(this); + m_list_proxy->setSourceModel(m_model); MakeTableView(); MakeListView(); @@ -30,7 +32,7 @@ GameList::GameList(QWidget* parent): QStackedWidget(parent) void GameList::MakeTableView() { m_table = new QTableView(this); - m_table->setModel(m_proxy); + m_table->setModel(m_table_proxy); m_table->setSelectionMode(QAbstractItemView::SingleSelection); m_table->setSelectionBehavior(QAbstractItemView::SelectRows); m_table->setAlternatingRowColors(true); @@ -44,9 +46,6 @@ void GameList::MakeTableView() m_table->setColumnWidth(GameListModel::COL_COUNTRY, 38); m_table->setColumnWidth(GameListModel::COL_RATING, 52); - // This column is for the icon view. Hide it. - m_table->setColumnHidden(GameListModel::COL_LARGE_ICON, true); - QHeaderView* header = m_table->horizontalHeader(); header->setSectionResizeMode(GameListModel::COL_PLATFORM, QHeaderView::Fixed); header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::Fixed); @@ -62,23 +61,31 @@ void GameList::MakeTableView() void GameList::MakeListView() { m_list = new QListView(this); - m_list->setModel(m_proxy); + m_list->setModel(m_list_proxy); m_list->setViewMode(QListView::IconMode); - m_list->setModelColumn(GameListModel::COL_LARGE_ICON); m_list->setResizeMode(QListView::Adjust); m_list->setUniformItemSizes(true); } QString GameList::GetSelectedGame() const { - QItemSelectionModel* sel_model; + QAbstractItemView* view; + QSortFilterProxyModel* proxy; if (currentWidget() == m_table) - sel_model = m_table->selectionModel(); + { + view = m_table; + proxy = m_table_proxy; + } else - sel_model = m_list->selectionModel(); - + { + view = m_list; + proxy = m_list_proxy; + } + QItemSelectionModel* sel_model = view->selectionModel(); if (sel_model->hasSelection()) - return m_model->GetPath(m_proxy->mapToSource(sel_model->selectedIndexes()[0]).row()); - else - return QString(); + { + QModelIndex model_index = proxy->mapToSource(sel_model->selectedIndexes()[0]); + return m_model->GetPath(model_index.row()); + } + return QStringLiteral(); } diff --git a/Source/Core/DolphinQt2/GameList/GameList.h b/Source/Core/DolphinQt2/GameList/GameList.h index a52571e77c..269db3b1bb 100644 --- a/Source/Core/DolphinQt2/GameList/GameList.h +++ b/Source/Core/DolphinQt2/GameList/GameList.h @@ -35,7 +35,9 @@ private: void MakeListView(); GameListModel* m_model; - QSortFilterProxyModel* m_proxy; + QSortFilterProxyModel* m_table_proxy; + QSortFilterProxyModel* m_list_proxy; + QListView* m_list; QTableView* m_table; }; diff --git a/Source/Core/DolphinQt2/GameList/GameListModel.h b/Source/Core/DolphinQt2/GameList/GameListModel.h index 5e0080d947..610db4389c 100644 --- a/Source/Core/DolphinQt2/GameList/GameListModel.h +++ b/Source/Core/DolphinQt2/GameList/GameListModel.h @@ -37,7 +37,6 @@ public: COL_SIZE, COL_COUNTRY, COL_RATING, - COL_LARGE_ICON, NUM_COLS }; diff --git a/Source/Core/DolphinQt2/GameList/ListProxyModel.cpp b/Source/Core/DolphinQt2/GameList/ListProxyModel.cpp new file mode 100644 index 0000000000..3ec6ccba03 --- /dev/null +++ b/Source/Core/DolphinQt2/GameList/ListProxyModel.cpp @@ -0,0 +1,38 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +#include "DolphinQt2/GameList/GameListModel.h" +#include "DolphinQt2/GameList/ListProxyModel.h" + +static constexpr QSize LARGE_BANNER_SIZE(144, 48); + +ListProxyModel::ListProxyModel(QObject* parent) + : QSortFilterProxyModel(parent) +{ + setSortCaseSensitivity(Qt::CaseInsensitive); + sort(GameListModel::COL_TITLE); +} + +QVariant ListProxyModel::data(const QModelIndex& i, int role) const +{ + QModelIndex source_index = mapToSource(i); + if (role == Qt::DisplayRole) + { + return sourceModel()->data( + sourceModel()->index(source_index.row(), GameListModel::COL_TITLE), + Qt::DisplayRole); + } + else if (role == Qt::DecorationRole) + { + return sourceModel()->data( + sourceModel()->index(source_index.row(), GameListModel::COL_BANNER), + Qt::DisplayRole).value().scaled( + LARGE_BANNER_SIZE, + Qt::KeepAspectRatio, + Qt::SmoothTransformation); + } + return QVariant(); +} diff --git a/Source/Core/DolphinQt2/GameList/ListProxyModel.h b/Source/Core/DolphinQt2/GameList/ListProxyModel.h new file mode 100644 index 0000000000..cabdf94b78 --- /dev/null +++ b/Source/Core/DolphinQt2/GameList/ListProxyModel.h @@ -0,0 +1,14 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +class ListProxyModel final : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + ListProxyModel(QObject* parent = nullptr); + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; +}; diff --git a/Source/Core/DolphinQt2/GameList/GameListProxyModel.cpp b/Source/Core/DolphinQt2/GameList/TableProxyModel.cpp similarity index 74% rename from Source/Core/DolphinQt2/GameList/GameListProxyModel.cpp rename to Source/Core/DolphinQt2/GameList/TableProxyModel.cpp index 6b4faedb86..df5766efe3 100644 --- a/Source/Core/DolphinQt2/GameList/GameListProxyModel.cpp +++ b/Source/Core/DolphinQt2/GameList/TableProxyModel.cpp @@ -4,10 +4,9 @@ #include "DolphinQt2/Resources.h" #include "DolphinQt2/GameList/GameListModel.h" -#include "DolphinQt2/GameList/GameListProxyModel.h" +#include "DolphinQt2/GameList/TableProxyModel.h" static constexpr QSize NORMAL_BANNER_SIZE(96, 32); -static constexpr QSize LARGE_BANNER_SIZE(144, 48); // Convert an integer size to a friendly string representation. static QString FormatSize(qint64 size) @@ -29,12 +28,13 @@ static QString FormatSize(qint64 size) return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit); } -GameListProxyModel::GameListProxyModel(QObject* parent) +TableProxyModel::TableProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { + setSortCaseSensitivity(Qt::CaseInsensitive); } -QVariant GameListProxyModel::data(const QModelIndex& i, int role) const +QVariant TableProxyModel::data(const QModelIndex& i, int role) const { QModelIndex source_index = mapToSource(i); QVariant source_data = sourceModel()->data(source_index, Qt::DisplayRole); @@ -51,9 +51,6 @@ QVariant GameListProxyModel::data(const QModelIndex& i, int role) const case GameListModel::COL_DESCRIPTION: case GameListModel::COL_MAKER: return source_data; - // Show the title in the display role of the icon view. - case GameListModel::COL_LARGE_ICON: - return data(index(i.row(), GameListModel::COL_TITLE), Qt::DisplayRole); } } else if (role == Qt::DecorationRole) @@ -74,13 +71,6 @@ QVariant GameListProxyModel::data(const QModelIndex& i, int role) const return Resources::GetCountry(source_data.toInt()); case GameListModel::COL_RATING: return Resources::GetRating(source_data.toInt()); - // Show a scaled icon in the decoration role of the icon view. - case GameListModel::COL_LARGE_ICON: - return data(index(i.row(), GameListModel::COL_BANNER), Qt::DecorationRole) - .value().scaled( - LARGE_BANNER_SIZE, - Qt::KeepAspectRatio, - Qt::SmoothTransformation); } } return QVariant(); diff --git a/Source/Core/DolphinQt2/GameList/GameListProxyModel.h b/Source/Core/DolphinQt2/GameList/TableProxyModel.h similarity index 83% rename from Source/Core/DolphinQt2/GameList/GameListProxyModel.h rename to Source/Core/DolphinQt2/GameList/TableProxyModel.h index b6728bdab3..d64662a1d3 100644 --- a/Source/Core/DolphinQt2/GameList/GameListProxyModel.h +++ b/Source/Core/DolphinQt2/GameList/TableProxyModel.h @@ -9,11 +9,11 @@ // For instance, the GameListModel exposes country as an integer, so this // class converts that into a flag, while still allowing sorting on the // underlying integer. -class GameListProxyModel final : public QSortFilterProxyModel +class TableProxyModel final : public QSortFilterProxyModel { Q_OBJECT public: - GameListProxyModel(QObject* parent = nullptr); + TableProxyModel(QObject* parent = nullptr); QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; }; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 09f8f1579b..e8be576fe6 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,8 +26,8 @@ MainWindow::MainWindow() : QMainWindow(nullptr) setWindowTitle(tr("Dolphin")); setWindowIcon(QIcon(Resources::GetMisc(Resources::LOGO_SMALL))); - MakeToolBar(); MakeGameList(); + MakeToolBar(); MakeRenderWidget(); MakeStack(); MakeMenus(); @@ -92,8 +93,7 @@ void MainWindow::AddTableColumnsMenu(QMenu* view_menu) SConfig::GetInstance().m_showRegionColumn, SConfig::GetInstance().m_showStateColumn, }; - // - 1 because we never show COL_LARGE_ICON column in the table. - for (int i = 0; i < GameListModel::NUM_COLS - 1; i++) + for (int i = 0; i < GameListModel::NUM_COLS; i++) { QAction* action = column_group->addAction(cols_menu->addAction(col_names[i])); action->setCheckable(true); @@ -151,12 +151,21 @@ void MainWindow::AddListTypePicker(QMenu* view_menu) void MainWindow::MakeToolBar() { - setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - m_tool_bar = addToolBar(tr("ToolBar")); - m_tool_bar->setMovable(false); - m_tool_bar->setFloatable(false); + m_tool_bar = new ToolBar(this); + addToolBar(m_tool_bar); - PopulateToolBar(); + connect(m_tool_bar, &ToolBar::OpenPressed, this, &MainWindow::Open); + // TODO make this open the config paths dialog, not the current Browse menu. + connect(m_tool_bar, &ToolBar::PathsPressed, this, &MainWindow::Browse); + connect(m_tool_bar, &ToolBar::PlayPressed, this, &MainWindow::Play); + connect(m_tool_bar, &ToolBar::PausePressed, this, &MainWindow::Pause); + connect(m_tool_bar, &ToolBar::StopPressed, this, &MainWindow::Stop); + connect(m_tool_bar, &ToolBar::FullScreenPressed, this, &MainWindow::FullScreen); + connect(m_tool_bar, &ToolBar::ScreenShotPressed, this, &MainWindow::ScreenShot); + + connect(this, &MainWindow::EmulationStarted, m_tool_bar, &ToolBar::EmulationStarted); + connect(this, &MainWindow::EmulationPaused, m_tool_bar, &ToolBar::EmulationPaused); + connect(this, &MainWindow::EmulationStopped, m_tool_bar, &ToolBar::EmulationStopped); } void MainWindow::MakeGameList() @@ -182,63 +191,6 @@ void MainWindow::MakeStack() setCentralWidget(m_stack); } -void MainWindow::PopulateToolBar() -{ - m_tool_bar->clear(); - - QString dir = QString::fromStdString(File::GetThemeDir(SConfig::GetInstance().theme_name)); - m_tool_bar->addAction( - QIcon(dir + QStringLiteral("open.png")), tr("Open"), - this, SLOT(Open())); - m_tool_bar->addAction( - QIcon(dir + QStringLiteral("browse.png")), tr("Browse"), - this, SLOT(Browse())); - - m_tool_bar->addSeparator(); - - QAction* play_action = m_tool_bar->addAction( - QIcon(dir + QStringLiteral("play.png")), tr("Play"), - this, SLOT(Play())); - connect(this, &MainWindow::EmulationStarted, [=](){ play_action->setEnabled(false); }); - connect(this, &MainWindow::EmulationPaused, [=](){ play_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationStopped, [=](){ play_action->setEnabled(true); }); - - QAction* pause_action = m_tool_bar->addAction( - QIcon(dir + QStringLiteral("pause.png")), tr("Pause"), - this, SLOT(Pause())); - pause_action->setEnabled(false); - connect(this, &MainWindow::EmulationStarted, [=](){ pause_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationPaused, [=](){ pause_action->setEnabled(false); }); - connect(this, &MainWindow::EmulationStopped, [=](){ pause_action->setEnabled(false); }); - - QAction* stop_action = m_tool_bar->addAction( - QIcon(dir + QStringLiteral("stop.png")), tr("Stop"), - this, SLOT(Stop())); - stop_action->setEnabled(false); - connect(this, &MainWindow::EmulationStarted, [=](){ stop_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationPaused, [=](){ stop_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationStopped, [=](){ stop_action->setEnabled(false); }); - - QAction* fullscreen_action = m_tool_bar->addAction( - QIcon(dir + QStringLiteral("fullscreen.png")), tr("Full Screen"), - this, SLOT(FullScreen())); - fullscreen_action->setEnabled(false); - connect(this, &MainWindow::EmulationStarted, [=](){ fullscreen_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationStopped, [=](){ fullscreen_action->setEnabled(false); }); - - QAction* screenshot_action = m_tool_bar->addAction( - QIcon(dir + QStringLiteral("screenshot.png")), tr("Screen Shot"), - this, SLOT(ScreenShot())); - screenshot_action->setEnabled(false); - connect(this, &MainWindow::EmulationStarted, [=](){ screenshot_action->setEnabled(true); }); - connect(this, &MainWindow::EmulationStopped, [=](){ screenshot_action->setEnabled(false); }); - - m_tool_bar->addSeparator(); - m_tool_bar->addAction(QIcon(dir + QStringLiteral("config.png")), tr("Settings"))->setEnabled(false); - m_tool_bar->addAction(QIcon(dir + QStringLiteral("graphics.png")), tr("Graphics"))->setEnabled(false); - m_tool_bar->addAction(QIcon(dir + QStringLiteral("classic.png")), tr("Controllers"))->setEnabled(false); -} - void MainWindow::Open() { QString file = QFileDialog::getOpenFileName(this, diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index 99ed25f054..96c62fb335 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -10,6 +10,7 @@ #include #include "DolphinQt2/RenderWidget.h" +#include "DolphinQt2/ToolBar.h" #include "DolphinQt2/GameList/GameList.h" class MainWindow final : public QMainWindow @@ -47,14 +48,12 @@ private: void AddTableColumnsMenu(QMenu* view_menu); void AddListTypePicker(QMenu* view_menu); - void PopulateToolBar(); - void StartGame(QString path); void ShowRenderWidget(); void HideRenderWidget(); QStackedWidget* m_stack; - QToolBar* m_tool_bar; + ToolBar* m_tool_bar; GameList* m_game_list; RenderWidget* m_render_widget; bool m_rendering_to_main; diff --git a/Source/Core/DolphinQt2/ToolBar.cpp b/Source/Core/DolphinQt2/ToolBar.cpp new file mode 100644 index 0000000000..649c1c2bd3 --- /dev/null +++ b/Source/Core/DolphinQt2/ToolBar.cpp @@ -0,0 +1,98 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +#include "Common/FileUtil.h" +#include "Core/ConfigManager.h" +#include "DolphinQt2/ToolBar.h" + +static constexpr QSize ICON_SIZE(32, 32); + +ToolBar::ToolBar(QWidget* parent) + : QToolBar(parent) +{ + setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + setMovable(false); + setFloatable(false); + setIconSize(ICON_SIZE); + + MakeActions(); + UpdateIcons(); +} + +void ToolBar::EmulationStarted() +{ + m_play_action->setEnabled(false); + m_pause_action->setEnabled(true); + m_stop_action->setEnabled(true); + m_fullscreen_action->setEnabled(true); + m_screenshot_action->setEnabled(true); +} + +void ToolBar::EmulationPaused() +{ + m_play_action->setEnabled(true); + m_pause_action->setEnabled(false); + m_stop_action->setEnabled(true); +} + +void ToolBar::EmulationStopped() +{ + m_play_action->setEnabled(true); + m_pause_action->setEnabled(false); + m_stop_action->setEnabled(false); + m_fullscreen_action->setEnabled(false); + m_screenshot_action->setEnabled(false); +} + +void ToolBar::MakeActions() +{ + m_open_action = addAction(tr("Open"), this, SIGNAL(OpenPressed())); + m_paths_action = addAction(tr("Paths"), this, SIGNAL(PathsPressed())); + + addSeparator(); + + m_play_action = addAction(tr("Play"), this, SIGNAL(PlayPressed())); + + m_pause_action = addAction(tr("Pause"), this, SIGNAL(PausePressed())); + m_pause_action->setEnabled(false); + + m_stop_action = addAction(tr("Stop"), this, SIGNAL(StopPressed())); + m_stop_action->setEnabled(false); + + m_fullscreen_action = addAction(tr("Full Screen"), this, SIGNAL(FullScreenPressed())); + m_fullscreen_action->setEnabled(false); + + m_screenshot_action = addAction(tr("Screen Shot"), this, SIGNAL(ScreenShotPressed())); + m_screenshot_action->setEnabled(false); + + addSeparator(); + + m_config_action = addAction(tr("Settings")); + m_config_action->setEnabled(false); + + m_graphics_action = addAction(tr("Graphics")); + m_graphics_action->setEnabled(false); + + m_controllers_action = addAction(tr("Controllers")); + m_controllers_action->setEnabled(false); +} + +void ToolBar::UpdateIcons() +{ + QString dir = QString::fromStdString(File::GetThemeDir(SConfig::GetInstance().theme_name)); + + m_open_action->setIcon(QIcon(QStringLiteral("open.png").prepend(dir))); + m_paths_action->setIcon(QIcon(QStringLiteral("browse.png").prepend(dir))); + m_play_action->setIcon(QIcon(QStringLiteral("play.png").prepend(dir))); + m_pause_action->setIcon(QIcon(QStringLiteral("pause.png").prepend(dir))); + m_stop_action->setIcon(QIcon(QStringLiteral("stop.png").prepend(dir))); + m_fullscreen_action->setIcon(QIcon(QStringLiteral("fullscreen.png").prepend(dir))); + m_screenshot_action->setIcon(QIcon(QStringLiteral("screenshot.png").prepend(dir))); + m_config_action->setIcon(QIcon(QStringLiteral("config.png").prepend(dir))); + m_graphics_action->setIcon(QIcon(QStringLiteral("graphics.png").prepend(dir))); + m_controllers_action->setIcon(QIcon(QStringLiteral("classic.png").prepend(dir))); +} + diff --git a/Source/Core/DolphinQt2/ToolBar.h b/Source/Core/DolphinQt2/ToolBar.h new file mode 100644 index 0000000000..ea88f0b796 --- /dev/null +++ b/Source/Core/DolphinQt2/ToolBar.h @@ -0,0 +1,47 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include + +class ToolBar final : public QToolBar +{ + Q_OBJECT + +public: + ToolBar(QWidget* parent = nullptr); + +public slots: + void EmulationStarted(); + void EmulationPaused(); + void EmulationStopped(); + +signals: + void OpenPressed(); + void PathsPressed(); + + void PlayPressed(); + void PausePressed(); + void StopPressed(); + void FullScreenPressed(); + void ScreenShotPressed(); + +private: + void MakeActions(); + void UpdateIcons(); + + QAction* m_open_action; + QAction* m_paths_action; + QAction* m_play_action; + QAction* m_pause_action; + QAction* m_stop_action; + QAction* m_fullscreen_action; + QAction* m_screenshot_action; + QAction* m_config_action; + QAction* m_graphics_action; + QAction* m_controllers_action; +};