Refactor proxy models and toolbar.

Remove the ugly LARGE_ICON column hack from the table proxy and use a
list proxy. Move the toolbar into its own file.
This commit is contained in:
spxtr 2015-12-03 20:41:17 -08:00
parent 8322040c47
commit a06b0d87a7
12 changed files with 252 additions and 104 deletions

View File

@ -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)

View File

@ -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();
}

View File

@ -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;
};

View File

@ -37,7 +37,6 @@ public:
COL_SIZE,
COL_COUNTRY,
COL_RATING,
COL_LARGE_ICON,
NUM_COLS
};

View File

@ -0,0 +1,38 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <QSize>
#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<QPixmap>().scaled(
LARGE_BANNER_SIZE,
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
return QVariant();
}

View File

@ -0,0 +1,14 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <QSortFilterProxyModel>
class ListProxyModel final : public QSortFilterProxyModel
{
Q_OBJECT
public:
ListProxyModel(QObject* parent = nullptr);
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
};

View File

@ -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<QPixmap>().scaled(
LARGE_BANNER_SIZE,
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
}
return QVariant();

View File

@ -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;
};

View File

@ -7,6 +7,7 @@
#include <QFile>
#include <QFileDialog>
#include <QIcon>
#include <QLineEdit>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
@ -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,

View File

@ -10,6 +10,7 @@
#include <QToolBar>
#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;

View File

@ -0,0 +1,98 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <QIcon>
#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)));
}

View File

@ -0,0 +1,47 @@
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <QAction>
#include <QLineEdit>
#include <QToolBar>
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;
};