summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ghinet <samuel.ghinet@qt.io>2022-11-24 19:23:03 +0200
committerSamuel Ghinet <samuel.ghinet@qt.io>2022-12-02 10:45:41 +0000
commite774aa238be546812754d7ab5497f8603fe51f62 (patch)
treebc3d423196fdafb43a7289f71f34ca7a4161dbf6
parent36c96a0972a4c923e3c6f8045836c336466fee02 (diff)
downloadqt-creator-e774aa238be546812754d7ab5497f8603fe51f62.tar.gz
Add "Add Texture" and "Add Light Probe" actions to Assets Library
When the user right-clicks on an image asset, "Add Light probe" now appears in the context menu. When the user right-clicks one or more image assets, "Add texture" or "Add textures" becomes available. Task-number: QDS-8344 Change-Id: Ia8d8379be2a0a285b33e4a230e08527c18756b47 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml26
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/components/addtexture.h10
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp12
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h1
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp12
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp11
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h4
-rw-r--r--src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp50
-rw-r--r--src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h6
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp117
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h8
12 files changed, 200 insertions, 58 deletions
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml
index 87c0966366..6dedaf7901 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml
@@ -50,8 +50,13 @@ StudioControls.Menu {
function openContextMenuForFile(fileIndex, dirModelIndex, selectedAssetPathsList, onFolderCreated)
{
- var numSelected = selectedAssetPathsList.filter(p => p).length
- deleteFileItem.text = numSelected > 1 ? qsTr("Delete Files") : qsTr("Delete File")
+ if (selectedAssetPathsList.length > 1) {
+ deleteFileItem.text = qsTr("Delete Files")
+ addTexturesItem.text = qsTr("Add Textures")
+ } else {
+ deleteFileItem.text = qsTr("Delete File")
+ addTexturesItem.text = qsTr("Add Texture")
+ }
root.__onFolderCreated = onFolderCreated
root.__selectedAssetPathsList = selectedAssetPathsList
@@ -84,6 +89,23 @@ StudioControls.Menu {
}
StudioControls.MenuItem {
+ id: addTexturesItem
+ text: qsTr("Add Texture")
+ visible: root.__fileIndex && assetsModel.allFilePathsAreImages(root.__selectedAssetPathsList)
+ height: addTexturesItem.visible ? addTexturesItem.implicitHeight : 0
+ onTriggered: rootView.addTextures(root.__selectedAssetPathsList)
+ }
+
+ StudioControls.MenuItem {
+ id: addLightProbes
+ text: qsTr("Add Light Probe")
+ visible: root.__fileIndex && root.__selectedAssetPathsList.length === 1
+ && assetsModel.allFilePathsAreImages(root.__selectedAssetPathsList)
+ height: addLightProbes.visible ? addLightProbes.implicitHeight : 0
+ onTriggered: rootView.addLightProbe(root.__selectedAssetPathsList[0])
+ }
+
+ StudioControls.MenuItem {
id: deleteFileItem
text: qsTr("Delete File")
visible: root.__fileIndex
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 7abed7212d..01fd880263 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -588,6 +588,7 @@ extend_qtc_plugin(QmlDesigner
PUBLIC_INCLUDES components
DEFINES QMLDESIGNERCOMPONENTS_LIBRARY
SOURCES
+ addtexture.h
qmldesignercomponents_global.h
)
diff --git a/src/plugins/qmldesigner/components/addtexture.h b/src/plugins/qmldesigner/components/addtexture.h
new file mode 100644
index 0000000000..8547b4bf84
--- /dev/null
+++ b/src/plugins/qmldesigner/components/addtexture.h
@@ -0,0 +1,10 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+namespace QmlDesigner {
+
+enum class AddTextureMode { Image, Texture, LightProbe };
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
index 83683096e9..864660a147 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
@@ -10,10 +10,11 @@
#include "assetslibrarymodel.h"
-#include <qmldesignerplugin.h>
#include <modelnodeoperations.h>
+#include <qmldesignerplugin.h>
#include <coreplugin/icore.h>
+#include <utils/algorithm.h>
#include <utils/qtcassert.h>
namespace QmlDesigner {
@@ -179,6 +180,15 @@ bool AssetsLibraryModel::deleteFolderRecursively(const QModelIndex &folderIndex)
return ok;
}
+bool AssetsLibraryModel::allFilePathsAreImages(const QStringList &filePaths) const
+{
+ return Utils::allOf(filePaths, [](const QString &path) {
+ const QString suffix = "*." + path.split('.').last().toLower();
+
+ return AssetsLibraryModel::supportedImageSuffixes().contains(suffix);
+ });
+}
+
bool AssetsLibraryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QString path = m_sourceFsModel->filePath(sourceParent);
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
index 82cf2b3ca2..f73d7fb7e3 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
@@ -44,6 +44,7 @@ public:
Q_INVOKABLE bool renameFolder(const QString &folderPath, const QString &newName);
Q_INVOKABLE bool addNewFolder(const QString &folderPath);
Q_INVOKABLE bool deleteFolderRecursively(const QModelIndex &folderIndex);
+ Q_INVOKABLE bool allFilePathsAreImages(const QStringList &filePaths) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const override
{
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp
index 56a536c82e..94e8c6412e 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp
@@ -2,8 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "assetslibraryview.h"
+
#include "assetslibrarywidget.h"
-#include "metainfo.h"
+#include "qmldesignerplugin.h"
#include <asynchronousimagecache.h>
#include <bindingproperty.h>
#include <coreplugin/icore.h>
@@ -22,9 +23,7 @@
#include <sqlitedatabase.h>
#include <synchronousimagecache.h>
#include <utils/algorithm.h>
-#include <qmldesignerplugin.h>
#include <qmlitemnode.h>
-#include <qmldesignerconstants.h>
namespace QmlDesigner {
@@ -60,6 +59,13 @@ WidgetInfo AssetsLibraryView::widgetInfo()
if (m_widget.isNull()) {
m_widget = new AssetsLibraryWidget{imageCacheData()->asynchronousFontImageCache,
imageCacheData()->synchronousFontImageCache};
+
+ connect(m_widget, &AssetsLibraryWidget::addTexturesRequested, this,
+ [&] (const QStringList &filePaths, AddTextureMode mode) {
+ // to MaterialBrowserView
+ emitCustomNotification("add_textures", {}, {"AssetsLibraryView::widgetInfo",
+ filePaths, QVariant::fromValue(mode), false});
+ });
}
return createWidgetInfo(m_widget.data(), "Assets", WidgetInfo::LeftPane, 0, tr("Assets"));
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
index 2858febe9f..05ebb72986 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
@@ -148,6 +148,17 @@ bool AssetsLibraryWidget::qtVersionIsAtLeast6_4() const
return (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0));
}
+
+void AssetsLibraryWidget::addTextures(const QStringList &filePaths)
+{
+ emit addTexturesRequested(filePaths, AddTextureMode::Texture);
+}
+
+void AssetsLibraryWidget::addLightProbe(const QString &filePath)
+{
+ emit addTexturesRequested({filePath}, AddTextureMode::LightProbe);
+}
+
void AssetsLibraryWidget::invalidateThumbnail(const QString &id)
{
m_assetsIconProvider->invalidateThumbnail(id);
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
index 1c19c65a3e..4d8737518a 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
@@ -4,6 +4,7 @@
#pragma once
#include <previewtooltip/previewtooltipbackend.h>
+#include "addtexture.h"
#include "assetslibrarymodel.h"
#include <QFileIconProvider>
@@ -72,6 +73,8 @@ public:
Q_INVOKABLE void openEffectMaker(const QString &filePath);
Q_INVOKABLE bool qtVersionIsAtLeast6_4() const;
Q_INVOKABLE void invalidateThumbnail(const QString &id);
+ Q_INVOKABLE void addTextures(const QStringList &filePaths);
+ Q_INVOKABLE void addLightProbe(const QString &filePaths);
signals:
void itemActivated(const QString &itemName);
@@ -79,6 +82,7 @@ signals:
const QList<QUrl> &complexFilePaths,
const QString &targetDirPath);
void directoryCreated(const QString &path);
+ void addTexturesRequested(const QStringList &filePaths, QmlDesigner::AddTextureMode mode);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
index 5e9f572c7a..58c677039f 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
@@ -55,53 +55,9 @@ WidgetInfo ContentLibraryView::widgetInfo()
m_draggedBundleTexture = tex;
});
connect(m_widget, &ContentLibraryWidget::addTextureRequested, this,
- [&] (const QString texPath, ContentLibraryWidget::AddTextureMode mode) {
- executeInTransaction("ContentLibraryView::widgetInfo", [&] {
- // copy image to project
- AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false);
-
- if (result.status() == AddFilesResult::Failed) {
- Core::AsynchronousMessageBox::warning(tr("Failed to Add Texture"),
- tr("Could not add %1 to project.").arg(texPath));
- return;
- }
-
- if (mode == ContentLibraryWidget::AddTextureMode::Image)
- return;
-
- // create a texture from the image
- ModelNode matLib = materialLibraryNode();
- if (!matLib.isValid())
- return;
-
- NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture");
-
- QString sourceVal = QLatin1String("images/%1").arg(texPath.split('/').last());
- ModelNode texNode = getTextureDefaultInstance(sourceVal);
- if (!texNode.isValid()) {
- texNode = createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
- metaInfo.minorVersion());
- texNode.validId();
- VariantProperty sourceProp = texNode.variantProperty("source");
- sourceProp.setValue(sourceVal);
- matLib.defaultNodeListProperty().reparentHere(texNode);
- }
-
- // assign the texture as scene environment's light probe
- if (mode == ContentLibraryWidget::AddTextureMode::LightProbe && m_sceneId != -1) {
- QmlObjectNode sceneEnv = resolveSceneEnv();
- if (sceneEnv.isValid()) {
- sceneEnv.setBindingProperty("lightProbe", texNode.id());
- sceneEnv.setVariantProperty("backgroundMode",
- QVariant::fromValue(Enumeration("SceneEnvironment",
- "SkyBox")));
- }
- }
- QTimer::singleShot(0, this, [this, texNode]() {
- if (model() && texNode.isValid())
- emitCustomNotification("selected_texture_changed", {texNode});
- });
- });
+ [&] (const QString &texPath, AddTextureMode mode) {
+ emitCustomNotification("add_texture", {}, {"ContentLibraryView::widgetInfo",
+ texPath, QVariant::fromValue(mode), true});
});
connect(m_widget, &ContentLibraryWidget::updateSceneEnvStateRequested,
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
index b6b24c4dec..f6866e0309 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
@@ -3,6 +3,8 @@
#pragma once
+#include "addtexture.h"
+
#include <QFrame>
#include <QPointer>
@@ -55,12 +57,10 @@ public:
Q_INVOKABLE void addLightProbe(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void updateSceneEnvState();
- enum class AddTextureMode { Image, Texture, LightProbe };
-
signals:
void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat);
void bundleTextureDragStarted(QmlDesigner::ContentLibraryTexture *bundleTex);
- void addTextureRequested(const QString texPath, QmlDesigner::ContentLibraryWidget::AddTextureMode mode);
+ void addTextureRequested(const QString texPath, QmlDesigner::AddTextureMode mode);
void updateSceneEnvStateRequested();
void hasQuick3DImportChanged();
void hasMaterialLibraryChanged();
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
index cba8f32199..39b9efe13a 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
@@ -4,9 +4,10 @@
#include "materialbrowserview.h"
#include "bindingproperty.h"
-#include "materialbrowserwidget.h"
#include "materialbrowsermodel.h"
#include "materialbrowsertexturesmodel.h"
+#include "materialbrowserwidget.h"
+#include "modelnodeoperations.h"
#include "nodeabstractproperty.h"
#include "nodemetainfo.h"
#include "qmlobjectnode.h"
@@ -14,11 +15,11 @@
#include <designmodecontext.h>
#include <nodeinstanceview.h>
-#include <nodemetainfo.h>
#include <nodelistproperty.h>
#include <qmldesignerconstants.h>
#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -449,7 +450,119 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
applyTextureToModel3D(nodeList.at(0), nodeList.at(1));
} else if (identifier == "apply_texture_to_material") {
applyTextureToMaterial({nodeList.at(0)}, nodeList.at(1));
+ } else if (identifier == "add_textures") {
+ if (data.size() != 4) {
+ qWarning() << "Wrong number of arguments passed to add_textures: " << data.size();
+ return;
+ }
+
+ QByteArray identifier = data.at(0).toByteArray();
+ QStringList filePaths = data.at(1).toStringList();
+ AddTextureMode mode = data.at(2).value<AddTextureMode>();
+ bool addToProject = data.at(3).toBool();
+
+ executeInTransaction(identifier, [&] {
+ addTextures(filePaths, mode, addToProject);
+ });
+ } else if (identifier == "add_texture") {
+ if (data.size() != 4) {
+ qWarning() << "Wrong number of arguments passed to add_texture: " << data.size();
+ return;
+ }
+
+ QByteArray identifier = data.at(0).toByteArray();
+ QString filePath = data.at(1).toString();
+ AddTextureMode mode = data.at(2).value<AddTextureMode>();
+ bool addToProject = data.at(3).toBool();
+
+ executeInTransaction(identifier, [&] {
+ addOneTexture(filePath, mode, addToProject);
+ });
+ }
+}
+
+void MaterialBrowserView::addOneTexture(const QString &texPath, AddTextureMode mode, bool addToProject)
+{
+ if (addToProject) {
+ // copy image to project
+ AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false);
+
+ if (result.status() == AddFilesResult::Failed) {
+ Core::AsynchronousMessageBox::warning(tr("Failed to Add Texture"),
+ tr("Could not add %1 to project.").arg(texPath));
+ return;
+ }
+ }
+
+ if (mode == AddTextureMode::Image)
+ return;
+
+ // create a texture from the image
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return;
+
+ NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture");
+
+ QString sourceVal = QLatin1String("images/%1").arg(texPath.split('/').last());
+ ModelNode texNode = getTextureDefaultInstance(sourceVal);
+ if (!texNode.isValid()) {
+ texNode = createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
+ metaInfo.minorVersion());
+ texNode.validId();
+ VariantProperty sourceProp = texNode.variantProperty("source");
+ sourceProp.setValue(sourceVal);
+ matLib.defaultNodeListProperty().reparentHere(texNode);
+ }
+
+ // assign the texture as scene environment's light probe
+ if (mode == AddTextureMode::LightProbe && m_sceneId != -1) {
+ QmlObjectNode sceneEnv = resolveSceneEnv();
+ if (sceneEnv.isValid()) {
+ sceneEnv.setBindingProperty("lightProbe", texNode.id());
+ sceneEnv.setVariantProperty("backgroundMode",
+ QVariant::fromValue(Enumeration("SceneEnvironment",
+ "SkyBox")));
+ }
}
+ QTimer::singleShot(0, this, [this, texNode]() {
+ if (model() && texNode.isValid())
+ emitCustomNotification("selected_texture_changed", {texNode});
+ });
+}
+
+void MaterialBrowserView::active3DSceneChanged(qint32 sceneId)
+{
+ m_sceneId = sceneId;
+}
+
+ModelNode MaterialBrowserView::resolveSceneEnv()
+{
+ ModelNode activeSceneEnv;
+
+ if (m_sceneId != -1) {
+ ModelNode activeScene = active3DSceneNode();
+ if (activeScene.isValid()) {
+ QmlObjectNode view3D;
+ if (activeScene.metaInfo().isQtQuick3DView3D()) {
+ view3D = activeScene;
+ } else {
+ ModelNode sceneParent = activeScene.parentProperty().parentModelNode();
+ if (sceneParent.metaInfo().isQtQuick3DView3D())
+ view3D = sceneParent;
+ }
+ if (view3D.isValid())
+ activeSceneEnv = modelNodeForId(view3D.expression("environment"));
+ }
+ }
+
+ return activeSceneEnv;
+}
+
+void MaterialBrowserView::addTextures(const QStringList &filePaths, AddTextureMode mode, bool addToProject)
+{
+ for (const QString &texPath : filePaths)
+ addOneTexture(texPath, mode, addToProject);
}
void MaterialBrowserView::instancesCompleted(const QVector<ModelNode> &completedNodeList)
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
index e8f1160f2f..5b16c0e626 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
@@ -4,6 +4,7 @@
#pragma once
#include "abstractview.h"
+#include "addtexture.h"
#include <QPointer>
#include <QSet>
@@ -51,6 +52,8 @@ public:
void applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture);
void applyTextureToMaterial(const QList<ModelNode> &materials, const ModelNode &texture);
+ void active3DSceneChanged(qint32 sceneId) override;
+
Q_INVOKABLE void updatePropsModel(const QString &matId);
Q_INVOKABLE void applyTextureToProperty(const QString &matId, const QString &propName);
Q_INVOKABLE void closeChooseMatPropsView();
@@ -64,6 +67,10 @@ private:
bool isTexture(const ModelNode &node) const;
void loadPropertyGroups();
void requestPreviews();
+ ModelNode resolveSceneEnv();
+
+ void addOneTexture(const QString &filePath, AddTextureMode mode, bool addToProject);
+ void addTextures(const QStringList &texturePaths, AddTextureMode mode, bool addToProject);
AsynchronousImageCache &m_imageCache;
QPointer<MaterialBrowserWidget> m_widget;
@@ -79,6 +86,7 @@ private:
QPointer<QQuickView> m_chooseMatPropsView;
QHash<QString, QList<PropertyName>> m_textureModels;
QString m_appliedTextureId;
+ int m_sceneId = -1;
};
} // namespace QmlDesigner