Files
qt-creator/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
Miikka Heikkinen c78c4817cd QmlDesigner: Fix asset drag to material browser
Drag now correctly accepts only assets that can be used as textures.

"selected_texture_changed" custom notification was used in two
semantically slightly different cases, both to indicate selected
texture had changed and that selection should change, which was little
confusing. Split the two cases to separate custom notifications to
clarify the situation and allow "select_texture" to be handled in
material browser even if it sent it. This fixes the issue of newly
added texture not getting selected after drag, because creation was
done by material browser view.

Similar issue was fixed with "selected_material_changed" as well.

Also fixed a couple of cases of drag not being properly ended.

Change-Id: Ie1cae01ef13b687d9e611ac1c91443688001fe49
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
2023-03-07 09:30:08 +00:00

706 lines
27 KiB
C++

// 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
#include "materialbrowserview.h"
#include "bindingproperty.h"
#include "createtexture.h"
#include "materialbrowsermodel.h"
#include "materialbrowsertexturesmodel.h"
#include "materialbrowserwidget.h"
#include "nodeabstractproperty.h"
#include "nodemetainfo.h"
#include "qmlobjectnode.h"
#include "variantproperty.h"
#include <designmodecontext.h>
#include <nodeinstanceview.h>
#include <nodelistproperty.h>
#include <qmldesignerconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickItem>
#include <QQuickView>
#include <QRegularExpression>
#include <QTimer>
namespace QmlDesigner {
static QString propertyEditorResourcesPath()
{
#ifdef SHARE_QML_PATH
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
#endif
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
}
MaterialBrowserView::MaterialBrowserView(AsynchronousImageCache &imageCache,
ExternalDependenciesInterface &externalDependencies)
: AbstractView{externalDependencies}
, m_imageCache(imageCache)
{
m_previewTimer.setSingleShot(true);
connect(&m_previewTimer, &QTimer::timeout, this, &MaterialBrowserView::requestPreviews);
}
MaterialBrowserView::~MaterialBrowserView()
{}
bool MaterialBrowserView::hasWidget() const
{
return true;
}
WidgetInfo MaterialBrowserView::widgetInfo()
{
if (m_widget.isNull()) {
m_widget = new MaterialBrowserWidget(m_imageCache, this);
auto matEditorContext = new Internal::MaterialBrowserContext(m_widget.data());
Core::ICore::addContextObject(matEditorContext);
// custom notifications below are sent to the MaterialEditor
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
connect(matBrowserModel, &MaterialBrowserModel::selectedIndexChanged, this, [&] (int idx) {
ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx);
emitCustomNotification("selected_material_changed", {matNode}, {});
});
connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this,
[&] (const ModelNode &material, bool add) {
emitCustomNotification("apply_to_selected_triggered", {material}, {add});
});
connect(matBrowserModel, &MaterialBrowserModel::renameMaterialTriggered, this,
[&] (const ModelNode &material, const QString &newName) {
emitCustomNotification("rename_material", {material}, {newName});
});
connect(matBrowserModel, &MaterialBrowserModel::addNewMaterialTriggered, this, [&] {
emitCustomNotification("add_new_material");
});
connect(matBrowserModel, &MaterialBrowserModel::duplicateMaterialTriggered, this,
[&] (const ModelNode &material) {
emitCustomNotification("duplicate_material", {material});
});
connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this,
[&] (const ModelNode &material,
const QList<QmlDesigner::MaterialBrowserModel::PropertyCopyData> &propDatas,
bool all) {
QmlObjectNode mat(material);
executeInTransaction(__FUNCTION__, [&] {
if (all) { // all material properties copied
// remove current properties
PropertyNameList propNames;
if (mat.isInBaseState()) {
const QList<AbstractProperty> baseProps = material.properties();
for (const auto &baseProp : baseProps) {
if (!baseProp.isDynamic())
propNames.append(baseProp.name());
}
} else {
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
if (changes.isValid()) {
const QList<AbstractProperty> changedProps = changes.targetProperties();
for (const auto &changedProp : changedProps) {
if (!changedProp.isDynamic())
propNames.append(changedProp.name());
}
}
}
for (const PropertyName &propName : std::as_const(propNames)) {
if (propName != "objectName" && propName != "data")
mat.removeProperty(propName);
}
}
// apply pasted properties
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
if (propData.isValid) {
const bool isDynamic = !propData.dynamicTypeName.isEmpty();
const bool isBaseState = currentState().isBaseState();
const bool hasProperty = mat.hasProperty(propData.name);
if (propData.isBinding) {
if (isDynamic && (!hasProperty || isBaseState)) {
mat.modelNode().bindingProperty(propData.name)
.setDynamicTypeNameAndExpression(
propData.dynamicTypeName, propData.value.toString());
continue;
}
mat.setBindingProperty(propData.name, propData.value.toString());
} else {
const bool isRecording = mat.timelineIsActive()
&& mat.currentTimeline().isRecording();
if (isDynamic && (!hasProperty || (isBaseState && !isRecording))) {
mat.modelNode().variantProperty(propData.name)
.setDynamicTypeNameAndValue(
propData.dynamicTypeName, propData.value);
continue;
}
mat.setVariantProperty(propData.name, propData.value);
}
} else {
mat.removeProperty(propData.name);
}
}
});
});
// custom notifications below are sent to the TextureEditor
MaterialBrowserTexturesModel *texturesModel = m_widget->materialBrowserTexturesModel().data();
connect(texturesModel, &MaterialBrowserTexturesModel::selectedIndexChanged, this, [&] (int idx) {
ModelNode texNode = m_widget->materialBrowserTexturesModel()->textureAt(idx);
emitCustomNotification("selected_texture_changed", {texNode});
});
connect(texturesModel, &MaterialBrowserTexturesModel::duplicateTextureTriggered, this,
[&] (const ModelNode &texture) {
emitCustomNotification("duplicate_texture", {texture});
});
connect(texturesModel, &MaterialBrowserTexturesModel::applyToSelectedMaterialTriggered, this,
[&] (const ModelNode &texture) {
if (!m_widget)
return;
const ModelNode material = m_widget->materialBrowserModel()->selectedMaterial();
applyTextureToMaterial({material}, texture);
});
connect(texturesModel, &MaterialBrowserTexturesModel::applyToSelectedModelTriggered, this,
[&] (const ModelNode &texture) {
if (m_selectedModels.size() != 1)
return;
applyTextureToModel3D(m_selectedModels[0], texture);
});
connect(texturesModel, &MaterialBrowserTexturesModel::addNewTextureTriggered, this, [&] {
emitCustomNotification("add_new_texture");
});
connect(texturesModel, &MaterialBrowserTexturesModel::updateSceneEnvStateRequested, this, [&]() {
ModelNode activeSceneEnv = CreateTexture(this).resolveSceneEnv(m_sceneId);
const bool sceneEnvExists = activeSceneEnv.isValid();
m_widget->materialBrowserTexturesModel()->setHasSceneEnv(sceneEnvExists);
});
connect(texturesModel, &MaterialBrowserTexturesModel::updateModelSelectionStateRequested, this, [&]() {
bool hasModel = false;
if (m_selectedModels.size() == 1)
hasModel = getMaterialOfModel(m_selectedModels.at(0)).isValid();
m_widget->materialBrowserTexturesModel()->setHasSingleModelSelection(hasModel);
});
connect(texturesModel, &MaterialBrowserTexturesModel::applyAsLightProbeRequested, this,
[&] (const ModelNode &texture) {
executeInTransaction(__FUNCTION__, [&] {
CreateTexture(this).assignTextureAsLightProbe(texture, m_sceneId);
});
});
}
return createWidgetInfo(m_widget.data(),
"MaterialBrowser",
WidgetInfo::LeftPane,
0,
tr("Material Browser"),
tr("Material Browser view"));
}
void MaterialBrowserView::createTextures(const QStringList &assetPaths)
{
auto *create = new CreateTextures(this, false);
executeInTransaction("MaterialBrowserView::createTextures", [&]() {
create->execute(assetPaths, AddTextureMode::Texture, m_sceneId);
});
create->deleteLater();
}
void MaterialBrowserView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
m_widget->clearSearchFilter();
m_widget->materialBrowserModel()->setHasMaterialLibrary(false);
m_hasQuick3DImport = model->hasImport("QtQuick3D");
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
// before refreshing the model
QTimer::singleShot(1000, model, [this]() {
refreshModel(true);
loadPropertyGroups(); // Needs the delay because it uses metaInfo
});
m_sceneId = model->active3DSceneId();
}
void MaterialBrowserView::refreshModel(bool updateImages)
{
if (!model())
return;
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
QList<ModelNode> materials;
QList<ModelNode> textures;
if (m_hasQuick3DImport && matLib.isValid()) {
const QList <ModelNode> matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &node : matLibNodes) {
if (isMaterial(node))
materials.append(node);
else if (isTexture(node))
textures.append(node);
}
}
m_widget->materialBrowserModel()->setMaterials(materials, m_hasQuick3DImport);
m_widget->materialBrowserTexturesModel()->setTextures(textures);
m_widget->materialBrowserModel()->setHasMaterialLibrary(matLib.isValid());
if (updateImages) {
for (const ModelNode &node : std::as_const(materials))
m_previewRequests.insert(node);
if (!m_previewRequests.isEmpty())
m_previewTimer.start(0);
}
}
bool MaterialBrowserView::isMaterial(const ModelNode &node) const
{
return node.metaInfo().isQtQuick3DMaterial();
}
bool MaterialBrowserView::isTexture(const ModelNode &node) const
{
if (!node.isValid())
return false;
return node.metaInfo().isQtQuick3DTexture();
}
void MaterialBrowserView::modelAboutToBeDetached(Model *model)
{
m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport);
m_widget->materialBrowserModel()->setHasMaterialLibrary(false);
m_widget->clearPreviewCache();
if (m_propertyGroupsLoaded) {
m_propertyGroupsLoaded = false;
m_widget->materialBrowserModel()->unloadPropertyGroups();
}
AbstractView::modelAboutToBeDetached(model);
}
void MaterialBrowserView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
[[maybe_unused]] const QList<ModelNode> &lastSelectedNodeList)
{
m_selectedModels = Utils::filtered(selectedNodeList, [](const ModelNode &node) {
return node.metaInfo().isQtQuick3DModel();
});
m_widget->materialBrowserModel()->setHasModelSelection(!m_selectedModels.isEmpty());
// the logic below selects the material of the first selected model if auto selection is on
if (!m_autoSelectModelMaterial)
return;
if (selectedNodeList.size() > 1 || m_selectedModels.isEmpty())
return;
ModelNode mat = getMaterialOfModel(m_selectedModels.at(0));
if (!mat.isValid())
return;
// if selected object is a model, select its material in the material browser and editor
int idx = m_widget->materialBrowserModel()->materialIndex(mat);
m_widget->materialBrowserModel()->selectMaterial(idx);
}
void MaterialBrowserView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap)
{
if (isMaterial(node))
m_widget->updateMaterialPreview(node, pixmap);
}
void MaterialBrowserView::nodeIdChanged(const ModelNode &node, [[maybe_unused]] const QString &newId,
[[maybe_unused]] const QString &oldId)
{
if (isTexture(node))
m_widget->materialBrowserTexturesModel()->updateTextureSource(node);
}
void MaterialBrowserView::variantPropertiesChanged(const QList<VariantProperty> &propertyList,
[[maybe_unused]] PropertyChangeFlags propertyChange)
{
for (const VariantProperty &property : propertyList) {
ModelNode node(property.parentModelNode());
if (isMaterial(node) && property.name() == "objectName") {
m_widget->materialBrowserModel()->updateMaterialName(node);
} else if (property.name() == "source") {
QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture();
if (isTexture(node))
m_widget->materialBrowserTexturesModel()->updateTextureSource(node);
else if (selectedTex.propertyChangeForCurrentState() == node)
m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex);
}
}
}
void MaterialBrowserView::propertiesRemoved(const QList<AbstractProperty> &propertyList)
{
for (const AbstractProperty &prop : propertyList) {
if (isTexture(prop.parentModelNode()) && prop.name() == "source")
m_widget->materialBrowserTexturesModel()->updateTextureSource(prop.parentModelNode());
}
}
void MaterialBrowserView::nodeReparented(const ModelNode &node,
const NodeAbstractProperty &newPropertyParent,
const NodeAbstractProperty &oldPropertyParent,
[[maybe_unused]] PropertyChangeFlags propertyChange)
{
Q_UNUSED(propertyChange)
if (node.id() == Constants::MATERIAL_LIB_ID)
m_widget->materialBrowserModel()->setHasMaterialLibrary(true);
if (!isMaterial(node) && !isTexture(node))
return;
ModelNode newParentNode = newPropertyParent.parentModelNode();
ModelNode oldParentNode = oldPropertyParent.parentModelNode();
bool added = newParentNode.id() == Constants::MATERIAL_LIB_ID;
bool removed = oldParentNode.id() == Constants::MATERIAL_LIB_ID;
if (!added && !removed)
return;
refreshModel(removed);
if (isMaterial(node)) {
if (added && !m_puppetResetPending) {
// Workaround to fix various material issues all likely caused by QTBUG-103316
resetPuppet();
m_puppetResetPending = true;
}
int idx = m_widget->materialBrowserModel()->materialIndex(node);
m_widget->materialBrowserModel()->selectMaterial(idx);
m_widget->materialBrowserModel()->refreshSearch();
} else { // is texture
int idx = m_widget->materialBrowserTexturesModel()->textureIndex(node);
m_widget->materialBrowserTexturesModel()->selectTexture(idx);
m_widget->materialBrowserTexturesModel()->refreshSearch();
}
}
void MaterialBrowserView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
// removing the material lib node
if (removedNode.id() == Constants::MATERIAL_LIB_ID) {
m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport);
m_widget->materialBrowserModel()->setHasMaterialLibrary(false);
m_widget->clearPreviewCache();
return;
}
// not under the material lib
if (removedNode.parentProperty().parentModelNode().id() != Constants::MATERIAL_LIB_ID)
return;
if (isMaterial(removedNode))
m_widget->materialBrowserModel()->removeMaterial(removedNode);
else if (isTexture(removedNode))
m_widget->materialBrowserTexturesModel()->removeTexture(removedNode);
}
void MaterialBrowserView::nodeRemoved([[maybe_unused]] const ModelNode &removedNode,
const NodeAbstractProperty &parentProperty,
[[maybe_unused]] PropertyChangeFlags propertyChange)
{
if (parentProperty.parentModelNode().id() != Constants::MATERIAL_LIB_ID)
return;
m_widget->materialBrowserModel()->updateSelectedMaterial();
m_widget->materialBrowserTexturesModel()->updateSelectedTexture();
}
void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
{
if (!m_hasQuick3DImport || m_propertyGroupsLoaded || !model())
return;
QString matPropsPath = model()->metaInfo("QtQuick3D.Material").importDirectoryPath()
+ "/designer/propertyGroups.json";
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
}
void MaterialBrowserView::requestPreviews()
{
if (model() && model()->nodeInstanceView()) {
for (const auto &node : std::as_const(m_previewRequests))
model()->nodeInstanceView()->previewImageDataForGenericNode(node, {});
}
m_previewRequests.clear();
}
ModelNode MaterialBrowserView::getMaterialOfModel(const ModelNode &model)
{
QmlObjectNode qmlObjNode(model);
QString matExp = qmlObjNode.expression("materials");
if (matExp.isEmpty())
return {};
const QStringList mats = matExp.remove('[').remove(']').split(',', Qt::SkipEmptyParts);
if (mats.isEmpty())
return {};
for (const auto &matId : mats) {
ModelNode mat = modelNodeForId(matId);
if (mat.isValid())
return mat;
}
return {};
}
void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
[[maybe_unused]] const QList<Import> &removedImports)
{
bool hasQuick3DImport = model()->hasImport("QtQuick3D");
if (hasQuick3DImport == m_hasQuick3DImport)
return;
m_hasQuick3DImport = hasQuick3DImport;
loadPropertyGroups();
// Import change will trigger puppet reset, so we don't want to update previews immediately
refreshModel(false);
}
void MaterialBrowserView::customNotification(const AbstractView *view,
const QString &identifier,
const QList<ModelNode> &nodeList,
const QList<QVariant> &data)
{
if (view == this && identifier != "select_texture")
return;
if (identifier == "select_material") {
int idx = m_widget->materialBrowserModel()->materialIndex(nodeList.first());
if (idx != -1)
m_widget->materialBrowserModel()->selectMaterial(idx);
} else if (identifier == "select_texture") {
int idx = m_widget->materialBrowserTexturesModel()->textureIndex(nodeList.first());
if (idx != -1) {
m_widget->materialBrowserTexturesModel()->selectTexture(idx);
m_widget->materialBrowserTexturesModel()->refreshSearch();
if (!data.isEmpty() && data[0].toBool())
m_widget->focusMaterialSection(false);
}
} else if (identifier == "refresh_material_browser") {
QTimer::singleShot(0, model(), [this]() {
refreshModel(true);
});
} else if (identifier == "delete_selected_material") {
m_widget->deleteSelectedItem();
} else if (identifier == "apply_asset_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") {
applyTextureToMaterial({nodeList.at(0)}, nodeList.at(1));
} else if (identifier == "focus_material_section") {
m_widget->focusMaterialSection(true);
}
}
void MaterialBrowserView::active3DSceneChanged(qint32 sceneId)
{
m_sceneId = sceneId;
}
void MaterialBrowserView::currentStateChanged([[maybe_unused]] const ModelNode &node)
{
m_widget->materialBrowserTexturesModel()->updateAllTexturesSources();
}
void MaterialBrowserView::instancesCompleted(const QVector<ModelNode> &completedNodeList)
{
for (const ModelNode &node : completedNodeList) {
// We use root node completion as indication of puppet reset
if (node.isRootNode()) {
m_puppetResetPending = false;
QTimer::singleShot(1000, this, [this]() {
if (!model() || !model()->nodeInstanceView())
return;
const QList<ModelNode> materials = m_widget->materialBrowserModel()->materials();
for (const ModelNode &node : materials)
m_previewRequests.insert(node);
if (!m_previewRequests.isEmpty())
m_previewTimer.start(0);
});
break;
}
}
}
void MaterialBrowserView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList)
{
for (const auto &nodeProp : propertyList) {
ModelNode node = nodeProp.first;
if (node.metaInfo().isQtQuick3DMaterial())
m_previewRequests.insert(node);
}
if (!m_previewRequests.isEmpty() && !m_previewTimer.isActive()) {
// Updating material browser isn't urgent in e.g. timeline scrubbing case, so have a bit
// of delay to reduce unnecessary rendering
m_previewTimer.start(500);
}
}
void MaterialBrowserView::applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture)
{
if (!texture.isValid() && m_appliedTexturePath.isEmpty())
return;
if (!model3D.isValid() || !model3D.modelNode().metaInfo().isQtQuick3DModel())
return;
BindingProperty matsProp = model3D.bindingProperty("materials");
QList<ModelNode> materials;
if (hasId(matsProp.expression()))
materials.append(modelNodeForId(matsProp.expression()));
else
materials = matsProp.resolveToModelNodeList();
applyTextureToMaterial(materials, texture);
}
void MaterialBrowserView::applyTextureToMaterial(const QList<ModelNode> &materials,
const ModelNode &texture)
{
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);
}
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)
{
m_chooseMatPropsView->rootContext()->setContextProperty("propertiesModel",
QVariant::fromValue(m_textureModels.value(matId)));
}
void MaterialBrowserView::applyTextureToProperty(const QString &matId, const QString &propName)
{
executeInTransaction(__FUNCTION__, [&] {
if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) {
bool import = true;
using namespace ProjectExplorer;
if (Project *proj = ProjectTree::currentProject()) {
Utils::FilePath projDir = proj->projectFilePath().parentDir().pathAppended("content");
if (m_appliedTexturePath.startsWith(projDir.toString()))
import = false;
}
auto texCreator = new CreateTexture(this, import);
ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture);
m_appliedTextureId = tex.id();
m_appliedTexturePath.clear();
texCreator->deleteLater();
}
QTC_ASSERT(!m_appliedTextureId.isEmpty(), return);
QmlObjectNode mat = modelNodeForId(matId);
QTC_ASSERT(mat.isValid(), return);
BindingProperty texProp = mat.bindingProperty(propName.toLatin1());
QTC_ASSERT(texProp.isValid(), return);
mat.setBindingProperty(propName.toLatin1(), m_appliedTextureId);
closeChooseMatPropsView();
});
}
void MaterialBrowserView::closeChooseMatPropsView()
{
m_chooseMatPropsView->close();
}
bool MaterialBrowserView::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Escape) {
if (obj == m_chooseMatPropsView)
m_chooseMatPropsView->close();
}
} else if (event->type() == QEvent::Close) {
if (obj == m_chooseMatPropsView) {
m_appliedTextureId.clear();
m_appliedTexturePath.clear();
m_chooseMatPropsView->deleteLater();
}
}
return AbstractView::eventFilter(obj, event);
}
} // namespace QmlDesigner