Revision control
Copy as Markdown
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "uniformmodel.h"
QT_BEGIN_NAMESPACE
UniformModel::UniformModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void UniformModel::setModelData(UniformTable *data)
{
beginResetModel();
m_uniformTable = data;
endResetModel();
}
int UniformModel::rowCount(const QModelIndex &) const
{
return int((m_uniformTable != nullptr) ? m_uniformTable->size() : 0);
}
QVariant UniformModel::data(const QModelIndex &index, int role) const
{
if (!m_uniformTable || !index.isValid())
return QVariant();
if (index.row() >= m_uniformTable->size())
return false;
const auto &uniform = (*m_uniformTable)[index.row()];
if (role == Type) {
return QVariant::fromValue(uniform.type);
} else if (role == Name) {
return QVariant::fromValue(QString::fromLatin1(uniform.name));
} else if (role == Value) {
switch (uniform.type) {
case CustomMaterial::Uniform::Type::Sampler:
return QVariant::fromValue(uniform.imagePath);
case CustomMaterial::Uniform::Type::Bool:
return QVariant::fromValue(uniform.b);
case CustomMaterial::Uniform::Type::Int:
return QVariant::fromValue(uniform.i);
case CustomMaterial::Uniform::Type::Float:
return QVariant::fromValue(uniform.f);
case CustomMaterial::Uniform::Type::Vec2:
return QVariant::fromValue(uniform.vec2);
case CustomMaterial::Uniform::Type::Vec3:
return QVariant::fromValue(uniform.vec3);
case CustomMaterial::Uniform::Type::Vec4:
return QVariant::fromValue(uniform.vec4);
case CustomMaterial::Uniform::Type::Mat44:
return QVariant::fromValue(uniform.m44);
case CustomMaterial::Uniform::Type::Last:
break;
}
}
return QVariant();
}
QHash<int, QByteArray> UniformModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Type] = "type";
roles[Name] = "name";
roles[Value] = "value";
return roles;
}
bool UniformModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || !m_uniformTable)
return false;
if (index.row() >= m_uniformTable->size())
return false;
auto &uniform = (*m_uniformTable)[index.row()];
bool ok = true;
if (role == Type) {
const auto v = value.toInt(&ok);
if (ok)
uniform.type = static_cast<CustomMaterial::Uniform::Type>(v);
} else if (role == Name) {
uniform.name = value.toString().toUtf8();
} else if (role == Value) {
switch (uniform.type) {
case CustomMaterial::Uniform::Type::Bool:
uniform.b = value.toBool();
break;
case CustomMaterial::Uniform::Type::Int:
uniform.i = value.toInt();
break;
case CustomMaterial::Uniform::Type::Float:
uniform.f = value.toFloat();
break;
case CustomMaterial::Uniform::Type::Vec2:
uniform.vec2 = value.value<QVector2D>();
break;
case CustomMaterial::Uniform::Type::Vec3:
uniform.vec3 = value.value<QVector3D>();
break;
case CustomMaterial::Uniform::Type::Vec4:
uniform.vec4 = value.value<QVector4D>();
break;
case CustomMaterial::Uniform::Type::Mat44:
uniform.m44 = value.value<QMatrix4x4>();
break;
case CustomMaterial::Uniform::Type::Sampler:
uniform.imagePath = value.toUrl().path();
break;
case CustomMaterial::Uniform::Type::Last:
break;
}
}
if (ok)
emit dataChanged(index, index, {role});
return ok;
}
bool UniformModel::insertRow(int rowIndex, int type, const QString &id)
{
if (m_uniformTable == nullptr)
return false;
if (!validateUniformName(id))
return false;
beginInsertRows(QModelIndex(), rowIndex, rowIndex);
CustomMaterial::Uniform uniform = { };
uniform.type = CustomMaterial::Uniform::Type(type);
uniform.name = id.toLocal8Bit();
switch (uniform.type) {
case CustomMaterial::Uniform::Type::Bool:
uniform.b = false;
break;
case CustomMaterial::Uniform::Type::Int:
uniform.i = 0;
break;
case CustomMaterial::Uniform::Type::Float:
uniform.f = 0.0f;
break;
case CustomMaterial::Uniform::Type::Vec2:
uniform.vec2 = QVector2D();
break;
case CustomMaterial::Uniform::Type::Vec3:
uniform.vec3 = QVector3D();
break;
case CustomMaterial::Uniform::Type::Vec4:
uniform.vec4 = QVector4D();
break;
case CustomMaterial::Uniform::Type::Mat44:
uniform.m44 = QMatrix4x4();
break;
case CustomMaterial::Uniform::Type::Sampler:
uniform.imagePath = QString();
break;
case CustomMaterial::Uniform::Type::Last:
Q_UNREACHABLE();
break;
}
m_uniformTable->insert(rowIndex, uniform);
endInsertRows();
emit dataChanged(QAbstractItemModel::createIndex(0, 0),
QAbstractItemModel::createIndex(rowIndex, 0));
return true;
}
void UniformModel::removeRow(int rowIndex, int rows)
{
if (m_uniformTable == nullptr)
return;
if (m_uniformTable->size() > rowIndex) {
rows = qBound(1, rows, m_uniformTable->size());
beginRemoveRows(QModelIndex(), rowIndex, rowIndex + rows - 1);
m_uniformTable->remove(rowIndex, rows);
endRemoveRows();
emit dataChanged(QAbstractItemModel::createIndex(0, 0),
QAbstractItemModel::createIndex(rowIndex, 0));
}
}
bool UniformModel::validateUniformName(const QString &uniformName)
{
if (!m_uniformTable)
return false;
// must be unique
for (const auto &uniform : *m_uniformTable)
{
if (uniform.name == uniformName)
return false;
}
// TODO: There are probably some other requirments
return true;
}
QT_END_NAMESPACE