QmlDesigner: Ensure material library gets created always

ComponentView already has some material library related functionality
and it is guaranteed to always be attached, so move material
library ensuring functionality there from material and texture editor
views. This also reduces duplicated code.

Fixes: QDS-13387
Change-Id: I60732d8f32eb79c64b83c0dc0406f720c5f11493
Reviewed-by: Ali Kianian <ali.kianian@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2025-02-18 13:49:55 +02:00
parent f999308802
commit 842df0568d
6 changed files with 59 additions and 65 deletions

View File

@@ -26,6 +26,8 @@ ComponentView::ComponentView(ExternalDependenciesInterface &externalDependencies
, m_standardItemModel(new QStandardItemModel(this)) , m_standardItemModel(new QStandardItemModel(this))
, m_componentAction(new ComponentAction(this)) , m_componentAction(new ComponentAction(this))
{ {
connect(&m_ensureMatLibTimer, &QTimer::timeout, this, &ComponentView::ensureMatLibTriggered);
m_ensureMatLibTimer.setInterval(500);
} }
void ComponentView::nodeAboutToBeRemoved(const ModelNode &removedNode) void ComponentView::nodeAboutToBeRemoved(const ModelNode &removedNode)
@@ -161,6 +163,48 @@ bool ComponentView::isSubComponentNode(const ModelNode &node) const
&& node.metaInfo().isGraphicalItem()); && node.metaInfo().isGraphicalItem());
} }
void ComponentView::ensureMatLibTriggered()
{
if (!model() || !model()->rewriterView()
|| model()->rewriterView()->hasIncompleteTypeInformation()
|| !model()->rewriterView()->errors().isEmpty()) {
return;
}
m_ensureMatLibTimer.stop();
ModelNode matLib = Utils3D::materialLibraryNode(this);
if (matLib.isValid())
return;
DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument();
if (doc && !doc->inFileComponentModelActive())
Utils3D::ensureMaterialLibraryNode(this);
matLib = Utils3D::materialLibraryNode(this);
if (!matLib.isValid())
return;
bool texSelected = Utils3D::selectedTexture(this).isValid();
bool matSelected = Utils3D::selectedMaterial(this).isValid();
if (!texSelected || !matSelected) {
const QList<ModelNode> matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &node : matLibNodes) {
if (!texSelected && node.metaInfo().isQtQuick3DTexture()) {
Utils3D::selectTexture(node);
if (matSelected)
break;
texSelected = true;
}
if (!matSelected && node.metaInfo().isQtQuick3DMaterial()) {
Utils3D::selectMaterial(node);
if (texSelected)
break;
matSelected = true;
}
}
}
}
void ComponentView::modelAttached(Model *model) void ComponentView::modelAttached(Model *model)
{ {
if (AbstractView::model() == model) if (AbstractView::model() == model)
@@ -172,12 +216,19 @@ void ComponentView::modelAttached(Model *model)
AbstractView::modelAttached(model); AbstractView::modelAttached(model);
searchForComponentAndAddToList(rootModelNode()); searchForComponentAndAddToList(rootModelNode());
if (model->hasImport("QtQuick3D")) {
// Creating the material library node on model attach causes errors as long as the type
// information is not complete yet, so we keep checking until type info is complete.
m_ensureMatLibTimer.start();
}
} }
void ComponentView::modelAboutToBeDetached(Model *model) void ComponentView::modelAboutToBeDetached(Model *model)
{ {
QSignalBlocker blocker(m_componentAction); QSignalBlocker blocker(m_componentAction);
m_standardItemModel->clear(); m_standardItemModel->clear();
m_ensureMatLibTimer.stop();
AbstractView::modelAboutToBeDetached(model); AbstractView::modelAboutToBeDetached(model);
} }
@@ -359,6 +410,9 @@ void ComponentView::importsChanged(const Imports &addedImports, const Imports &r
resetPuppet(); resetPuppet();
} }
} }
if (model()->hasImport("QtQuick3D"))
m_ensureMatLibTimer.start();
} }
void ComponentView::possibleImportsChanged([[maybe_unused]] const Imports &possibleImports) void ComponentView::possibleImportsChanged([[maybe_unused]] const Imports &possibleImports)

