forked from qt-creator/qt-creator
QmlDesigner: Allow dragging bundle textures to Navigator
Fixes: QDS-8338 Change-Id: Id5d02c4e5ed84f3592c19299b1d33dbe9b5cc486 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -5,14 +5,18 @@
|
||||
|
||||
#include <modelnode.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
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);
|
||||
|
@@ -483,7 +483,7 @@ void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &a
|
||||
void MaterialBrowserView::customNotification(const AbstractView *view,
|
||||
const QString &identifier,
|
||||
const QList<ModelNode> &nodeList,
|
||||
[[maybe_unused]] const QList<QVariant> &data)
|
||||
const QList<QVariant> &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<QPair<ModelNode, P
|
||||
|
||||
void MaterialBrowserView::applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture)
|
||||
{
|
||||
if (!texture.isValid() || !model3D.isValid() || !model3D.modelNode().metaInfo().isQtQuick3DModel())
|
||||
if (!texture.isValid() && m_appliedTexturePath.isEmpty())
|
||||
return;
|
||||
|
||||
if (!model3D.isValid() || !model3D.modelNode().metaInfo().isQtQuick3DModel())
|
||||
return;
|
||||
|
||||
BindingProperty matsProp = model3D.bindingProperty("materials");
|
||||
@@ -573,42 +579,45 @@ void MaterialBrowserView::applyTextureToModel3D(const QmlObjectNode &model3D, co
|
||||
void MaterialBrowserView::applyTextureToMaterial(const QList<ModelNode> &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<PropertyName> 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<PropertyName> 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();
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "abstractview.h"
|
||||
#include "createtexture.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QSet>
|
||||
@@ -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<ModelNode> &materials, const ModelNode &texture);
|
||||
|
||||
|
||||
@@ -87,6 +86,7 @@ private:
|
||||
QPointer<QQuickView> m_chooseMatPropsView;
|
||||
QHash<QString, QList<PropertyName>> m_textureModels;
|
||||
QString m_appliedTextureId;
|
||||
QString m_appliedTexturePath; // defers texture creation until dialog apply
|
||||
int m_sceneId = -1;
|
||||
};
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <metainfo.h>
|
||||
#include <modelnodecontextmenu.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmlobjectnode.h>
|
||||
#include <theme.h>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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())
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user