1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "uniformmodel.h"
5
6QT_BEGIN_NAMESPACE
7
8UniformModel::UniformModel(QObject *parent)
9 : QAbstractListModel(parent)
10{
11
12}
13
14void UniformModel::setModelData(UniformTable *data)
15{
16 beginResetModel();
17 m_uniformTable = data;
18 endResetModel();
19}
20
21int UniformModel::rowCount(const QModelIndex &) const
22{
23 return int((m_uniformTable != nullptr) ? m_uniformTable->size() : 0);
24}
25
26QVariant UniformModel::data(const QModelIndex &index, int role) const
27{
28 if (!m_uniformTable || !index.isValid())
29 return QVariant();
30
31 if (index.row() >= m_uniformTable->size())
32 return false;
33
34 const auto &uniform = (*m_uniformTable)[index.row()];
35
36 if (role == Type) {
37 return QVariant::fromValue(value: uniform.type);
38 } else if (role == Name) {
39 return QVariant::fromValue(value: QString::fromLatin1(ba: uniform.name));
40 } else if (role == Value) {
41 switch (uniform.type) {
42 case CustomMaterial::Uniform::Type::Sampler:
43 return QVariant::fromValue(value: uniform.imagePath);
44 case CustomMaterial::Uniform::Type::Bool:
45 return QVariant::fromValue(value: uniform.b);
46 case CustomMaterial::Uniform::Type::Int:
47 return QVariant::fromValue(value: uniform.i);
48 case CustomMaterial::Uniform::Type::Float:
49 return QVariant::fromValue(value: uniform.f);
50 case CustomMaterial::Uniform::Type::Vec2:
51 return QVariant::fromValue(value: uniform.vec2);
52 case CustomMaterial::Uniform::Type::Vec3:
53 return QVariant::fromValue(value: uniform.vec3);
54 case CustomMaterial::Uniform::Type::Vec4:
55 return QVariant::fromValue(value: uniform.vec4);
56 case CustomMaterial::Uniform::Type::Mat44:
57 return QVariant::fromValue(value: uniform.m44);
58 case CustomMaterial::Uniform::Type::Last:
59 break;
60 }
61 }
62
63 return QVariant();
64}
65
66QHash<int, QByteArray> UniformModel::roleNames() const
67{
68 QHash<int, QByteArray> roles;
69 roles[Type] = "type";
70 roles[Name] = "name";
71 roles[Value] = "value";
72 return roles;
73}
74
75bool UniformModel::setData(const QModelIndex &index, const QVariant &value, int role)
76{
77 if (!index.isValid() || !m_uniformTable)
78 return false;
79
80 if (index.row() >= m_uniformTable->size())
81 return false;
82
83 auto &uniform = (*m_uniformTable)[index.row()];
84
85 bool ok = true;
86
87 if (role == Type) {
88 const auto v = value.toInt(ok: &ok);
89 if (ok)
90 uniform.type = static_cast<CustomMaterial::Uniform::Type>(v);
91 } else if (role == Name) {
92 uniform.name = value.toString().toUtf8();
93 } else if (role == Value) {
94 switch (uniform.type) {
95 case CustomMaterial::Uniform::Type::Bool:
96 uniform.b = value.toBool();
97 break;
98 case CustomMaterial::Uniform::Type::Int:
99 uniform.i = value.toInt();
100 break;
101 case CustomMaterial::Uniform::Type::Float:
102 uniform.f = value.toFloat();
103 break;
104 case CustomMaterial::Uniform::Type::Vec2:
105 uniform.vec2 = value.value<QVector2D>();
106 break;
107 case CustomMaterial::Uniform::Type::Vec3:
108 uniform.vec3 = value.value<QVector3D>();
109 break;
110 case CustomMaterial::Uniform::Type::Vec4:
111 uniform.vec4 = value.value<QVector4D>();
112 break;
113 case CustomMaterial::Uniform::Type::Mat44:
114 uniform.m44 = value.value<QMatrix4x4>();
115 break;
116 case CustomMaterial::Uniform::Type::Sampler:
117 uniform.imagePath = value.toUrl().path();
118 break;
119 case CustomMaterial::Uniform::Type::Last:
120 break;
121 }
122 }
123
124
125 if (ok)
126 emit dataChanged(topLeft: index, bottomRight: index, roles: {role});
127
128 return ok;
129}
130
131bool UniformModel::insertRow(int rowIndex, int type, const QString &id)
132{
133 if (m_uniformTable == nullptr)
134 return false;
135
136 if (!validateUniformName(uniformName: id))
137 return false;
138
139
140 beginInsertRows(parent: QModelIndex(), first: rowIndex, last: rowIndex);
141
142 CustomMaterial::Uniform uniform = { };
143 uniform.type = CustomMaterial::Uniform::Type(type);
144 uniform.name = id.toLocal8Bit();
145 switch (uniform.type) {
146 case CustomMaterial::Uniform::Type::Bool:
147 uniform.b = false;
148 break;
149 case CustomMaterial::Uniform::Type::Int:
150 uniform.i = 0;
151 break;
152 case CustomMaterial::Uniform::Type::Float:
153 uniform.f = 0.0f;
154 break;
155 case CustomMaterial::Uniform::Type::Vec2:
156 uniform.vec2 = QVector2D();
157 break;
158 case CustomMaterial::Uniform::Type::Vec3:
159 uniform.vec3 = QVector3D();
160 break;
161 case CustomMaterial::Uniform::Type::Vec4:
162 uniform.vec4 = QVector4D();
163 break;
164 case CustomMaterial::Uniform::Type::Mat44:
165 uniform.m44 = QMatrix4x4();
166 break;
167 case CustomMaterial::Uniform::Type::Sampler:
168 uniform.imagePath = QString();
169 break;
170 case CustomMaterial::Uniform::Type::Last:
171 Q_UNREACHABLE();
172 break;
173 }
174
175 m_uniformTable->insert(i: rowIndex, t: uniform);
176
177 endInsertRows();
178
179 emit dataChanged(topLeft: QAbstractItemModel::createIndex(arow: 0, acolumn: 0),
180 bottomRight: QAbstractItemModel::createIndex(arow: rowIndex, acolumn: 0));
181 return true;
182}
183
184void UniformModel::removeRow(int rowIndex, int rows)
185{
186 if (m_uniformTable == nullptr)
187 return;
188
189 if (m_uniformTable->size() > rowIndex) {
190 rows = qBound(min: 1, val: rows, max: m_uniformTable->size());
191 beginRemoveRows(parent: QModelIndex(), first: rowIndex, last: rowIndex + rows - 1);
192 m_uniformTable->remove(i: rowIndex, n: rows);
193 endRemoveRows();
194 emit dataChanged(topLeft: QAbstractItemModel::createIndex(arow: 0, acolumn: 0),
195 bottomRight: QAbstractItemModel::createIndex(arow: rowIndex, acolumn: 0));
196 }
197}
198
199bool UniformModel::validateUniformName(const QString &uniformName)
200{
201 if (!m_uniformTable)
202 return false;
203
204 // must be unique
205 for (const auto &uniform : *m_uniformTable)
206 {
207 if (uniform.name == uniformName)
208 return false;
209 }
210
211 // TODO: There are probably some other requirments
212
213 return true;
214}
215
216QT_END_NAMESPACE
217
218
219

source code of qtquick3d/tools/materialeditor/uniformmodel.cpp