Replace TableProxyModel with TableDelegate.
This commit is contained in:
parent
cafc879b7c
commit
dfb0db9d31
|
@ -18,7 +18,7 @@ set(SRCS
|
||||||
GameList/GameListModel.cpp
|
GameList/GameListModel.cpp
|
||||||
GameList/GameTracker.cpp
|
GameList/GameTracker.cpp
|
||||||
GameList/ListProxyModel.cpp
|
GameList/ListProxyModel.cpp
|
||||||
GameList/TableProxyModel.cpp
|
GameList/TableDelegate.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND LIBS core uicommon)
|
list(APPEND LIBS core uicommon)
|
||||||
|
|
|
@ -7,16 +7,18 @@
|
||||||
#include "DolphinQt2/Settings.h"
|
#include "DolphinQt2/Settings.h"
|
||||||
#include "DolphinQt2/GameList/GameList.h"
|
#include "DolphinQt2/GameList/GameList.h"
|
||||||
#include "DolphinQt2/GameList/ListProxyModel.h"
|
#include "DolphinQt2/GameList/ListProxyModel.h"
|
||||||
#include "DolphinQt2/GameList/TableProxyModel.h"
|
#include "DolphinQt2/GameList/TableDelegate.h"
|
||||||
|
|
||||||
GameList::GameList(QWidget* parent): QStackedWidget(parent)
|
GameList::GameList(QWidget* parent): QStackedWidget(parent)
|
||||||
{
|
{
|
||||||
m_model = new GameListModel(this);
|
m_model = new GameListModel(this);
|
||||||
m_table_proxy = new TableProxyModel(this);
|
m_table_proxy = new QSortFilterProxyModel(this);
|
||||||
m_table_proxy->setSourceModel(m_model);
|
m_table_proxy->setSourceModel(m_model);
|
||||||
m_list_proxy = new ListProxyModel(this);
|
m_list_proxy = new ListProxyModel(this);
|
||||||
m_list_proxy->setSourceModel(m_model);
|
m_list_proxy->setSourceModel(m_model);
|
||||||
|
|
||||||
|
m_delegate = new TableDelegate(this);
|
||||||
|
|
||||||
MakeTableView();
|
MakeTableView();
|
||||||
MakeListView();
|
MakeListView();
|
||||||
MakeEmptyView();
|
MakeEmptyView();
|
||||||
|
@ -39,6 +41,7 @@ void GameList::MakeTableView()
|
||||||
{
|
{
|
||||||
m_table = new QTableView(this);
|
m_table = new QTableView(this);
|
||||||
m_table->setModel(m_table_proxy);
|
m_table->setModel(m_table_proxy);
|
||||||
|
m_table->setItemDelegate(m_delegate);
|
||||||
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
m_table->setAlternatingRowColors(true);
|
m_table->setAlternatingRowColors(true);
|
||||||
|
@ -58,15 +61,15 @@ void GameList::MakeTableView()
|
||||||
m_table->setColumnHidden(GameListModel::COL_RATING, false);
|
m_table->setColumnHidden(GameListModel::COL_RATING, false);
|
||||||
|
|
||||||
QHeaderView* hor_header = m_table->horizontalHeader();
|
QHeaderView* hor_header = m_table->horizontalHeader();
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_PLATFORM, QHeaderView::Fixed);
|
hor_header->setSectionResizeMode(GameListModel::COL_PLATFORM, QHeaderView::ResizeToContents);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::Fixed);
|
hor_header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::ResizeToContents);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_ID, QHeaderView::ResizeToContents);
|
hor_header->setSectionResizeMode(GameListModel::COL_ID, QHeaderView::ResizeToContents);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_BANNER, QHeaderView::ResizeToContents);
|
hor_header->setSectionResizeMode(GameListModel::COL_BANNER, QHeaderView::ResizeToContents);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_TITLE, QHeaderView::Stretch);
|
hor_header->setSectionResizeMode(GameListModel::COL_TITLE, QHeaderView::Stretch);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_MAKER, QHeaderView::Stretch);
|
hor_header->setSectionResizeMode(GameListModel::COL_MAKER, QHeaderView::Stretch);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_SIZE, QHeaderView::ResizeToContents);
|
hor_header->setSectionResizeMode(GameListModel::COL_SIZE, QHeaderView::ResizeToContents);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_DESCRIPTION, QHeaderView::Stretch);
|
hor_header->setSectionResizeMode(GameListModel::COL_DESCRIPTION, QHeaderView::Stretch);
|
||||||
hor_header->setSectionResizeMode(GameListModel::COL_RATING, QHeaderView::Fixed);
|
hor_header->setSectionResizeMode(GameListModel::COL_RATING, QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
QHeaderView* ver_header = m_table->verticalHeader();
|
QHeaderView* ver_header = m_table->verticalHeader();
|
||||||
ver_header->setSectionResizeMode(QHeaderView::ResizeToContents);
|
ver_header->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "DolphinQt2/GameList/GameFile.h"
|
#include "DolphinQt2/GameList/GameFile.h"
|
||||||
#include "DolphinQt2/GameList/GameListModel.h"
|
#include "DolphinQt2/GameList/GameListModel.h"
|
||||||
|
|
||||||
|
class TableDelegate;
|
||||||
|
|
||||||
class GameList final : public QStackedWidget
|
class GameList final : public QStackedWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -41,6 +43,7 @@ private:
|
||||||
void ConsiderViewChange();
|
void ConsiderViewChange();
|
||||||
|
|
||||||
GameListModel* m_model;
|
GameListModel* m_model;
|
||||||
|
TableDelegate* m_delegate;
|
||||||
QSortFilterProxyModel* m_table_proxy;
|
QSortFilterProxyModel* m_table_proxy;
|
||||||
QSortFilterProxyModel* m_list_proxy;
|
QSortFilterProxyModel* m_list_proxy;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Copyright 2016 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "DolphinQt2/Resources.h"
|
||||||
|
#include "DolphinQt2/GameList/GameListModel.h"
|
||||||
|
#include "DolphinQt2/GameList/TableDelegate.h"
|
||||||
|
|
||||||
|
static QSize NORMAL_BANNER_SIZE(96, 32);
|
||||||
|
|
||||||
|
// Convert an integer size to a friendly string representation.
|
||||||
|
static QString FormatSize(qint64 size)
|
||||||
|
{
|
||||||
|
QStringList units{
|
||||||
|
QStringLiteral("KB"),
|
||||||
|
QStringLiteral("MB"),
|
||||||
|
QStringLiteral("GB"),
|
||||||
|
QStringLiteral("TB")
|
||||||
|
};
|
||||||
|
QStringListIterator i(units);
|
||||||
|
QString unit = QStringLiteral("B");
|
||||||
|
double num = (double) size;
|
||||||
|
while (num > 1024.0 && i.hasNext())
|
||||||
|
{
|
||||||
|
unit = i.next();
|
||||||
|
num /= 1024.0;
|
||||||
|
}
|
||||||
|
return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
TableDelegate::TableDelegate(QWidget* parent) : QStyledItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TableDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QVariant data = index.data(Qt::DisplayRole);
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case GameListModel::COL_PLATFORM:
|
||||||
|
DrawPixmap(painter, option.rect, Resources::GetPlatform(data.toInt()));
|
||||||
|
break;
|
||||||
|
case GameListModel::COL_COUNTRY:
|
||||||
|
DrawPixmap(painter, option.rect, Resources::GetCountry(data.toInt()));
|
||||||
|
break;
|
||||||
|
case GameListModel::COL_RATING:
|
||||||
|
DrawPixmap(painter, option.rect, Resources::GetRating(data.toInt()));
|
||||||
|
break;
|
||||||
|
case GameListModel::COL_BANNER:
|
||||||
|
DrawPixmap(painter, option.rect, data.value<QPixmap>().scaled(
|
||||||
|
NORMAL_BANNER_SIZE,
|
||||||
|
Qt::KeepAspectRatio,
|
||||||
|
Qt::SmoothTransformation));
|
||||||
|
break;
|
||||||
|
case GameListModel::COL_SIZE:
|
||||||
|
painter->drawText(option.rect, Qt::AlignCenter, FormatSize(data.toULongLong()));
|
||||||
|
break;
|
||||||
|
// Fall through.
|
||||||
|
case GameListModel::COL_ID:
|
||||||
|
case GameListModel::COL_TITLE:
|
||||||
|
case GameListModel::COL_DESCRIPTION:
|
||||||
|
case GameListModel::COL_MAKER:
|
||||||
|
painter->drawText(option.rect, Qt::AlignVCenter, data.toString());
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize TableDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case GameListModel::COL_PLATFORM:
|
||||||
|
return Resources::GetPlatform(0).size();
|
||||||
|
case GameListModel::COL_COUNTRY:
|
||||||
|
return Resources::GetCountry(0).size();
|
||||||
|
case GameListModel::COL_RATING:
|
||||||
|
return Resources::GetRating(0).size();
|
||||||
|
case GameListModel::COL_BANNER:
|
||||||
|
return NORMAL_BANNER_SIZE;
|
||||||
|
default: return QSize(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TableDelegate::DrawPixmap(QPainter* painter, const QRect& rect, const QPixmap& pixmap) const
|
||||||
|
{
|
||||||
|
// We don't want to stretch the pixmap out, so center it in the rect.
|
||||||
|
painter->drawPixmap(
|
||||||
|
rect.left() + (rect.width() - pixmap.width()) / 2,
|
||||||
|
rect.top() + (rect.height() - pixmap.height()) / 2,
|
||||||
|
pixmap);
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2016 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
class TableDelegate final : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TableDelegate(QWidget* parent = nullptr);
|
||||||
|
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawPixmap(QPainter* painter, const QRect& rect, const QPixmap& pixmap) const;
|
||||||
|
};
|
|
@ -1,77 +0,0 @@
|
||||||
// Copyright 2015 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "DolphinQt2/Resources.h"
|
|
||||||
#include "DolphinQt2/GameList/GameListModel.h"
|
|
||||||
#include "DolphinQt2/GameList/TableProxyModel.h"
|
|
||||||
|
|
||||||
static constexpr QSize NORMAL_BANNER_SIZE(96, 32);
|
|
||||||
|
|
||||||
// Convert an integer size to a friendly string representation.
|
|
||||||
static QString FormatSize(qint64 size)
|
|
||||||
{
|
|
||||||
QStringList units{
|
|
||||||
QStringLiteral("KB"),
|
|
||||||
QStringLiteral("MB"),
|
|
||||||
QStringLiteral("GB"),
|
|
||||||
QStringLiteral("TB")
|
|
||||||
};
|
|
||||||
QStringListIterator i(units);
|
|
||||||
QString unit = QStringLiteral("B");
|
|
||||||
double num = (double) size;
|
|
||||||
while (num > 1024.0 && i.hasNext())
|
|
||||||
{
|
|
||||||
unit = i.next();
|
|
||||||
num /= 1024.0;
|
|
||||||
}
|
|
||||||
return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
TableProxyModel::TableProxyModel(QObject* parent)
|
|
||||||
: QSortFilterProxyModel(parent)
|
|
||||||
{
|
|
||||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant TableProxyModel::data(const QModelIndex& i, int role) const
|
|
||||||
{
|
|
||||||
QModelIndex source_index = mapToSource(i);
|
|
||||||
QVariant source_data = sourceModel()->data(source_index, Qt::DisplayRole);
|
|
||||||
if (role == Qt::DisplayRole)
|
|
||||||
{
|
|
||||||
switch (i.column())
|
|
||||||
{
|
|
||||||
// Sort by the integer but display the formatted string.
|
|
||||||
case GameListModel::COL_SIZE:
|
|
||||||
return FormatSize(source_data.toULongLong());
|
|
||||||
// These fall through to the underlying model.
|
|
||||||
case GameListModel::COL_ID:
|
|
||||||
case GameListModel::COL_TITLE:
|
|
||||||
case GameListModel::COL_DESCRIPTION:
|
|
||||||
case GameListModel::COL_MAKER:
|
|
||||||
return source_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (role == Qt::DecorationRole)
|
|
||||||
{
|
|
||||||
switch (i.column())
|
|
||||||
{
|
|
||||||
// Show icons in the decoration roles. This lets us sort by the
|
|
||||||
// underlying ints, but display just the icons without doing any
|
|
||||||
// fixed-width hacks.
|
|
||||||
case GameListModel::COL_PLATFORM:
|
|
||||||
return Resources::GetPlatform(source_data.toInt());
|
|
||||||
case GameListModel::COL_BANNER:
|
|
||||||
return source_data.value<QPixmap>().scaled(
|
|
||||||
NORMAL_BANNER_SIZE,
|
|
||||||
Qt::KeepAspectRatio,
|
|
||||||
Qt::SmoothTransformation);
|
|
||||||
case GameListModel::COL_COUNTRY:
|
|
||||||
return Resources::GetCountry(source_data.toInt());
|
|
||||||
case GameListModel::COL_RATING:
|
|
||||||
return Resources::GetRating(source_data.toInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright 2015 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
// This subclass of QSortFilterProxyModel transforms the raw GameFile data
|
|
||||||
// into presentable icons, and allows for sorting and filtering.
|
|
||||||
// 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 TableProxyModel final : public QSortFilterProxyModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit TableProxyModel(QObject* parent = nullptr);
|
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
|
||||||
};
|
|
Loading…
Reference in New Issue