View File

@@ -7,6 +7,7 @@
#include <modelnode.h> #include <modelnode.h>
#include <QStringList> #include <QStringList>
#include <QTimer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QStandardItemModel; class QStandardItemModel;
@@ -71,6 +72,7 @@ private: //functions
QString descriptionForNode(const ModelNode &node) const; QString descriptionForNode(const ModelNode &node) const;
void updateDescription(const ModelNode &node); void updateDescription(const ModelNode &node);
bool isSubComponentNode(const ModelNode &node) const; bool isSubComponentNode(const ModelNode &node) const;
void ensureMatLibTriggered();
private: private:
QStandardItemModel *m_standardItemModel; QStandardItemModel *m_standardItemModel;
@@ -78,6 +80,7 @@ private:
QVariantMap m_importableExtensions3DMap; QVariantMap m_importableExtensions3DMap;
QVariantMap m_importOptions3DMap; QVariantMap m_importOptions3DMap;
QTimer m_ensureMatLibTimer;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -86,30 +86,6 @@ MaterialEditorView::MaterialEditorView(ExternalDependenciesInterface &externalDe
m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F7), m_stackedWidget); m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F7), m_stackedWidget);
connect(m_updateShortcut, &QShortcut::activated, this, &MaterialEditorView::reloadQml); connect(m_updateShortcut, &QShortcut::activated, this, &MaterialEditorView::reloadQml);
m_ensureMatLibTimer.callOnTimeout([this] {
if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation()
&& model()->rewriterView()->errors().isEmpty()) {
DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument();
if (doc && !doc->inFileComponentModelActive())
Utils3D::ensureMaterialLibraryNode(this);
ModelNode matLib = Utils3D::materialLibraryNode(this);
if (m_qmlBackEnd && m_qmlBackEnd->contextObject())
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(matLib.isValid());
m_ensureMatLibTimer.stop();
ModelNode mat = Utils3D::selectedMaterial(this);
if (!mat.isValid()) {
const QList <ModelNode> matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &node : matLibNodes) {
if (node.metaInfo().isQtQuick3DMaterial()) {
Utils3D::selectMaterial(node);
break;
}
}
}
}
});
QmlDesignerPlugin::trackWidgetFocusTime(m_stackedWidget, Constants::EVENT_MATERIALEDITOR_TIME); QmlDesignerPlugin::trackWidgetFocusTime(m_stackedWidget, Constants::EVENT_MATERIALEDITOR_TIME);
MaterialEditorDynamicPropertiesProxyModel::registerDeclarativeType(); MaterialEditorDynamicPropertiesProxyModel::registerDeclarativeType();
@@ -769,14 +745,10 @@ void MaterialEditorView::modelAttached(Model *model)
m_hasQuick3DImport = model->hasImport("QtQuick3D"); m_hasQuick3DImport = model->hasImport("QtQuick3D");
m_hasMaterialRoot = rootModelNode().metaInfo().isQtQuick3DMaterial(); m_hasMaterialRoot = rootModelNode().metaInfo().isQtQuick3DMaterial();
if (m_hasMaterialRoot) { if (m_hasMaterialRoot)
m_selectedMaterial = rootModelNode(); m_selectedMaterial = rootModelNode();
} else if (m_hasQuick3DImport) { else if (m_hasQuick3DImport)
// Creating the material library node on model attach causes errors as long as the type
// information is not complete yet, so we keep checking until type info is complete.
m_ensureMatLibTimer.start(500);
m_selectedMaterial = Utils3D::selectedMaterial(this); m_selectedMaterial = Utils3D::selectedMaterial(this);
}
if (!m_setupCompleted) { if (!m_setupCompleted) {
reloadQml(); reloadQml();
@@ -1028,9 +1000,6 @@ void MaterialEditorView::importsChanged([[maybe_unused]] const Imports &addedImp
if (m_qmlBackEnd) if (m_qmlBackEnd)
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
if (m_hasQuick3DImport)
m_ensureMatLibTimer.start(500);
resetView(); resetView();
} }

View File

@@ -10,7 +10,6 @@
#include <QHash> #include <QHash>
#include <QPointer> #include <QPointer>
#include <QSize> #include <QSize>
#include <QTimer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QShortcut; class QShortcut;
@@ -132,7 +131,6 @@ private:
void asyncResetView(); void asyncResetView();
ModelNode m_selectedMaterial; ModelNode m_selectedMaterial;
QTimer m_ensureMatLibTimer;
QShortcut *m_updateShortcut = nullptr; QShortcut *m_updateShortcut = nullptr;
int m_timerId = 0; int m_timerId = 0;
QStackedWidget *m_stackedWidget = nullptr; QStackedWidget *m_stackedWidget = nullptr;

View File

@@ -67,30 +67,6 @@ TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache,
m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F12), m_stackedWidget); m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F12), m_stackedWidget);
connect(m_updateShortcut, &QShortcut::activated, this, &TextureEditorView::reloadQml); connect(m_updateShortcut, &QShortcut::activated, this, &TextureEditorView::reloadQml);
m_ensureMatLibTimer.callOnTimeout([this] {
if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation()
&& model()->rewriterView()->errors().isEmpty()) {
DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument();
if (doc && !doc->inFileComponentModelActive())
Utils3D::ensureMaterialLibraryNode(this);
ModelNode matLib = Utils3D::materialLibraryNode(this);
if (m_qmlBackEnd && m_qmlBackEnd->contextObject())
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(matLib.isValid());
m_ensureMatLibTimer.stop();
ModelNode tex = Utils3D::selectedTexture(this);
if (!tex.isValid()) {
const QList <ModelNode> matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &node : matLibNodes) {
if (node.metaInfo().isQtQuick3DTexture()) {
Utils3D::selectTexture(node);
break;
}
}
}
}
});
m_stackedWidget->setStyleSheet(Theme::replaceCssColors( m_stackedWidget->setStyleSheet(Theme::replaceCssColors(
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")))); QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
m_stackedWidget->setMinimumWidth(250); m_stackedWidget->setMinimumWidth(250);
@@ -619,7 +595,6 @@ void TextureEditorView::modelAttached(Model *model)
} else if (m_hasQuick3DImport) { } else if (m_hasQuick3DImport) {
// Creating the material library node on model attach causes errors as long as the type // Creating the material library node on model attach causes errors as long as the type
// information is not complete yet, so we keep checking until type info is complete. // information is not complete yet, so we keep checking until type info is complete.
m_ensureMatLibTimer.start(500);
m_selectedTexture = Utils3D::selectedTexture(this); m_selectedTexture = Utils3D::selectedTexture(this);
} }
@@ -896,9 +871,6 @@ void TextureEditorView::importsChanged([[maybe_unused]] const Imports &addedImpo
m_hasQuick3DImport = model()->hasImport("QtQuick3D"); m_hasQuick3DImport = model()->hasImport("QtQuick3D");
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
if (m_hasQuick3DImport)
m_ensureMatLibTimer.start(500);
resetView(); resetView();
} }

View File

@@ -9,7 +9,6 @@
#include <QHash> #include <QHash>
#include <QPointer> #include <QPointer>
#include <QTimer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QShortcut; class QShortcut;
@@ -119,7 +118,6 @@ private:
AsynchronousImageCache &m_imageCache; AsynchronousImageCache &m_imageCache;
ModelNode m_selectedTexture; ModelNode m_selectedTexture;
QTimer m_ensureMatLibTimer;
QShortcut *m_updateShortcut = nullptr; QShortcut *m_updateShortcut = nullptr;
int m_timerId = 0; int m_timerId = 0;
QStackedWidget *m_stackedWidget = nullptr; QStackedWidget *m_stackedWidget = nullptr;