Commit 556406f9 authored by Yuya Nishihara's avatar Yuya Nishihara
Browse files

reimplement TileListModel in C++

I'll add more logic to this model and JavaScript sucks.
parent fe99c309
......@@ -15,8 +15,10 @@ find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick REQUIRED)
set(PROJECT_SOURCES
main.cpp
qml.qrc
main.cpp
qml.qrc
tilelistmodel.cpp
tilelistmodel.h
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
......
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "tilelistmodel.h"
int main(int argc, char *argv[])
{
......@@ -9,6 +10,8 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
qmlRegisterType<TileListModel>("MyTileExample", 1, 0, "TileListModel");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(
......
......@@ -3,6 +3,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import MyTileExample 1.0
Window {
id: root
......@@ -15,31 +16,13 @@ Window {
visible: true
title: qsTr("Hello World")
ListModel {
TileListModel {
id: tileListModel
function setTileIndex(index, tileIndex) {
if (get(index).tileIndex === tileIndex)
return;
for (let i = 0; i < count; ++i) {
if (get(i).tileIndex !== tileIndex)
continue;
setProperty(i, "tileIndex", -1);
break;
Component.onCompleted: {
for (let i = 0; i < 10; ++i) {
assignTileItem(String.fromCharCode(65 + i));
}
setProperty(index, "tileIndex", tileIndex);
}
ListElement { name: "A"; tileIndex: 0 }
ListElement { name: "B"; tileIndex: 1 }
ListElement { name: "C"; tileIndex: 2 }
ListElement { name: "D"; tileIndex: 3 }
ListElement { name: "E"; tileIndex: 4 }
ListElement { name: "F"; tileIndex: 5 }
ListElement { name: "G"; tileIndex: 6 }
ListElement { name: "H"; tileIndex: 7 }
ListElement { name: "I"; tileIndex: 8 }
ListElement { name: "J"; tileIndex: 9 }
}
RowLayout {
......
#include <algorithm>
#include "tilelistmodel.h"
namespace {
enum Role : int {
NameRole = Qt::UserRole + 1,
TileIndexRole,
};
}
TileListModel::TileListModel(QObject *parent) : QAbstractListModel(parent), m_tiles() { }
QHash<int, QByteArray> TileListModel::roleNames() const
{
static const QHash<int, QByteArray> roles = {
{ NameRole, QByteArrayLiteral("name") },
{ TileIndexRole, QByteArrayLiteral("tileIndex") },
};
return roles;
}
int TileListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return static_cast<int>(m_tiles.size());
}
QVariant TileListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.parent().isValid())
return {};
if (index.row() < 0 || index.row() >= static_cast<int>(m_tiles.size()))
return {};
const auto &tile = m_tiles.at(static_cast<size_t>(index.row()));
switch (static_cast<Role>(role)) {
case NameRole:
return tile.name;
case TileIndexRole:
return tile.tileIndex;
}
return {};
}
void TileListModel::assignTileItem(const QString &name)
{
const int row = static_cast<int>(m_tiles.size());
beginInsertRows(QModelIndex(), row, row);
m_tiles.push_back({ name, row }); // TODO: assign free tile index
endInsertRows();
}
void TileListModel::setTileIndex(int row, int tileIndex)
{
if (row < 0 || row >= static_cast<int>(m_tiles.size()))
return;
auto &tile = m_tiles.at(static_cast<size_t>(row));
if (tile.tileIndex == tileIndex)
return;
const auto p = std::find_if(m_tiles.begin(), m_tiles.end(),
[tileIndex](const auto &t) { return t.tileIndex == tileIndex; });
if (p != m_tiles.end()) {
p->tileIndex = -1;
const int r = static_cast<int>(p - m_tiles.begin());
emit dataChanged(index(r), index(r), { TileIndexRole });
}
tile.tileIndex = tileIndex;
emit dataChanged(index(row), index(row), { TileIndexRole });
}
#ifndef TILELISTMODEL_H
#define TILELISTMODEL_H
#include <QAbstractListModel>
#include <vector>
class TileListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit TileListModel(QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE void assignTileItem(const QString &name);
Q_INVOKABLE void setTileIndex(int row, int tileIndex);
private:
struct Tile
{
QString name;
int tileIndex;
};
std::vector<Tile> m_tiles;
};
#endif // TILELISTMODEL_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment