mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-18 11:55:38 +00:00
Qt: Implement "File Title" column and toggling in game list
This commit is contained in:
parent
c8954a3089
commit
5c0660744a
|
@ -6,6 +6,7 @@
|
||||||
#include <QtCore/QSortFilterProxyModel>
|
#include <QtCore/QSortFilterProxyModel>
|
||||||
#include <QtGui/QPixmap>
|
#include <QtGui/QPixmap>
|
||||||
#include <QtWidgets/QHeaderView>
|
#include <QtWidgets/QHeaderView>
|
||||||
|
#include <QtWidgets/QMenu>
|
||||||
|
|
||||||
class GameListModel final : public QAbstractTableModel
|
class GameListModel final : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
|
@ -15,12 +16,16 @@ public:
|
||||||
Column_Type,
|
Column_Type,
|
||||||
Column_Code,
|
Column_Code,
|
||||||
Column_Title,
|
Column_Title,
|
||||||
|
Column_FileTitle,
|
||||||
Column_Region,
|
Column_Region,
|
||||||
Column_Size,
|
Column_Size,
|
||||||
|
|
||||||
Column_Count
|
Column_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline constexpr std::array<const char*, static_cast<int>(GameListModel::Column_Count)> s_column_names = {
|
||||||
|
{"Type", "Code", "Title", "File Title", "Region", "Size"}};
|
||||||
|
|
||||||
GameListModel(GameList* game_list, QObject* parent = nullptr)
|
GameListModel(GameList* game_list, QObject* parent = nullptr)
|
||||||
: QAbstractTableModel(parent), m_game_list(game_list), m_size(static_cast<int>(m_game_list->GetEntryCount()))
|
: QAbstractTableModel(parent), m_game_list(game_list), m_size(static_cast<int>(m_game_list->GetEntryCount()))
|
||||||
{
|
{
|
||||||
|
@ -67,6 +72,12 @@ public:
|
||||||
case Column_Title:
|
case Column_Title:
|
||||||
return QString::fromStdString(ge.title);
|
return QString::fromStdString(ge.title);
|
||||||
|
|
||||||
|
case Column_FileTitle:
|
||||||
|
{
|
||||||
|
const std::string_view file_title(GameList::GetTitleForPath(ge.path.c_str()));
|
||||||
|
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
|
||||||
|
}
|
||||||
|
|
||||||
case Column_Size:
|
case Column_Size:
|
||||||
return QString("%1 MB").arg(static_cast<double>(ge.total_size) / 1048576.0, 0, 'f', 2);
|
return QString("%1 MB").arg(static_cast<double>(ge.total_size) / 1048576.0, 0, 'f', 2);
|
||||||
|
|
||||||
|
@ -88,6 +99,12 @@ public:
|
||||||
case Column_Title:
|
case Column_Title:
|
||||||
return QString::fromStdString(ge.title);
|
return QString::fromStdString(ge.title);
|
||||||
|
|
||||||
|
case Column_FileTitle:
|
||||||
|
{
|
||||||
|
const std::string_view file_title(GameList::GetTitleForPath(ge.path.c_str()));
|
||||||
|
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
|
||||||
|
}
|
||||||
|
|
||||||
case Column_Region:
|
case Column_Region:
|
||||||
return static_cast<int>(ge.region);
|
return static_cast<int>(ge.region);
|
||||||
|
|
||||||
|
@ -141,29 +158,10 @@ public:
|
||||||
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
|
||||||
{
|
{
|
||||||
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
|
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0 || section >= Column_Count)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
switch (section)
|
return tr(s_column_names[section]);
|
||||||
{
|
|
||||||
case Column_Type:
|
|
||||||
return "Type";
|
|
||||||
|
|
||||||
case Column_Code:
|
|
||||||
return "Code";
|
|
||||||
|
|
||||||
case Column_Title:
|
|
||||||
return "Title";
|
|
||||||
|
|
||||||
case Column_Region:
|
|
||||||
return "Region";
|
|
||||||
|
|
||||||
case Column_Size:
|
|
||||||
return "Size";
|
|
||||||
|
|
||||||
default:
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh()
|
void refresh()
|
||||||
|
@ -266,18 +264,24 @@ void GameListWidget::initialize(QtHostInterface* host_interface)
|
||||||
m_table_view->setShowGrid(false);
|
m_table_view->setShowGrid(false);
|
||||||
m_table_view->setCurrentIndex({});
|
m_table_view->setCurrentIndex({});
|
||||||
m_table_view->horizontalHeader()->setHighlightSections(false);
|
m_table_view->horizontalHeader()->setHighlightSections(false);
|
||||||
|
m_table_view->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
m_table_view->verticalHeader()->hide();
|
m_table_view->verticalHeader()->hide();
|
||||||
m_table_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
m_table_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
m_table_view->resizeColumnsToContents();
|
m_table_view->resizeColumnsToContents();
|
||||||
|
|
||||||
|
// hide the implicit title by default
|
||||||
|
m_table_view->setColumnHidden(GameListModel::Column_FileTitle, true);
|
||||||
|
|
||||||
// sort by disc type, then title
|
// sort by disc type, then title
|
||||||
m_table_sort_model->sort(0, Qt::AscendingOrder);
|
m_table_sort_model->sort(GameListModel::Column_Type, Qt::AscendingOrder);
|
||||||
|
|
||||||
connect(m_table_view->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
connect(m_table_view->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||||
&GameListWidget::onSelectionModelCurrentChanged);
|
&GameListWidget::onSelectionModelCurrentChanged);
|
||||||
connect(m_table_view, &QTableView::doubleClicked, this, &GameListWidget::onTableViewItemDoubleClicked);
|
connect(m_table_view, &QTableView::doubleClicked, this, &GameListWidget::onTableViewItemDoubleClicked);
|
||||||
connect(m_table_view, &QTableView::customContextMenuRequested, this,
|
connect(m_table_view, &QTableView::customContextMenuRequested, this,
|
||||||
&GameListWidget::onTableViewContextMenuRequested);
|
&GameListWidget::onTableViewContextMenuRequested);
|
||||||
|
connect(m_table_view->horizontalHeader(), &QHeaderView::customContextMenuRequested, this,
|
||||||
|
&GameListWidget::onTableViewHeaderContextMenuRequested);
|
||||||
|
|
||||||
insertWidget(0, m_table_view);
|
insertWidget(0, m_table_view);
|
||||||
setCurrentIndex(0);
|
setCurrentIndex(0);
|
||||||
|
@ -320,11 +324,33 @@ void GameListWidget::onTableViewContextMenuRequested(const QPoint& point)
|
||||||
emit entryContextMenuRequested(m_table_view->mapToGlobal(point), entry);
|
emit entryContextMenuRequested(m_table_view->mapToGlobal(point), entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameListWidget::onTableViewHeaderContextMenuRequested(const QPoint& point)
|
||||||
|
{
|
||||||
|
QMenu menu;
|
||||||
|
|
||||||
|
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||||
|
{
|
||||||
|
QAction* action = menu.addAction(tr(GameListModel::s_column_names[column]));
|
||||||
|
action->setCheckable(true);
|
||||||
|
action->setChecked(!m_table_view->isColumnHidden(column));
|
||||||
|
connect(action, &QAction::toggled, [this, column](bool enabled) {
|
||||||
|
m_table_view->setColumnHidden(column, !enabled);
|
||||||
|
resizeTableViewColumnsToFit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.exec(m_table_view->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
|
||||||
void GameListWidget::resizeEvent(QResizeEvent* event)
|
void GameListWidget::resizeEvent(QResizeEvent* event)
|
||||||
{
|
{
|
||||||
QStackedWidget::resizeEvent(event);
|
QStackedWidget::resizeEvent(event);
|
||||||
|
resizeTableViewColumnsToFit();
|
||||||
|
}
|
||||||
|
|
||||||
QtUtils::ResizeColumnsForTableView(m_table_view, {32, 80, -1, 60, 100});
|
void GameListWidget::resizeTableViewColumnsToFit()
|
||||||
|
{
|
||||||
|
QtUtils::ResizeColumnsForTableView(m_table_view, {32, 80, -1, -1, 60, 100});
|
||||||
}
|
}
|
||||||
|
|
||||||
const GameListEntry* GameListWidget::getSelectedEntry() const
|
const GameListEntry* GameListWidget::getSelectedEntry() const
|
||||||
|
|
|
@ -30,12 +30,14 @@ private Q_SLOTS:
|
||||||
void onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
|
void onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
void onTableViewItemDoubleClicked(const QModelIndex& index);
|
void onTableViewItemDoubleClicked(const QModelIndex& index);
|
||||||
void onTableViewContextMenuRequested(const QPoint& point);
|
void onTableViewContextMenuRequested(const QPoint& point);
|
||||||
|
void onTableViewHeaderContextMenuRequested(const QPoint& point);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent* event);
|
void resizeEvent(QResizeEvent* event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GameListEntry* getSelectedEntry() const;
|
const GameListEntry* getSelectedEntry() const;
|
||||||
|
void resizeTableViewColumnsToFit();
|
||||||
|
|
||||||
QtHostInterface* m_host_interface = nullptr;
|
QtHostInterface* m_host_interface = nullptr;
|
||||||
GameList* m_game_list = nullptr;
|
GameList* m_game_list = nullptr;
|
||||||
|
|
|
@ -46,6 +46,12 @@ void ResizeColumnsForTableView(QTableView* view, const std::initializer_list<int
|
||||||
int column_index = 0;
|
int column_index = 0;
|
||||||
for (const int spec_width : widths)
|
for (const int spec_width : widths)
|
||||||
{
|
{
|
||||||
|
if (view->isColumnHidden(column_index))
|
||||||
|
{
|
||||||
|
column_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const int width = spec_width < 0 ? flex_width : spec_width;
|
const int width = spec_width < 0 ? flex_width : spec_width;
|
||||||
view->setColumnWidth(column_index, width);
|
view->setColumnWidth(column_index, width);
|
||||||
column_index++;
|
column_index++;
|
||||||
|
|
Loading…
Reference in a new issue