diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index 0410bbf3e5e..b715deb9c3c 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include namespace QmlDesigner { @@ -74,6 +73,9 @@ BakeLights::BakeLights(AbstractView *view) return; } + m_pendingRebakeTimer.setInterval(100); + connect(&m_pendingRebakeTimer, &QTimer::timeout, this, &BakeLights::handlePendingRebakeTimeout); + showSetupDialog(); } @@ -215,7 +217,8 @@ void BakeLights::rebake() void BakeLights::exposeModelsAndLights(const QString &nodeId) { ModelNode compNode = m_view->modelNodeForId(nodeId); - if (!compNode.isValid() || !compNode.isComponent()) { + if (!compNode.isValid() || !compNode.isComponent() + || (m_pendingRebakeTimer.isActive() && compNode == m_pendingRebakeCheckNode)) { return; } @@ -294,8 +297,9 @@ void BakeLights::exposeModelsAndLights(const QString &nodeId) compModel->setRewriterView({}); - // Rebake to relaunch setup dialog with updated properties - rebake(); + m_pendingRebakeTimerCount = 0; + m_pendingRebakeCheckNode = compNode; + m_pendingRebakeTimer.start(); } void BakeLights::showSetupDialog() @@ -376,6 +380,8 @@ void BakeLights::cleanup() m_model.reset(); } + pendingRebakeCleanup(); + delete m_setupDialog; delete m_progressDialog; delete m_rewriterView; @@ -386,6 +392,43 @@ void BakeLights::cleanup() m_manualMode = false; } +void BakeLights::handlePendingRebakeTimeout() +{ + QScopeGuard timerCleanup([this]() { + pendingRebakeCleanup(); + }); + + if (m_view.isNull() || !m_pendingRebakeCheckNode || !m_pendingRebakeCheckNode.isComponent()) + return; + + const Model *model = m_pendingRebakeCheckNode.model(); + if (!model) + return; + + const QList props = m_pendingRebakeCheckNode.properties(); + PropertyMetaInfos metaInfos = m_pendingRebakeCheckNode.metaInfo().properties(); + for (const PropertyMetaInfo &mi : metaInfos) { + if (mi.isValid() && !mi.isPrivate() && mi.isWritable()) { + if (mi.propertyType().isBasedOn(model->qtQuick3DModelMetaInfo(), + model->qtQuick3DLightMetaInfo())) { + // Rebake to relaunch setup dialog with updated properties + rebake(); + return; + } + } + } + + if (++m_pendingRebakeTimerCount < 100) + timerCleanup.dismiss(); +} + +void BakeLights::pendingRebakeCleanup() +{ + m_pendingRebakeTimer.stop(); + m_pendingRebakeTimerCount = 0; + m_pendingRebakeCheckNode = {}; +} + void BakeLights::cancel() { if (!m_setupDialog.isNull() && m_setupDialog->isVisible()) diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.h b/src/plugins/qmldesigner/components/edit3d/bakelights.h index 2b6848bd482..3bdb8bfec9d 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.h +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.h @@ -7,6 +7,7 @@ #include #include +#include QT_BEGIN_NAMESPACE class QQuickView; @@ -53,6 +54,8 @@ private: void showSetupDialog(); void showProgressDialog(); void cleanup(); + void handlePendingRebakeTimeout(); + void pendingRebakeCleanup(); // Separate dialogs for setup and progress, as setup needs to be modal QPointer m_setupDialog; @@ -66,6 +69,9 @@ private: ModelPointer m_model; QString m_view3dId; bool m_manualMode = false; + QTimer m_pendingRebakeTimer; + ModelNode m_pendingRebakeCheckNode; + int m_pendingRebakeTimerCount = 0; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 286e203e704..262b2078283 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -172,6 +172,7 @@ public: NodeMetaInfo qtQuick3DBakedLightmapMetaInfo() const; NodeMetaInfo qtQuick3DDefaultMaterialMetaInfo() const; NodeMetaInfo qtQuick3DDirectionalLightMetaInfo() const; + NodeMetaInfo qtQuick3DLightMetaInfo() const; NodeMetaInfo qtQuick3DMaterialMetaInfo() const; NodeMetaInfo qtQuick3DModelMetaInfo() const; NodeMetaInfo qtQuick3DNodeMetaInfo() const; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 98d3e7f6669..9e1b6959c59 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2724,6 +2724,16 @@ NodeMetaInfo Model::qtQuick3DDefaultMaterialMetaInfo() const } } +NodeMetaInfo Model::qtQuick3DLightMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick3D.Light"); + } +} + NodeMetaInfo Model::qtQuick3DDirectionalLightMetaInfo() const { if constexpr (useProjectStorage()) {