initial qml stuff

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
Sefa Eyeoglu 2022-12-08 14:09:33 +01:00
parent 05d9c2d864
commit ac33b150fa
No known key found for this signature in database
GPG Key ID: C10411294912A422
16 changed files with 161 additions and 38 deletions

View File

@ -207,7 +207,7 @@ endif()
include(QtVersionlessBackport)
if(Launcher_QT_VERSION_MAJOR EQUAL 5)
set(QT_VERSION_MAJOR 5)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network Test Xml)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Concurrent Network QuickWidgets Test Xml)
if(NOT Launcher_FORCE_BUNDLED_LIBS)
find_package(QuaZip-Qt5 1.3 QUIET)
@ -221,7 +221,7 @@ if(Launcher_QT_VERSION_MAJOR EQUAL 5)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE -D_UNICODE")
elseif(Launcher_QT_VERSION_MAJOR EQUAL 6)
set(QT_VERSION_MAJOR 6)
find_package(Qt6 REQUIRED COMPONENTS Core CoreTools Widgets Concurrent Network Test Xml Core5Compat)
find_package(Qt6 REQUIRED COMPONENTS Core CoreTools Widgets Concurrent Network QuickWidgets Test Xml Core5Compat)
list(APPEND Launcher_QT_LIBS Qt6::Core5Compat)
if(NOT Launcher_FORCE_BUNDLED_LIBS)

View File

@ -611,6 +611,11 @@ SET(LAUNCHER_SOURCES
icons/MMCIcon.cpp
icons/IconList.h
icons/IconList.cpp
icons/IconImageProvider.h
icons/IconImageProvider.cpp
# GUI
ui/resources.qrc
# GUI - windows
ui/GuiUtil.h
@ -999,6 +1004,7 @@ target_link_libraries(Launcher_logic
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Concurrent
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::QuickWidgets
Qt${QT_VERSION_MAJOR}::Widgets
${Launcher_QT_LIBS}
)

View File

@ -137,6 +137,17 @@ int InstanceList::columnCount(const QModelIndex& parent) const
return ColumnCount;
}
QHash<int, QByteArray> InstanceList::roleNames() const
{
QHash<int, QByteArray> roles;
roles[SortRole] = "sort";
roles[IconRole] = "icon";
roles[NameRole] = "name";
roles[CategoryRole] = "category";
roles[InstanceIDRole] = "instanceId";
return roles;
}
QVariant InstanceList::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole) {
@ -251,11 +262,19 @@ QVariant InstanceList::data(const QModelIndex& index, int role) const
break;
}
case IconRole: {
return inst->iconKey();
}
case NameRole: {
return inst->name();
}
case InstanceIDRole: {
return inst->id();
}
case GroupRole: {
case CategoryRole: {
return instanceGroup;
}
}
@ -337,7 +356,7 @@ void InstanceList::setInstanceGroup(const InstancePtr inst, const GroupId& name)
if (changed) {
m_groupNameCache.insert(name);
auto idx = getInstIndex(inst.get());
emit dataChanged(index(idx, NameColumn), index(idx, NameColumn), { GroupRole });
emit dataChanged(index(idx, NameColumn), index(idx, NameColumn), { CategoryRole });
saveGroupList();
}
}
@ -377,7 +396,7 @@ void InstanceList::deleteGroup(const QString& name)
removed = true;
auto idx = getInstIndex(instance.get());
if (idx > 0) {
emit dataChanged(index(idx, NameColumn), index(idx, NameColumn), { GroupRole });
emit dataChanged(index(idx, NameColumn), index(idx, NameColumn), { CategoryRole });
}
}
}

View File

@ -67,7 +67,9 @@ class InstanceList : public QAbstractTableModel {
ColumnCount
};
enum AdditionalRoles { SortRole = Qt::UserRole + 1, GroupRole, InstanceIDRole };
enum AdditionalRoles { SortRole = Qt::UserRole + 1, IconRole, NameRole, CategoryRole, InstanceIDRole };
QHash<int, QByteArray> roleNames() const override;
InstancePtr at(int i) const { return m_instances.at(i); }

View File

