From 0b8d2c15cab3a20921d35a695f95d475f37c914f Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 25 Jan 2023 12:48:05 +0200 Subject: [PATCH] QmlDesigner: Allow dragging bundle textures to Navigator Fixes: QDS-8338 Change-Id: Id5d02c4e5ed84f3592c19299b1d33dbe9b5cc486 Reviewed-by: Miikka Heikkinen --- .../qmldesigner/components/createtexture.h | 6 +- .../materialbrowser/materialbrowserview.cpp | 104 +++++++++++------- .../materialbrowser/materialbrowserview.h | 4 +- .../components/navigator/nameitemdelegate.cpp | 15 ++- .../navigator/navigatortreemodel.cpp | 6 + .../components/navigator/navigatorview.cpp | 3 + .../propertyeditor/propertyeditorvalue.cpp | 1 + 7 files changed, 90 insertions(+), 49 deletions(-) diff --git a/src/plugins/qmldesigner/components/createtexture.h b/src/plugins/qmldesigner/components/createtexture.h index a919435f9a0..6a0280ac06b 100644 --- a/src/plugins/qmldesigner/components/createtexture.h +++ b/src/plugins/qmldesigner/components/createtexture.h @@ -5,14 +5,18 @@ #include +#include + namespace QmlDesigner { class AbstractView; enum class AddTextureMode { Image, Texture, LightProbe }; -class CreateTexture +class CreateTexture : public QObject { + Q_OBJECT + public: CreateTexture(AbstractView *view, bool importFiles = false); ModelNode execute(const QString &filePath, AddTextureMode mode, int sceneId = -1); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 79907ee9a4e..5c01dff8411 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -483,7 +483,7 @@ void MaterialBrowserView::importsChanged([[maybe_unused]] const QList &a void MaterialBrowserView::customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, - [[maybe_unused]] const QList &data) + const QList &data) { if (view == this) return; @@ -504,6 +504,9 @@ void MaterialBrowserView::customNotification(const AbstractView *view, }); } else if (identifier == "delete_selected_material") { m_widget->deleteSelectedItem(); + } else if (identifier == "apply_bundle_texture_to_model3D") { + m_appliedTexturePath = data.at(0).toString(); + applyTextureToModel3D(nodeList.at(0)); } else if (identifier == "apply_texture_to_model3D") { applyTextureToModel3D(nodeList.at(0), nodeList.at(1)); } else if (identifier == "apply_texture_to_material") { @@ -557,7 +560,10 @@ void MaterialBrowserView::instancePropertyChanged(const QList &materials, const ModelNode &texture) { - if (materials.size() > 0) { + if (materials.isEmpty()) + return; + + if (texture.isValid()) m_appliedTextureId = texture.id(); - m_textureModels.clear(); - QStringList materialsModel; - for (const ModelNode &mat : std::as_const(materials)) { - QString matName = mat.variantProperty("objectName").value().toString(); - materialsModel.append(QLatin1String("%1 (%2)").arg(matName, mat.id())); - QList texProps; - for (const PropertyMetaInfo &p : mat.metaInfo().properties()) { - if (p.propertyType().isQtQuick3DTexture()) - texProps.append(p.name()); - } - m_textureModels.insert(mat.id(), texProps); + + m_textureModels.clear(); + QStringList materialsModel; + for (const ModelNode &mat : std::as_const(materials)) { + QString matName = mat.variantProperty("objectName").value().toString(); + materialsModel.append(QLatin1String("%1 (%2)").arg(matName, mat.id())); + QList texProps; + for (const PropertyMetaInfo &p : mat.metaInfo().properties()) { + if (p.propertyType().isQtQuick3DTexture()) + texProps.append(p.name()); } - - QString path = MaterialBrowserWidget::qmlSourcesPath() + "/ChooseMaterialProperty.qml"; - - m_chooseMatPropsView = new QQuickView; - m_chooseMatPropsView->setTitle(tr("Select a material property")); - m_chooseMatPropsView->setResizeMode(QQuickView::SizeRootObjectToView); - m_chooseMatPropsView->setMinimumSize({150, 100}); - m_chooseMatPropsView->setMaximumSize({600, 400}); - m_chooseMatPropsView->setWidth(450); - m_chooseMatPropsView->setHeight(300); - m_chooseMatPropsView->setFlags(Qt::Widget); - m_chooseMatPropsView->setModality(Qt::ApplicationModal); - m_chooseMatPropsView->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); - m_chooseMatPropsView->rootContext()->setContextProperties({ - {"rootView", QVariant::fromValue(this)}, - {"materialsModel", QVariant::fromValue(materialsModel)}, - {"propertiesModel", QVariant::fromValue(m_textureModels.value(materials.at(0).id()))}, - }); - m_chooseMatPropsView->setSource(QUrl::fromLocalFile(path)); - m_chooseMatPropsView->installEventFilter(this); - m_chooseMatPropsView->show(); + m_textureModels.insert(mat.id(), texProps); } + + QString path = MaterialBrowserWidget::qmlSourcesPath() + "/ChooseMaterialProperty.qml"; + + m_chooseMatPropsView = new QQuickView; + m_chooseMatPropsView->setTitle(tr("Select a material property")); + m_chooseMatPropsView->setResizeMode(QQuickView::SizeRootObjectToView); + m_chooseMatPropsView->setMinimumSize({150, 100}); + m_chooseMatPropsView->setMaximumSize({600, 400}); + m_chooseMatPropsView->setWidth(450); + m_chooseMatPropsView->setHeight(300); + m_chooseMatPropsView->setFlags(Qt::Widget); + m_chooseMatPropsView->setModality(Qt::ApplicationModal); + m_chooseMatPropsView->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); + m_chooseMatPropsView->rootContext()->setContextProperties({ + {"rootView", QVariant::fromValue(this)}, + {"materialsModel", QVariant::fromValue(materialsModel)}, + {"propertiesModel", QVariant::fromValue(m_textureModels.value(materials.at(0).id()))}, + }); + m_chooseMatPropsView->setSource(QUrl::fromLocalFile(path)); + m_chooseMatPropsView->installEventFilter(this); + m_chooseMatPropsView->show(); } void MaterialBrowserView::updatePropsModel(const QString &matId) @@ -619,17 +628,27 @@ void MaterialBrowserView::updatePropsModel(const QString &matId) void MaterialBrowserView::applyTextureToProperty(const QString &matId, const QString &propName) { - QTC_ASSERT(!m_appliedTextureId.isEmpty(), return); + executeInTransaction(__FUNCTION__, [&] { + if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) { + auto texCreator = new CreateTexture(this, true); + ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture); + m_appliedTextureId = tex.id(); + m_appliedTexturePath.clear(); + texCreator->deleteLater(); + } - QmlObjectNode mat = modelNodeForId(matId); - QTC_ASSERT(mat.isValid(), return); + QTC_ASSERT(!m_appliedTextureId.isEmpty(), return); - BindingProperty texProp = mat.bindingProperty(propName.toLatin1()); - QTC_ASSERT(texProp.isValid(), return); + QmlObjectNode mat = modelNodeForId(matId); + QTC_ASSERT(mat.isValid(), return); - mat.setBindingProperty(propName.toLatin1(), m_appliedTextureId); + BindingProperty texProp = mat.bindingProperty(propName.toLatin1()); + QTC_ASSERT(texProp.isValid(), return); - closeChooseMatPropsView(); + mat.setBindingProperty(propName.toLatin1(), m_appliedTextureId); + + closeChooseMatPropsView(); + }); } void MaterialBrowserView::closeChooseMatPropsView() @@ -648,6 +667,7 @@ bool MaterialBrowserView::eventFilter(QObject *obj, QEvent *event) } else if (event->type() == QEvent::Close) { if (obj == m_chooseMatPropsView) { m_appliedTextureId.clear(); + m_appliedTexturePath.clear(); m_chooseMatPropsView->deleteLater(); } } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 0d2ec42af0d..398269a95fe 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -4,7 +4,6 @@ #pragma once #include "abstractview.h" -#include "createtexture.h" #include #include @@ -53,7 +52,7 @@ public: void active3DSceneChanged(qint32 sceneId) override; void currentStateChanged(const ModelNode &node) override; - void applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture); + void applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture = {}); void applyTextureToMaterial(const QList &materials, const ModelNode &texture); @@ -87,6 +86,7 @@ private: QPointer m_chooseMatPropsView; QHash> m_textureModels; QString m_appliedTextureId; + QString m_appliedTexturePath; // defers texture creation until dialog apply int m_sceneId = -1; }; diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index 65822094394..b60164dd30f 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -216,17 +217,23 @@ void NameItemDelegate::paint(QPainter *painter, if (widget && !widget->dragType().isEmpty()) { QByteArray dragType = widget->dragType(); const NodeMetaInfo metaInfo = node.metaInfo(); - const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType); - ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true); - if (!filter->propertyList.isEmpty()) { + bool validDrop = false; + if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) { + validDrop = metaInfo.isQtQuick3DModel(); + } else { + const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType); + ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true); + validDrop = !filter->propertyList.isEmpty(); + delete filter; + } + if (validDrop) { painter->setOpacity(0.5); painter->fillRect(styleOption.rect.adjusted(0, delegateMargin, 0, -delegateMargin), Theme::getColor(Theme::Color::DSnavigatorDropIndicatorBackground)); painter->setOpacity(1.0); painter->setPen(Theme::getColor(Theme::Color::DSnavigatorTextSelected)); } - delete filter; } } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 088399bcb06..024c5551703 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -453,6 +453,7 @@ QStringList NavigatorTreeModel::mimeTypes() const Constants::MIME_TYPE_ITEM_LIBRARY_INFO, Constants::MIME_TYPE_TEXTURE, Constants::MIME_TYPE_MATERIAL, + Constants::MIME_TYPE_BUNDLE_TEXTURE, Constants::MIME_TYPE_BUNDLE_MATERIAL, Constants::MIME_TYPE_ASSETS}); @@ -553,6 +554,11 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, handleTextureDrop(mimeData, dropModelIndex); } else if (mimeData->hasFormat(Constants::MIME_TYPE_MATERIAL)) { handleMaterialDrop(mimeData, dropModelIndex); + } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { + QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE); + ModelNode targetNode(modelNodeForIndex(dropModelIndex)); + if (targetNode.metaInfo().isQtQuick3DModel()) + m_view->emitCustomNotification("apply_bundle_texture_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.isValid()) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 7096564c96c..32f45fc6003 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -267,6 +267,9 @@ void NavigatorView::dragStarted(QMimeData *mimeData) m_widget->setDragType(matNode.metaInfo().typeName()); m_widget->update(); + } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { + m_widget->setDragType(Constants::MIME_TYPE_BUNDLE_TEXTURE); + m_widget->update(); } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { QByteArray data = mimeData->data(Constants::MIME_TYPE_BUNDLE_MATERIAL); QDataStream stream(data); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index ef987c9efd2..60be1747335 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -511,6 +511,7 @@ void PropertyEditorValue::commitDrop(const QString &dropData) bool needsImport = !imagePath.isChildOf(QmlDesigner::DocumentManager::currentResourcePath()); auto texCreator = new QmlDesigner::CreateTexture(m_modelNode.view(), needsImport); texture = texCreator->execute(imagePath.toString(), QmlDesigner::AddTextureMode::Texture); + texCreator->deleteLater(); } // assign the texture to the property