feat: prototype grid view
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
parent
8a4ad82d8d
commit
2e34464948
@ -866,8 +866,10 @@ SET(LAUNCHER_SOURCES
|
||||
ui/widgets/WideBar.cpp
|
||||
|
||||
# GUI - instance group view
|
||||
ui/instanceview/InstanceProxyModel.cpp
|
||||
ui/instanceview/InstanceProxyModel.h
|
||||
ui/instanceview/InstanceTableProxyModel.cpp
|
||||
ui/instanceview/InstanceTableProxyModel.h
|
||||
ui/instanceview/InstanceGridProxyModel.cpp
|
||||
ui/instanceview/InstanceGridProxyModel.h
|
||||
ui/instanceview/InstanceDelegate.h
|
||||
ui/instanceview/InstanceDelegate.cpp
|
||||
ui/instanceview/InstanceView.h
|
||||
|
@ -53,7 +53,6 @@
|
||||
class LaunchController;
|
||||
class NewsChecker;
|
||||
class QToolButton;
|
||||
class InstanceProxyModel;
|
||||
class LabeledToolButton;
|
||||
class QLabel;
|
||||
class InstanceView;
|
||||
|
@ -19,15 +19,12 @@
|
||||
#include "InstanceDelegate.h"
|
||||
#include "InstanceList.h"
|
||||
|
||||
InstanceDelegate::InstanceDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
|
||||
InstanceDelegate::InstanceDelegate(QObject* parent, int iconSize) : QStyledItemDelegate(parent), m_iconSize(iconSize) {}
|
||||
|
||||
void InstanceDelegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const
|
||||
{
|
||||
QStyledItemDelegate::initStyleOption(option, index);
|
||||
if (index.column() == InstanceList::NameColumn) {
|
||||
// make decoration fill cell, subtract default margins
|
||||
QSize decorationSize = QSize(option->rect.height(), option->rect.height());
|
||||
decorationSize -= QSize(2, 2); // subtract 1px margin
|
||||
option->decorationSize = decorationSize;
|
||||
option->decorationSize = QSize(m_iconSize, m_iconSize);;
|
||||
}
|
||||
}
|
@ -24,7 +24,10 @@ class InstanceDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstanceDelegate(QObject* parent = 0);
|
||||
InstanceDelegate(QObject* parent = 0, int iconSize = 48);
|
||||
|
||||
void initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const override;
|
||||
|
||||
private:
|
||||
int m_iconSize;
|
||||
};
|
||||
|
26
launcher/ui/instanceview/InstanceGridProxyModel.cpp
Normal file
26
launcher/ui/instanceview/InstanceGridProxyModel.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "InstanceGridProxyModel.h"
|
||||
|
||||
#include <icons/IconList.h>
|
||||
#include "Application.h"
|
||||
#include "InstanceList.h"
|
||||
|
||||
// Placeholder model, as we might need this in the future
|
||||
InstanceGridProxyModel::InstanceGridProxyModel(QObject* parent) : InstanceTableProxyModel(parent) {}
|
28
launcher/ui/instanceview/InstanceGridProxyModel.h
Normal file
28
launcher/ui/instanceview/InstanceGridProxyModel.h
Normal file
@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "InstanceTableProxyModel.h"
|
||||
|
||||
class InstanceGridProxyModel : public InstanceTableProxyModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstanceGridProxyModel(QObject* parent = 0);
|
||||
};
|
@ -13,22 +13,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "InstanceProxyModel.h"
|
||||
#include "InstanceTableProxyModel.h"
|
||||
|
||||
#include <icons/IconList.h>
|
||||
#include "Application.h"
|
||||
#include "InstanceList.h"
|
||||
|
||||
InstanceProxyModel::InstanceProxyModel(QObject* parent) : QSortFilterProxyModel(parent)
|
||||
InstanceTableProxyModel::InstanceTableProxyModel(QObject* parent) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
m_naturalSort.setNumericMode(true);
|
||||
m_naturalSort.setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
|
||||
// FIXME: use loaded translation as source of locale instead, hook this up to translation changes
|
||||
m_naturalSort.setLocale(QLocale::system());
|
||||
setSortRole(InstanceList::SortRole);
|
||||
}
|
||||
|
||||
QVariant InstanceProxyModel::data(const QModelIndex& index, int role) const
|
||||
QVariant InstanceTableProxyModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant data = QSortFilterProxyModel::data(index, role);
|
||||
if (role == Qt::DecorationRole) {
|
@ -18,11 +18,11 @@
|
||||
#include <QCollator>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class InstanceProxyModel : public QSortFilterProxyModel {
|
||||
class InstanceTableProxyModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InstanceProxyModel(QObject* parent = 0);
|
||||
InstanceTableProxyModel(QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
@ -27,7 +27,8 @@
|
||||
|
||||
#include "InstanceDelegate.h"
|
||||
#include "InstanceList.h"
|
||||
#include "ui/instanceview/InstanceProxyModel.h"
|
||||
#include "ui/instanceview/InstanceTableProxyModel.h"
|
||||
#include "ui/instanceview/InstanceGridProxyModel.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QSize>
|
||||
@ -36,9 +37,11 @@ InstanceView::InstanceView(QWidget* parent, InstanceList* instances) : QStackedW
|
||||
{
|
||||
prepareModel();
|
||||
createTable();
|
||||
createGrid();
|
||||
|
||||
addWidget(m_table);
|
||||
setCurrentWidget(m_table);
|
||||
addWidget(m_grid);
|
||||
switchDisplayMode(InstanceView::GridMode);
|
||||
}
|
||||
|
||||
void InstanceView::storeState()
|
||||
@ -46,18 +49,33 @@ void InstanceView::storeState()
|
||||
APPLICATION->settings()->set("InstanceViewTableHeaderState", m_table->horizontalHeader()->saveState().toBase64());
|
||||
}
|
||||
|
||||
void InstanceView::switchDisplayMode(InstanceView::DisplayMode mode)
|
||||
{
|
||||
m_displayMode = mode;
|
||||
if (mode == DisplayMode::TableMode) {
|
||||
setCurrentWidget(m_table);
|
||||
} else {
|
||||
setCurrentWidget(m_grid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstanceView::prepareModel()
|
||||
{
|
||||
m_proxy = new InstanceProxyModel(this);
|
||||
m_proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_proxy->setSourceModel(m_instances);
|
||||
connect(m_proxy, &QAbstractItemModel::dataChanged, this, &InstanceView::dataChanged);
|
||||
m_tableProxy = new InstanceTableProxyModel(this);
|
||||
m_tableProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_tableProxy->setSourceModel(m_instances);
|
||||
m_tableProxy->setSortRole(InstanceList::SortRole);
|
||||
connect(m_tableProxy, &QAbstractItemModel::dataChanged, this, &InstanceView::dataChanged);
|
||||
m_gridProxy = new InstanceGridProxyModel(this);
|
||||
m_gridProxy->setSourceModel(m_instances);
|
||||
connect(m_tableProxy, &QAbstractItemModel::dataChanged, this, &InstanceView::dataChanged);
|
||||
}
|
||||
|
||||
void InstanceView::createTable()
|
||||
{
|
||||
m_table = new QTableView(this);
|
||||
m_table->setModel(m_proxy);
|
||||
m_table->setModel(m_tableProxy);
|
||||
m_table->setItemDelegate(new InstanceDelegate(this));
|
||||
|
||||
m_table->setTabKeyNavigation(false);
|
||||
@ -83,7 +101,7 @@ void InstanceView::createTable()
|
||||
header->setSectionResizeMode(InstanceList::GameVersionColumn, QHeaderView::Interactive);
|
||||
header->setSectionResizeMode(InstanceList::PlayTimeColumn, QHeaderView::Interactive);
|
||||
header->setSectionResizeMode(InstanceList::LastPlayedColumn, QHeaderView::Interactive);
|
||||
m_table->verticalHeader()->setDefaultSectionSize(m_rowHeight + 1 + 1); // padding top and bottom
|
||||
m_table->verticalHeader()->setDefaultSectionSize(m_iconSize + 1 + 1); // padding top and bottom
|
||||
|
||||
if (APPLICATION->settings()->get("InstanceViewTableHeaderState").toString().isEmpty()) {
|
||||
m_table->setColumnWidth(InstanceList::GameVersionColumn, 96 + 3 + 3);
|
||||
@ -100,9 +118,34 @@ void InstanceView::createTable()
|
||||
connect(m_table, &QWidget::customContextMenuRequested, this, &InstanceView::contextMenuRequested);
|
||||
}
|
||||
|
||||
void InstanceView::createGrid()
|
||||
{
|
||||
m_grid = new QListView(this);
|
||||
m_grid->setModel(m_gridProxy);
|
||||
m_grid->setModelColumn(InstanceList::NameColumn);
|
||||
m_grid->setItemDelegate(new InstanceDelegate(this));
|
||||
|
||||
m_grid->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_grid->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_grid->setEditTriggers(QAbstractItemView::EditKeyPressed);
|
||||
m_grid->setCurrentIndex(QModelIndex());
|
||||
m_grid->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_grid->setWordWrap(true);
|
||||
m_grid->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_grid->setViewMode(QListView::IconMode);
|
||||
m_grid->setMovement(QListView::Static);
|
||||
m_grid->setResizeMode(QListView::Adjust);
|
||||
m_grid->setFrameStyle(QFrame::NoFrame);
|
||||
m_grid->setGridSize(QSize(m_iconSize * 2, m_iconSize * 2));
|
||||
|
||||
connect(m_grid, &QAbstractItemView::doubleClicked, this, &InstanceView::activateInstance);
|
||||
connect(m_grid->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &InstanceView::currentRowChanged);
|
||||
connect(m_grid, &QWidget::customContextMenuRequested, this, &InstanceView::contextMenuRequested);
|
||||
}
|
||||
|
||||
InstancePtr InstanceView::currentInstance()
|
||||
{
|
||||
auto current = m_table->selectionModel()->currentIndex();
|
||||
auto current = currentView()->selectionModel()->currentIndex();
|
||||
if (current.isValid()) {
|
||||
int row = mappedIndex(current).row();
|
||||
return m_instances->at(row);
|
||||
@ -135,13 +178,13 @@ void InstanceView::currentRowChanged(const QModelIndex& current, const QModelInd
|
||||
void InstanceView::selectNameColumn(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
// Make sure Name column is always selected
|
||||
m_table->setCurrentIndex(current.siblingAtColumn(InstanceList::NameColumn));
|
||||
currentView()->setCurrentIndex(current.siblingAtColumn(InstanceList::NameColumn));
|
||||
}
|
||||
|
||||
void InstanceView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||
{
|
||||
// Notify others if data of the current instance changed
|
||||
auto current = m_table->selectionModel()->currentIndex();
|
||||
auto current = currentView()->selectionModel()->currentIndex();
|
||||
|
||||
QItemSelection foo(topLeft, bottomRight);
|
||||
if (foo.contains(current)) {
|
||||
@ -153,18 +196,21 @@ void InstanceView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bo
|
||||
|
||||
void InstanceView::contextMenuRequested(const QPoint pos)
|
||||
{
|
||||
QModelIndex index = m_table->indexAt(pos);
|
||||
QModelIndex index = currentView()->indexAt(pos);
|
||||
|
||||
if (index.isValid()) {
|
||||
int row = mappedIndex(index).row();
|
||||
InstancePtr inst = m_instances->at(row);
|
||||
emit showContextMenu(m_table->mapToParent(pos), inst);
|
||||
emit showContextMenu(currentView()->mapToParent(pos), inst);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex InstanceView::mappedIndex(const QModelIndex& index) const
|
||||
{
|
||||
return m_proxy->mapToSource(index);
|
||||
if (m_displayMode == DisplayMode::GridMode) {
|
||||
return m_gridProxy->mapToSource(index);
|
||||
}
|
||||
return m_tableProxy->mapToSource(index);
|
||||
}
|
||||
|
||||
void InstanceView::setCatDisplayed(bool enabled)
|
||||
|
@ -18,21 +18,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QListView>
|
||||
#include <QStackedWidget>
|
||||
#include <QTableView>
|
||||
|
||||
#include "BaseInstance.h"
|
||||
|
||||
class InstanceProxyModel;
|
||||
class InstanceTableProxyModel;
|
||||
class InstanceGridProxyModel;
|
||||
class InstanceList;
|
||||
|
||||
class InstanceView : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
|
||||
enum DisplayMode { TableMode = 0, GridMode };
|
||||
|
||||
public:
|
||||
explicit InstanceView(QWidget* parent = nullptr, InstanceList* instances = nullptr);
|
||||
|
||||
QAbstractItemView* currentView() { return m_table; }
|
||||
void switchDisplayMode(DisplayMode mode);
|
||||
|
||||
QAbstractItemView* currentView()
|
||||
{
|
||||
if (m_displayMode == GridMode)
|
||||
return m_grid;
|
||||
return m_table;
|
||||
}
|
||||
|
||||
InstancePtr currentInstance();
|
||||
|
||||
@ -56,12 +67,16 @@ class InstanceView : public QStackedWidget {
|
||||
|
||||
private:
|
||||
void createTable();
|
||||
void createGrid();
|
||||
void prepareModel();
|
||||
QModelIndex mappedIndex(const QModelIndex& index) const;
|
||||
|
||||
int m_rowHeight = 48;
|
||||
int m_iconSize = 48;
|
||||
DisplayMode m_displayMode = TableMode;
|
||||
|
||||
QTableView* m_table;
|
||||
InstanceProxyModel* m_proxy;
|
||||
QListView* m_grid;
|
||||
InstanceTableProxyModel* m_tableProxy;
|
||||
InstanceGridProxyModel* m_gridProxy;
|
||||
InstanceList* m_instances;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user