@ -0,0 +1,14 @@
#include "IconImageProvider.h"
IconImageProvider::IconImageProvider(std::shared_ptr<IconList> iconList, int iconSize) : QQuickImageProvider(QQuickImageProvider::Pixmap), m_iconList(iconList), m_iconSize(iconSize)
{
}
QPixmap IconImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
if (size)
*size = QSize(m_iconSize, m_iconSize);
QIcon i = m_iconList->getIcon(id);
return i.pixmap(requestedSize.width() > 0 ? requestedSize.width() : m_iconSize, requestedSize.height() > 0 ? requestedSize.height() : m_iconSize);
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "IconList.h"
#include <QQuickImageProvider>
class IconImageProvider : public QQuickImageProvider
{
public:
IconImageProvider(std::shared_ptr<IconList> iconList, int iconSize = 48);
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
private:
std::shared_ptr<IconList> m_iconList;
int m_iconSize;
};

View File

@ -76,6 +76,7 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(backgrounds);
Q_INIT_RESOURCE(documents);
Q_INIT_RESOURCE(prismlauncher);
Q_INIT_RESOURCE(resources);
Q_INIT_RESOURCE(pe_dark);
Q_INIT_RESOURCE(pe_light);

View File

@ -50,7 +50,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent, int iconSize)
contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
contentsWidget->setFrameStyle(QFrame::NoFrame);
contentsWidget->setGridSize(QSize(m_iconSize * 2, m_iconSize * 2));
contentsWidget->setItemDelegate(new InstanceDelegate(this, m_iconSize, true));
contentsWidget->setItemDelegate(new InstanceDelegate(this, m_iconSize));
contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// contentsWidget->setAcceptDrops(true);

View File

@ -19,8 +19,8 @@
#include "InstanceDelegate.h"
#include "InstanceList.h"
InstanceDelegate::InstanceDelegate(QObject* parent, int iconSize, bool isGrid)
: QStyledItemDelegate(parent), m_iconSize(iconSize), m_isGrid(isGrid)
InstanceDelegate::InstanceDelegate(QObject* parent, int iconSize)
: QStyledItemDelegate(parent), m_iconSize(iconSize)
{}
void InstanceDelegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const
@ -28,9 +28,5 @@ void InstanceDelegate::initStyleOption(QStyleOptionViewItem* option, const QMode
QStyledItemDelegate::initStyleOption(option, index);
if (index.column() == InstanceList::NameColumn) {
option->decorationSize = QSize(m_iconSize, m_iconSize);
if (m_isGrid) {
// FIXME: kinda hacky way to add vertical padding. This assumes that the icon is square in the first place
option->decorationSize.rheight() += 8;
}
}
}

View File

@ -24,11 +24,10 @@ class InstanceDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
InstanceDelegate(QObject* parent = 0, int iconSize = 48, bool isGrid = false);
InstanceDelegate(QObject* parent = 0, int iconSize = 48);
void initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const override;
private:
int m_iconSize;
bool m_isGrid;
};

View File

@ -24,3 +24,21 @@
// Placeholder model, as we might need this in the future
InstanceGridProxyModel::InstanceGridProxyModel(QObject* parent) : InstanceTableProxyModel(parent) {}
QVariant InstanceGridProxyModel::data(const QModelIndex& index, int role) const
{
QVariant data = InstanceTableProxyModel::data(index, role);
QVariant displayData = data;
if (role != Qt::DisplayRole)
displayData = InstanceTableProxyModel::data(index, Qt::DisplayRole);
switch (role) {
case InstanceList::IconRole: {
QString iconKey = data.toString();
if (iconKey.isEmpty())
break;
return "image://instance/" + iconKey;
}
}
return data;
}

View File

@ -25,4 +25,7 @@ class InstanceGridProxyModel : public InstanceTableProxyModel {
public:
InstanceGridProxyModel(QObject* parent = 0);
protected:
QVariant data(const QModelIndex& index, int role) const override;
};

View File

@ -0,0 +1,49 @@
import QtQuick 2.0
GridView {
id: grid
model: instances
anchors.fill: parent
cellWidth: iconSize*2
cellHeight: iconSize*2
highlight: Rectangle {
width: grid.cellWidth; height: grid.cellHeight
color: "lightsteelblue"; radius: 5
x: grid.currentItem.x
y: grid.currentItem.y
Behavior on x { SmoothedAnimation { duration: 150 } }
Behavior on y { SmoothedAnimation { duration: 150 } }
}
interactive: true
focus: true
delegate: Item {
required property int index
required property string name
required property string icon
width: iconSize*2
height: iconSize*2
MouseArea {
anchors.fill: parent
onClicked: currentIndex = index;
}
Image {
id: icon
width: iconSize
height: iconSize
anchors.top: parent.top
source: parent.icon
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
anchors.top: icon.bottom
text: parent.name
anchors.horizontalCenter: parent.horizontalCenter
}
}
}

View File

@ -27,11 +27,14 @@
#include "InstanceDelegate.h"
#include "InstanceList.h"
#include "icons/IconImageProvider.h"
#include "ui/instanceview/InstanceGridProxyModel.h"
#include "ui/instanceview/InstanceTableProxyModel.h"
#include <QHeaderView>
#include <QKeyEvent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QSize>
#include <QSortFilterProxyModel>
@ -59,8 +62,8 @@ void InstancesView::switchDisplayMode(InstancesView::DisplayMode mode)
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
setCurrentWidget(m_table);
} else {
m_grid->selectionModel()->setCurrentIndex(m_gridProxy->mapFromSource(sourceIndex),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
//m_grid->selectionModel()->setCurrentIndex(m_gridProxy->mapFromSource(sourceIndex),
// QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
setCurrentWidget(m_grid);
}
m_displayMode = mode;
@ -92,7 +95,7 @@ void InstancesView::createTable()
m_table = new QTableView(this);
m_table->installEventFilter(this);
m_table->setModel(m_tableProxy);
m_table->setItemDelegate(new InstanceDelegate(this, m_iconSize, false));
m_table->setItemDelegate(new InstanceDelegate(this, m_iconSize));
m_table->setTabKeyNavigation(false);
m_table->setSelectionMode(QAbstractItemView::SingleSelection);
@ -138,27 +141,18 @@ void InstancesView::createTable()
void InstancesView::createGrid()
{
m_grid = new QListView(this);
m_grid = new QQuickWidget(this);
m_grid->rootContext()->setContextProperty("instances", m_gridProxy);
m_grid->rootContext()->setContextProperty("iconSize", m_iconSize);
m_grid->engine()->addImageProvider("instance", new IconImageProvider(APPLICATION->icons(), m_iconSize));
m_grid->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_grid->setSource(QUrl("qrc:/instanceview/InstancesGrid.qml"));
m_grid->installEventFilter(this);
m_grid->setModel(m_gridProxy);
m_grid->setModelColumn(InstanceList::NameColumn);
m_grid->setItemDelegate(new InstanceDelegate(this, m_iconSize, true));
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));
m_grid->show();
connect(m_grid, &QAbstractItemView::doubleClicked, this, &InstancesView::activateInstance);
connect(m_grid->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &InstancesView::currentRowChanged);
//connect(m_grid, &QAbstractItemView::doubleClicked, this, &InstancesView::activateInstance);
//connect(m_grid->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &InstancesView::currentRowChanged);
connect(m_grid, &QWidget::customContextMenuRequested, this, &InstancesView::contextMenuRequested);
}

View File

@ -21,6 +21,7 @@
#include <QListView>
#include <QStackedWidget>
#include <QTableView>
#include <QQuickWidget>
#include "BaseInstance.h"
#include "InstanceList.h"
@ -41,7 +42,7 @@ class InstancesView : public QStackedWidget {
QAbstractItemView* currentView()
{
if (m_displayMode == GridMode)
return m_grid;
return nullptr; // TODO
return m_table;
}
@ -82,7 +83,7 @@ class InstancesView : public QStackedWidget {
DisplayMode m_displayMode = TableMode;
QTableView* m_table;
QListView* m_grid;
QQuickWidget* m_grid;
InstanceTableProxyModel* m_tableProxy;
InstanceGridProxyModel* m_gridProxy;
InstanceList* m_instances;

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>instanceview/InstancesGrid.qml</file>
</qresource>
</RCC>