diff options
9 files changed, 120 insertions, 67 deletions
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 0ea4aa816f..83683096e9 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -42,13 +42,6 @@ void AssetsLibraryModel::createBackendModel() }); } -bool AssetsLibraryModel::isEffectQmlExist(const QString &effectName) -{ - Utils::FilePath effectsResDir = ModelNodeOperations::getEffectsDirectory(); - Utils::FilePath qmlPath = effectsResDir.resolvePath(effectName + "/" + effectName + ".qml"); - return qmlPath.exists(); -} - void AssetsLibraryModel::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, [[maybe_unused]] const QList<int> &roles) { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index b4010497b5..82cf2b3ca2 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -63,8 +63,6 @@ public: static const QStringList &supportedEffectMakerSuffixes(); static const QSet<QString> &supportedSuffixes(); - static bool isEffectQmlExist(const QString &effectName); - signals: void directoryLoaded(const QString &path); void rootPathChanged(); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index c5e32b84c5..97e2716b03 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -2,13 +2,13 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "modelnodeoperations.h" +#include "coreplugin/coreplugintr.h" #include "designmodewidget.h" #include "modelnodecontextmenu_helper.h" #include "addimagesdialog.h" #include "layoutingridlayout.h" #include "findimplementation.h" - #include "addsignalhandlerdialog.h" #include <bindingproperty.h> @@ -1704,6 +1704,33 @@ QString getEffectIcon(const QString &effectPath) return effectResPath.exists() ? QString("effectExported") : QString("effectClass"); } +bool useLayerEffect() +{ + QSettings *settings = Core::ICore::settings(); + const QString layerEffectEntry = "QML/Designer/UseLayerEffect"; + + return settings->value(layerEffectEntry, true).toBool(); +} + +bool validateEffect(const QString &effectPath) +{ + const QString effectName = QFileInfo(effectPath).baseName(); + Utils::FilePath effectsResDir = ModelNodeOperations::getEffectsDirectory(); + Utils::FilePath qmlPath = effectsResDir.resolvePath(effectName + "/" + effectName + ".qml"); + if (!qmlPath.exists()) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("Effect %1 not complete").arg(effectName)); + msgBox.setInformativeText(QObject::tr("Do you want to edit %1?").arg(effectName)); + msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + msgBox.setDefaultButton(QMessageBox::Yes); + msgBox.setIcon(QMessageBox::Question); + if (msgBox.exec() == QMessageBox::Yes) + ModelNodeOperations::openEffectMaker(effectName); + return false; + } + return true; +} + } // namespace ModelNodeOperations } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index be238a0439..5dcc20ff91 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -122,6 +122,8 @@ void updateImported3DAsset(const SelectionContext &selectionContext); QMLDESIGNERCORE_EXPORT Utils::FilePath getEffectsDirectory(); void openEffectMaker(const QString &filePath); QString getEffectIcon(const QString &effectPath); +bool useLayerEffect(); +bool validateEffect(const QString &effectPath); // ModelNodePreviewImageOperations QVariant previewImageDataForGenericNode(const ModelNode &modelNode); diff --git a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp index ce27128cb3..b64ce3d100 100644 --- a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp @@ -243,31 +243,14 @@ void DragTool::dropEvent(const QList<QGraphicsItem *> &itemList, QGraphicsSceneD if (!effectPath.isEmpty()) { FormEditorItem *targetContainerFormEditorItem = targetContainerOrRootItem(itemList); if (targetContainerFormEditorItem) { - QmlItemNode parentQmlItemNode = targetContainerFormEditorItem->qmlItemNode(); - QString effectName = QFileInfo(effectPath).baseName(); - - if (!AssetsLibraryModel::isEffectQmlExist(effectName)) { - QMessageBox msgBox; - msgBox.setText("Effect " + effectName + " is empty"); - msgBox.setInformativeText("Do you want to edit " + effectName + "?"); - msgBox.setStandardButtons(QMessageBox::No |QMessageBox::Yes); - msgBox.setDefaultButton(QMessageBox::Yes); - msgBox.setIcon(QMessageBox::Question); - int ret = msgBox.exec(); - switch (ret) { - case QMessageBox::Yes: - ModelNodeOperations::openEffectMaker(effectPath); - break; - default: - break; - } - + if (!ModelNodeOperations::validateEffect(effectPath)) { event->ignore(); return; } - QmlItemNode::createQmlItemNodeForEffect(view(), parentQmlItemNode, effectName); - + bool layerEffect = ModelNodeOperations::useLayerEffect(); + QmlItemNode parentQmlItemNode = targetContainerFormEditorItem->qmlItemNode(); + QmlItemNode::createQmlItemNodeForEffect(view(), parentQmlItemNode, effectPath, layerEffect); view()->setSelectedModelNodes({parentQmlItemNode}); commitTransaction(); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index a407cf129b..66b6f640fa 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -146,16 +146,25 @@ static bool isInLayoutable(NodeAbstractProperty &parentProperty) static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty, const ModelNode &modelNode) { try { + if (parentProperty.parentModelNode().type().startsWith("Effects.")) + return; + if (!modelNode.hasParentProperty() || parentProperty != modelNode.parentProperty()) { if (isInLayoutable(parentProperty)) { removePosition(modelNode); parentProperty.reparentHere(modelNode); } else { if (QmlItemNode::isValidQmlItemNode(modelNode)) { - QPointF scenePosition = QmlItemNode(modelNode).instanceScenePosition(); - parentProperty.reparentHere(modelNode); - if (!scenePosition.isNull()) - setScenePosition(modelNode, scenePosition); + if (modelNode.hasParentProperty() && modelNode.parentProperty().name() == "layer.effect") { + parentProperty = parentProperty.parentModelNode().nodeAbstractProperty("layer.effect"); + QmlItemNode::placeEffectNode(parentProperty, modelNode, true); + } else { + QPointF scenePosition = QmlItemNode(modelNode).instanceScenePosition(); + parentProperty.reparentHere(modelNode); + if (!scenePosition.isNull()) + setScenePosition(modelNode, scenePosition); + } + } else { parentProperty.reparentHere(modelNode); } @@ -597,6 +606,9 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, } else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { currNode = handleItemLibraryTexture3dDrop(assetPath, targetProperty, rowModelIndex, moveNodesAfter); + } else if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) { + currNode = handleItemLibraryEffectDrop(assetPath, rowModelIndex); + moveNodesAfter = false; } if (currNode.isValid()) @@ -1003,6 +1015,24 @@ ModelNode NavigatorTreeModel::handleItemLibraryTexture3dDrop(const QString &tex3 return newModelNode; } +ModelNode NavigatorTreeModel::handleItemLibraryEffectDrop(const QString &effectPath, const QModelIndex &rowModelIndex) +{ + QTC_ASSERT(m_view, return {}); + + ModelNode targetNode(modelNodeForIndex(rowModelIndex)); + ModelNode newModelNode; + + if (targetNode.hasParentProperty() && targetNode.parentProperty().name() == "layer.effect") + return newModelNode; + + if (ModelNodeOperations::validateEffect(effectPath)) { + bool layerEffect = ModelNodeOperations::useLayerEffect(); + newModelNode = QmlItemNode::createQmlItemNodeForEffect(m_view, targetNode, effectPath, layerEffect); + } + + return newModelNode; +} + bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode, const NodeAbstractProperty &targetProp, const QString &imagePath, diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h index 85741c0ff0..e67bcc8849 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h @@ -106,6 +106,7 @@ private: const QModelIndex &rowModelIndex); ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath, NodeAbstractProperty targetProperty, const QModelIndex &rowModelIndex, bool &outMoveNodesAfter); + ModelNode handleItemLibraryEffectDrop(const QString &effectPath, const QModelIndex &rowModelIndex); bool dropAsImage3dTexture(const ModelNode &targetNode, const NodeAbstractProperty &targetProp, const QString &imagePath, ModelNode &newNode, bool &outMoveNodesAfter); ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath); diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 61c38dd504..a0d1210444 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -60,9 +60,19 @@ public: const QPointF &position, NodeAbstractProperty parentproperty, bool executeInTransaction = true); - static void createQmlItemNodeForEffect(AbstractView *view, - const QmlItemNode &parentNode, - const QString &effectName); + + static QmlItemNode createQmlItemNodeForEffect(AbstractView *view, + QmlItemNode parentQmlItemNode, + const QString &effectPath, + bool isLayerEffect); + static QmlItemNode createQmlItemNodeForEffect(AbstractView *view, + NodeAbstractProperty parentProperty, + const QString &effectPath, + bool isLayerEffect); + static void placeEffectNode(NodeAbstractProperty &parentProperty, + const QmlItemNode &effectNode, + bool isLayerEffect); + QList<QmlItemNode> children() const; QList<QmlObjectNode> resources() const; QList<QmlObjectNode> allDirectSubNodes() const; diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index 46618eed50..4570e5fc43 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -158,24 +158,31 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view, return newQmlItemNode; } -static bool useLayerEffect() +QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, + QmlItemNode parentQmlItemNode, + const QString &effectPath, + bool isLayerEffect) { - QSettings *settings = Core::ICore::settings(); - const QString layerEffectEntry = "QML/Designer/UseLayerEffect"; + if (!parentQmlItemNode.isValid()) + parentQmlItemNode = QmlItemNode(view->rootModelNode()); - return settings->value(layerEffectEntry, true).toBool(); + NodeAbstractProperty parentProperty = isLayerEffect + ? parentQmlItemNode.nodeAbstractProperty("layer.effect") + : parentQmlItemNode.defaultNodeAbstractProperty(); + + return createQmlItemNodeForEffect(view, parentProperty, effectPath, isLayerEffect); } -void QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, - const QmlItemNode &parentNode, - const QString &effectName) +QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, + NodeAbstractProperty parentProperty, + const QString &effectPath, + bool isLayerEffect) { QmlItemNode newQmlItemNode; - view->executeInTransaction("QmlItemNode::createQmlItemNodeForEffect", [=, &newQmlItemNode, &parentNode]() { - const bool layerEffect = useLayerEffect(); - - QmlDesigner::Import import = Import::createLibraryImport("Effects." + effectName, "1.0"); + auto createEffectNode = [=, &newQmlItemNode, &parentProperty]() { + const QString effectName = QFileInfo(effectPath).baseName(); + Import import = Import::createLibraryImport("Effects." + effectName, "1.0"); try { if (!view->model()->hasImport(import, true, true)) view->model()->changeImports({import}, {}); @@ -185,26 +192,28 @@ void QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, TypeName type(effectName.toUtf8()); newQmlItemNode = QmlItemNode(view->createModelNode(type, -1, -1)); - NodeAbstractProperty parentProperty = layerEffect - ? parentNode.nodeAbstractProperty("layer.effect") - : parentNode.defaultNodeAbstractProperty(); - - if (layerEffect) { - if (!parentProperty .isEmpty()) { //already contains a node - ModelNode oldEffect = parentProperty.toNodeProperty().modelNode(); - QmlObjectNode(oldEffect).destroy(); - } - } - parentProperty.reparentHere(newQmlItemNode); + placeEffectNode(parentProperty, newQmlItemNode, isLayerEffect); + }; - if (!layerEffect) { - newQmlItemNode.modelNode().bindingProperty("source").setExpression("parent"); - newQmlItemNode.modelNode().bindingProperty("anchors.fill").setExpression("parent"); - } else { - parentNode.modelNode().variantProperty("layer.enabled").setValue(true); - } - }); + view->executeInTransaction("QmlItemNode::createQmlItemNodeFromEffect", createEffectNode); + return newQmlItemNode; +} + +void QmlItemNode::placeEffectNode(NodeAbstractProperty &parentProperty, const QmlItemNode &effectNode, bool isLayerEffect) { + if (isLayerEffect && !parentProperty.isEmpty()) { // already contains a node + ModelNode oldEffect = parentProperty.toNodeProperty().modelNode(); + QmlObjectNode(oldEffect).destroy(); + } + + parentProperty.reparentHere(effectNode); + + if (!isLayerEffect) { + effectNode.modelNode().bindingProperty("source").setExpression("parent"); + effectNode.modelNode().bindingProperty("anchors.fill").setExpression("parent"); + } else { + parentProperty.parentModelNode().variantProperty("layer.enabled").setValue(true); + } } bool QmlItemNode::isValid() const |