aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@qt.io>2023-10-05 15:58:09 +0200
committerTim Jenssen <tim.jenssen@qt.io>2023-10-05 13:59:07 +0000
commite02f87da5854a90d3a74255932b041a8173e0e31 (patch)
tree55ff185c5fd8a33064854d66f69c7003ff08597a /src
parent0a5f48a9493d280855821b6f503ecccbba298cea (diff)
parent05aa1e76dad4fd853131c2ab75eae72deaf34aae (diff)
Merge remote-tracking branch 'origin/qds/dev' into 12.0
Diffstat (limited to 'src')
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp199
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h76
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectioneditorconstants.h2
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.cpp120
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.h15
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp28
-rw-r--r--src/tools/qml2puppet/mockfiles/qt6/GridMaterial.qml1
-rw-r--r--src/tools/qml2puppet/mockfiles/qt6/HelperGrid.qml21
-rw-r--r--src/tools/qml2puppet/mockfiles/qt6/SceneView3D.qml8
-rw-r--r--src/tools/qml2puppet/mockfiles/shaders/gridmaterial.frag12
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp9
12 files changed, 414 insertions, 78 deletions
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 97dbc9eac3..a2f0dba38e 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -792,6 +792,7 @@ extend_qtc_plugin(QmlDesigner
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/collectioneditor
SOURCES
+ collectiondetails.cpp collectiondetails.h
collectioneditorconstants.h
collectionlistmodel.cpp collectionlistmodel.h
collectionsourcemodel.cpp collectionsourcemodel.h
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp
new file mode 100644
index 0000000000..4b8a297140
--- /dev/null
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp
@@ -0,0 +1,199 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "collectiondetails.h"
+
+#include <QJsonObject>
+#include <QVariant>
+
+namespace QmlDesigner {
+
+class CollectionDetails::Private
+{
+ using SourceFormat = CollectionEditor::SourceFormat;
+
+public:
+ QStringList headers;
+ QList<QJsonObject> elements;
+ SourceFormat sourceFormat = SourceFormat::Unknown;
+ CollectionReference reference;
+ bool isChanged = false;
+
+ bool isValidColumnId(int column) const { return column > -1 && column < headers.size(); }
+
+ bool isValidRowId(int row) const { return row > -1 && row < elements.size(); }
+};
+
+CollectionDetails::CollectionDetails()
+ : d(new Private())
+{}
+
+CollectionDetails::CollectionDetails(const CollectionReference &reference)
+ : CollectionDetails()
+{
+ d->reference = reference;
+}
+
+CollectionDetails::CollectionDetails(const CollectionDetails &other) = default;
+
+CollectionDetails::~CollectionDetails() = default;
+
+void CollectionDetails::resetDetails(const QStringList &headers,
+ const QList<QJsonObject> &elements,
+ CollectionEditor::SourceFormat format)
+{
+ if (!isValid())
+ return;
+
+ d->headers = headers;
+ d->elements = elements;
+ d->sourceFormat = format;
+
+ markSaved();
+}
+
+void CollectionDetails::insertHeader(const QString &header, int place, const QVariant &defaultValue)
+{
+ if (!isValid())
+ return;
+
+ if (d->headers.contains(header))
+ return;
+
+ if (d->isValidColumnId(place))
+ d->headers.insert(place, header);
+ else
+ d->headers.append(header);
+
+ QJsonValue defaultJsonValue = QJsonValue::fromVariant(defaultValue);
+ for (QJsonObject &element : d->elements)
+ element.insert(header, defaultJsonValue);
+
+ markChanged();
+}
+
+void CollectionDetails::removeHeader(int place)
+{
+ if (!isValid())
+ return;
+
+ if (!d->isValidColumnId(place))
+ return;
+
+ const QString header = d->headers.takeAt(place);
+
+ for (QJsonObject &element : d->elements)
+ element.remove(header);
+
+ markChanged();
+}
+
+void CollectionDetails::insertElementAt(std::optional<QJsonObject> object, int row)
+{
+ if (!isValid())
+ return;
+
+ auto insertJson = [this, row](const QJsonObject &jsonObject) {
+ if (d->isValidRowId(row))
+ d->elements.insert(row, jsonObject);
+ else
+ d->elements.append(jsonObject);
+ };
+
+ if (object.has_value()) {
+ insertJson(object.value());
+ } else {
+ QJsonObject defaultObject;
+ for (const QString &header : std::as_const(d->headers))
+ defaultObject.insert(header, {});
+ insertJson(defaultObject);
+ }
+
+ markChanged();
+}
+
+CollectionReference CollectionDetails::reference() const
+{
+ return d->reference;
+}
+
+CollectionEditor::SourceFormat CollectionDetails::sourceFormat() const
+{
+ return d->sourceFormat;
+}
+
+QVariant CollectionDetails::data(int row, int column) const
+{
+ if (!isValid())
+ return {};
+
+ if (!d->isValidRowId(row))
+ return {};
+
+ if (!d->isValidColumnId(column))
+ return {};
+
+ const QString &propertyName = d->headers.at(column);
+ const QJsonObject &elementNode = d->elements.at(row);
+
+ if (elementNode.contains(propertyName))
+ return elementNode.value(propertyName).toVariant();
+
+ return {};
+}
+
+QString CollectionDetails::headerAt(int column) const
+{
+ if (!d->isValidColumnId(column))
+ return {};
+
+ return d->headers.at(column);
+}
+
+bool CollectionDetails::isValid() const
+{
+ return d->reference.node.isValid() && d->reference.name.size();
+}
+
+bool CollectionDetails::isChanged() const
+{
+ return d->isChanged;
+}
+
+int CollectionDetails::columns() const
+{
+ return d->headers.size();
+}
+
+int CollectionDetails::rows() const
+{
+ return d->elements.size();
+}
+
+bool CollectionDetails::markSaved()
+{
+ if (d->isChanged) {
+ d->isChanged = false;
+ return true;
+ }
+ return false;
+}
+
+void CollectionDetails::swap(CollectionDetails &other)
+{
+ d.swap(other.d);
+}
+
+CollectionDetails &CollectionDetails::operator=(const CollectionDetails &other)
+{
+ CollectionDetails value(other);
+ swap(value);
+ return *this;
+}
+
+void CollectionDetails::markChanged()
+{
+ d->isChanged = true;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h
new file mode 100644
index 0000000000..c3ec59f5d8
--- /dev/null
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h
@@ -0,0 +1,76 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "collectioneditorconstants.h"
+#include "modelnode.h"
+
+#include <QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+class QJsonObject;
+class QVariant;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+
+struct CollectionReference
+{
+ ModelNode node;
+ QString name;
+
+ friend auto qHash(const CollectionReference &collection)
+ {
+ return qHash(collection.node) ^ ::qHash(collection.name);
+ }
+
+ bool operator==(const CollectionReference &other) const
+ {
+ return node == other.node && name == other.name;
+ }
+
+ bool operator!=(const CollectionReference &other) const { return !(*this == other); }
+};
+
+class CollectionDetails
+{
+public:
+ explicit CollectionDetails();
+ CollectionDetails(const CollectionReference &reference);
+ CollectionDetails(const CollectionDetails &other);
+ ~CollectionDetails();
+
+ void resetDetails(const QStringList &headers,
+ const QList<QJsonObject> &elements,
+ CollectionEditor::SourceFormat format);
+ void insertHeader(const QString &header, int place = -1, const QVariant &defaultValue = {});
+ void removeHeader(int place);
+
+ void insertElementAt(std::optional<QJsonObject> object, int row = -1);
+
+ CollectionReference reference() const;
+ CollectionEditor::SourceFormat sourceFormat() const;
+ QVariant data(int row, int column) const;
+ QString headerAt(int column) const;
+
+ bool isValid() const;
+ bool isChanged() const;
+
+ int columns() const;
+ int rows() const;
+
+ bool markSaved();
+
+ void swap(CollectionDetails &other);
+ CollectionDetails &operator=(const CollectionDetails &other);
+
+private:
+ void markChanged();
+
+ // The private data is supposed to be shared between the copies
+ class Private;
+ QSharedPointer<Private> d;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorconstants.h b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorconstants.h
index d75fe221e9..f5e18a93ec 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorconstants.h
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorconstants.h
@@ -5,6 +5,8 @@
namespace QmlDesigner::CollectionEditor {
+enum class SourceFormat { Unknown, Json, Csv };
+
inline constexpr char SOURCEFILE_PROPERTY[] = "sourceFile";
inline constexpr char COLLECTIONMODEL_IMPORT[] = "QtQuick.Studio.Models";
diff --git a/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.cpp
index 62a95474a5..a86b42cd16 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.cpp
+++ b/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.cpp
@@ -11,6 +11,7 @@
#include <QFile>
#include <QJsonArray>
+#include <QJsonObject>
#include <QJsonParseError>
namespace {
@@ -39,26 +40,19 @@ SingleCollectionModel::SingleCollectionModel(QObject *parent)
int SingleCollectionModel::rowCount([[maybe_unused]] const QModelIndex &parent) const
{
- return m_elements.count();
+ return m_currentCollection.rows();
}
int SingleCollectionModel::columnCount([[maybe_unused]] const QModelIndex &parent) const
{
- return m_headers.count();
+ return m_currentCollection.columns();
}
QVariant SingleCollectionModel::data(const QModelIndex &index, int) const
{
if (!index.isValid())
return {};
-
- const QString &propertyName = m_headers.at(index.column());
- const QJsonObject &elementNode = m_elements.at(index.row());
-
- if (elementNode.contains(propertyName))
- return elementNode.value(propertyName).toVariant();
-
- return {};
+ return m_currentCollection.data(index.row(), index.column());
}
bool SingleCollectionModel::setData(const QModelIndex &, const QVariant &, int)
@@ -79,7 +73,7 @@ QVariant SingleCollectionModel::headerData(int section,
[[maybe_unused]] int role) const
{
if (orientation == Qt::Horizontal)
- return m_headers.at(section);
+ return m_currentCollection.headerAt(section);
return {};
}
@@ -88,16 +82,62 @@ void SingleCollectionModel::loadCollection(const ModelNode &sourceNode, const QS
{
QString fileName = sourceNode.variantProperty(CollectionEditor::SOURCEFILE_PROPERTY).value().toString();
- if (sourceNode.type() == CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME)
- loadJsonCollection(fileName, collection);
- else if (sourceNode.type() == CollectionEditor::CSVCOLLECTIONMODEL_TYPENAME)
- loadCsvCollection(fileName, collection);
+ CollectionReference newReference{sourceNode, collection};
+ bool alreadyOpen = m_openedCollections.contains(newReference);
+
+ if (alreadyOpen) {
+ if (m_currentCollection.reference() != newReference) {
+ beginResetModel();
+ switchToCollection(newReference);
+ endResetModel();
+ }
+ } else {
+ switchToCollection(newReference);
+ if (sourceNode.type() == CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME)
+ loadJsonCollection(fileName, collection);
+ else if (sourceNode.type() == CollectionEditor::CSVCOLLECTIONMODEL_TYPENAME)
+ loadCsvCollection(fileName, collection);
+ }
+}
+
+void SingleCollectionModel::switchToCollection(const CollectionReference &collection)
+{
+ if (m_currentCollection.reference() == collection)
+ return;
+
+ closeCurrentCollectionIfSaved();
+
+ if (!m_openedCollections.contains(collection))
+ m_openedCollections.insert(collection, CollectionDetails(collection));
+
+ m_currentCollection = m_openedCollections.value(collection);
+
+ setCollectionName(collection.name);
+}
+
+void SingleCollectionModel::closeCollectionIfSaved(const CollectionReference &collection)
+{
+ if (!m_openedCollections.contains(collection))
+ return;
+
+ const CollectionDetails &collectionDetails = m_openedCollections.value(collection);
+
+ if (!collectionDetails.isChanged())
+ m_openedCollections.remove(collection);
+
+ m_currentCollection = CollectionDetails{};
+}
+
+void SingleCollectionModel::closeCurrentCollectionIfSaved()
+{
+ if (m_currentCollection.isValid())
+ closeCollectionIfSaved(m_currentCollection.reference());
}
void SingleCollectionModel::loadJsonCollection(const QString &source, const QString &collection)
{
- beginResetModel();
- setCollectionName(collection);
+ using CollectionEditor::SourceFormat;
+
QFile sourceFile(source);
QJsonArray collectionNodes;
bool jsonFileIsOk = false;
@@ -119,62 +159,64 @@ void SingleCollectionModel::loadJsonCollection(const QString &source, const QStr
}
}
- setCollectionSourceFormat(jsonFileIsOk ? SourceFormat::Json : SourceFormat::Unknown);
-
if (collectionNodes.isEmpty()) {
- m_headers.clear();
- m_elements.clear();
+ closeCurrentCollectionIfSaved();
endResetModel();
return;
- }
-
- m_headers = getJsonHeaders(collectionNodes);
+ };
- m_elements.clear();
+ QList<QJsonObject> elements;
for (const QJsonValue &value : std::as_const(collectionNodes)) {
if (value.isObject()) {
QJsonObject object = value.toObject();
- m_elements.append(object);
+ elements.append(object);
}
}
+ SourceFormat sourceFormat = jsonFileIsOk ? SourceFormat::Json : SourceFormat::Unknown;
+
+ beginResetModel();
+ m_currentCollection.resetDetails(getJsonHeaders(collectionNodes), elements, sourceFormat);
endResetModel();
}
-void SingleCollectionModel::loadCsvCollection(const QString &source, const QString &collectionName)
+void SingleCollectionModel::loadCsvCollection(const QString &source,
+ [[maybe_unused]] const QString &collectionName)
{
- beginResetModel();
+ using CollectionEditor::SourceFormat;
- setCollectionName(collectionName);
QFile sourceFile(source);
- m_headers.clear();
- m_elements.clear();
+ QStringList headers;
+ QList<QJsonObject> elements;
bool csvFileIsOk = false;
if (sourceFile.open(QFile::ReadOnly)) {
QTextStream stream(&sourceFile);
if (!stream.atEnd())
- m_headers = stream.readLine().split(',');
+ headers = stream.readLine().split(',');
- if (!m_headers.isEmpty()) {
+ if (!headers.isEmpty()) {
while (!stream.atEnd()) {
const QStringList recordDataList = stream.readLine().split(',');
int column = -1;
QJsonObject recordData;
for (const QString &cellData : recordDataList) {
- if (++column == m_headers.size())
+ if (++column == headers.size())
break;
- recordData.insert(m_headers.at(column), cellData);
+ recordData.insert(headers.at(column), cellData);
}
if (recordData.count())
- m_elements.append(recordData);
+ elements.append(recordData);
}
csvFileIsOk = true;
}
}
- setCollectionSourceFormat(csvFileIsOk ? SourceFormat::Csv : SourceFormat::Unknown);
+ SourceFormat sourceFormat = csvFileIsOk ? SourceFormat::Csv : SourceFormat::Unknown;
+
+ beginResetModel();
+ m_currentCollection.resetDetails(headers, elements, sourceFormat);
endResetModel();
}
@@ -186,8 +228,4 @@ void SingleCollectionModel::setCollectionName(const QString &newCollectionName)
}
}
-void SingleCollectionModel::setCollectionSourceFormat(SourceFormat sourceFormat)
-{
- m_sourceFormat = sourceFormat;
-}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.h b/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.h
index 471e43b967..a545f4b0e7 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.h
+++ b/src/plugins/qmldesigner/components/collectioneditor/singlecollectionmodel.h
@@ -3,8 +3,10 @@
#pragma once
+#include "collectiondetails.h"
+
#include <QAbstractTableModel>
-#include <QJsonObject>
+#include <QHash>
namespace QmlDesigner {
@@ -17,7 +19,6 @@ class SingleCollectionModel : public QAbstractTableModel
Q_PROPERTY(QString collectionName MEMBER m_collectionName NOTIFY collectionNameChanged)
public:
- enum class SourceFormat { Unknown, Json, Csv };
explicit SingleCollectionModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
@@ -35,15 +36,17 @@ signals:
void collectionNameChanged(const QString &collectionName);
private:
+ void switchToCollection(const CollectionReference &collection);
+ void closeCollectionIfSaved(const CollectionReference &collection);
+ void closeCurrentCollectionIfSaved();
void setCollectionName(const QString &newCollectionName);
- void setCollectionSourceFormat(SourceFormat sourceFormat);
void loadJsonCollection(const QString &source, const QString &collection);
void loadCsvCollection(const QString &source, const QString &collectionName);
- QStringList m_headers;
- QList<QJsonObject> m_elements;
+ QHash<CollectionReference, CollectionDetails> m_openedCollections;
+ CollectionDetails m_currentCollection;
+
QString m_collectionName;
- SourceFormat m_sourceFormat = SourceFormat::Unknown;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
index ef7eca0d8f..e78a6d1a37 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
@@ -744,8 +744,9 @@ std::shared_ptr<NodeMetaInfoPrivate> NodeMetaInfoPrivate::create(Model *model,
newData->minorVersion());
if (auto found = cache.find(stringfiedQualifiedType); found != cache.end()) {
- cache.insert(stringfiedType, *found);
- return *found;
+ newData = *found;
+ cache.insert(stringfiedType, newData);
+ return newData;
}
if (stringfiedQualifiedType != stringfiedType)
@@ -1709,10 +1710,12 @@ std::vector<NodeMetaInfo> NodeMetaInfo::selfAndPrototypes() const
NodeMetaInfos hierarchy = {*this};
Model *model = m_privateData->model();
for (const TypeDescription &type : m_privateData->prototypes()) {
- hierarchy.emplace_back(model,
- type.className.toUtf8(),
- type.majorVersion,
- type.minorVersion);
+ auto &last = hierarchy.emplace_back(model,
+ type.className.toUtf8(),
+ type.majorVersion,
+ type.minorVersion);
+ if (!last.isValid())
+ hierarchy.pop_back();
}
return hierarchy;
@@ -1735,11 +1738,14 @@ NodeMetaInfos NodeMetaInfo::prototypes() const
if (isValid()) {
NodeMetaInfos hierarchy;
Model *model = m_privateData->model();
- for (const TypeDescription &type : m_privateData->prototypes())
- hierarchy.emplace_back(model,
- type.className.toUtf8(),
- type.majorVersion,
- type.minorVersion);
+ for (const TypeDescription &type : m_privateData->prototypes()) {
+ auto &last = hierarchy.emplace_back(model,
+ type.className.toUtf8(),
+ type.majorVersion,
+ type.minorVersion);
+ if (!last.isValid())
+ hierarchy.pop_back();
+ }
return hierarchy;
}
diff --git a/src/tools/qml2puppet/mockfiles/qt6/GridMaterial.qml b/src/tools/qml2puppet/mockfiles/qt6/GridMaterial.qml
index 37c23806b2..11ebbfd411 100644
--- a/src/tools/qml2puppet/mockfiles/qt6/GridMaterial.qml
+++ b/src/tools/qml2puppet/mockfiles/qt6/GridMaterial.qml
@@ -17,6 +17,5 @@ CustomMaterial {
sourceBlend: CustomMaterial.NoBlend
destinationBlend: CustomMaterial.NoBlend
shadingMode: CustomMaterial.Unshaded
- depthDrawMode: Material.AlwaysDepthDraw
cullMode: Material.NoCulling
}
diff --git a/src/tools/qml2puppet/mockfiles/qt6/HelperGrid.qml b/src/tools/qml2puppet/mockfiles/qt6/HelperGrid.qml
index e189d06401..c82303d779 100644
--- a/src/tools/qml2puppet/mockfiles/qt6/HelperGrid.qml
+++ b/src/tools/qml2puppet/mockfiles/qt6/HelperGrid.qml
@@ -14,7 +14,18 @@ Node {
property double distance: 500
readonly property int maxGridStep: 32 * _generalHelper.minGridStep
- readonly property int gridArea: _generalHelper.minGridStep * 512
+
+ readonly property int gridArea: {
+ let newArea = _generalHelper.minGridStep * 512
+
+ // Let's limit the grid size to something sensible
+ while (newArea > 30000)
+ newArea -= gridStep
+
+ return newArea
+ }
+
+ readonly property double gridOpacity: 0.99
// Step of the main lines of the grid, between those is always one subdiv line
property int gridStep: 100
@@ -71,7 +82,7 @@ Node {
orthoMode: grid.orthoMode
}
]
- opacity: 0.99
+ opacity: grid.gridOpacity
}
Model { // Subdivision lines
@@ -91,7 +102,7 @@ Node {
orthoMode: grid.orthoMode
}
]
- opacity: 0.99
+ opacity: grid.gridOpacity
}
Model { // Z Axis
@@ -110,7 +121,7 @@ Node {
orthoMode: grid.orthoMode
}
]
- opacity: 0.99
+ opacity: grid.gridOpacity
}
Model { // X Axis
readonly property bool _edit3dLocked: true // Make this non-pickable
@@ -129,6 +140,6 @@ Node {
orthoMode: grid.orthoMode
}
]
- opacity: 0.99
+ opacity: grid.gridOpacity
}
}
diff --git a/src/tools/qml2puppet/mockfiles/qt6/SceneView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/SceneView3D.qml
index 0eafeeb816..6945579bf1 100644
--- a/src/tools/qml2puppet/mockfiles/qt6/SceneView3D.qml
+++ b/src/tools/qml2puppet/mockfiles/qt6/SceneView3D.qml
@@ -22,8 +22,12 @@ View3D {
// gives a reasonable grid spacing in most cases while keeping spacing constant when
// orbiting the camera.
readonly property double cameraDistance: {
- if (usePerspective)
- return cameraLookAt.minus(camera.position).length() + Math.abs(cameraLookAt.y)
+ if (usePerspective) {
+ // Round to five decimals to avoid rounding errors causing constant property updates
+ // on the material when simply orbiting.
+ let dist = cameraLookAt.minus(camera.position).length() + Math.abs(cameraLookAt.y)
+ return Number(dist.toPrecision(5));
+ }
// Orthocamera should only care about camera magnification,
// as grid will be same size regardless of distance, so setting steps based on distance
diff --git a/src/tools/qml2puppet/mockfiles/shaders/gridmaterial.frag b/src/tools/qml2puppet/mockfiles/shaders/gridmaterial.frag
index 7d785bc531..20738ff46b 100644
--- a/src/tools/qml2puppet/mockfiles/shaders/gridmaterial.frag
+++ b/src/tools/qml2puppet/mockfiles/shaders/gridmaterial.frag
@@ -19,15 +19,9 @@ void MAIN()
if (depth > 90000.0)
alpha *= clamp((100000.0 - depth) / 10000.0, 0, 1);
- if (alpha > 0.01) {
- vec2 uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0));
- vec4 sc = texture(SCREEN_TEXTURE, uv);
- if (sc.a == 0.0)
- FRAGCOLOR = vec4(color.xyz * alpha, alpha);
- else
- FRAGCOLOR = vec4((color.xyz * alpha + sc.xyz * (1.0 - alpha)) * alpha, alpha);
- } else {
+ if (alpha > 0.01)
+ FRAGCOLOR = vec4(color.xyz * alpha, alpha);
+ else
discard;
- }
}
}
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
index 1ef951ca3b..4af31d072f 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
@@ -81,9 +81,12 @@ void GridGeometry::doUpdateGeometry()
setVertexData(vertexData);
int lastIndex = (vertexData.size() - 1) / int(sizeof(QVector3D));
- auto vertexPtr = reinterpret_cast<QVector3D *>(vertexData.data());
- setBounds(QVector3D(vertexPtr[0][0], vertexPtr[0][1], 0.0),
- QVector3D(vertexPtr[lastIndex][0], vertexPtr[lastIndex][1], 0.0));
+
+ // Set bounds based on main grid size instead of actual mesh size to make all parts of the
+ // grid have consistent bounds.
+ const float extent = float(m_lines) * m_step;
+ setBounds(QVector3D(-extent, -extent, 0.0),
+ QVector3D(extent, extent, 0.0));
}
#if QT_VERSION_MAJOR == 6 && QT_VERSION_MINOR == 4