forked from qt-creator/qt-creator
QmlDesigner: Avoid duplicate bundle material instance creation
When apply a material from the material bundle directly to a model in the 3D scene, check frist if there is an existing material that has no properties set, if so apply it instead of creating a new instance. Also few tweaks. Change-Id: I4ddadfd84442164b671645af5e4f5d9e8dcb7cb0 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -129,70 +129,23 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
||||
MaterialBrowserBundleModel *matBrowserBundleModel = m_widget->materialBrowserBundleModel().data();
|
||||
|
||||
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::applyToSelectedTriggered, this,
|
||||
[&] (BundleMaterial *material, bool add) {
|
||||
[&] (BundleMaterial *bundleMat, bool add) {
|
||||
if (!m_selectedModel.isValid())
|
||||
return;
|
||||
|
||||
m_bundleMaterialDropTarget = m_selectedModel;
|
||||
m_bundleMaterialAddToSelected = add;
|
||||
m_widget->materialBrowserBundleModel()->addMaterial(material);
|
||||
|
||||
ModelNode defaultMat = getBundleMaterialDefaultInstance(bundleMat->type());
|
||||
if (defaultMat.isValid())
|
||||
applyBundleMaterialToDropTarget(defaultMat);
|
||||
else
|
||||
m_widget->materialBrowserBundleModel()->addMaterial(bundleMat);
|
||||
});
|
||||
|
||||
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::addBundleMaterialToProjectRequested, this,
|
||||
[&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
|
||||
ModelNode matLib = materialLibraryNode();
|
||||
if (!matLib.isValid())
|
||||
return;
|
||||
|
||||
executeInTransaction("MaterialBrowserView::widgetInfo", [&] {
|
||||
ModelNode newMatNode = createModelNode(metaInfo.typeName(), metaInfo.majorVersion(),
|
||||
metaInfo.minorVersion());
|
||||
matLib.defaultNodeListProperty().reparentHere(newMatNode);
|
||||
|
||||
static QRegularExpression rgx("([A-Z])([a-z]*)");
|
||||
QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed();
|
||||
QString newId = model()->generateIdFromName(newName, "material");
|
||||
newMatNode.setIdWithRefactoring(newId);
|
||||
|
||||
VariantProperty objNameProp = newMatNode.variantProperty("objectName");
|
||||
objNameProp.setValue(newName);
|
||||
|
||||
if (m_bundleMaterialDropTarget.isValid()) {
|
||||
QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
|
||||
if (m_bundleMaterialAddToSelected) {
|
||||
// TODO: unify this logic as it exist elsewhere also
|
||||
auto expToList = [](const QString &exp) {
|
||||
QString copy = exp;
|
||||
copy = copy.remove("[").remove("]");
|
||||
|
||||
QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
|
||||
for (QString &str : tmp)
|
||||
str = str.trimmed();
|
||||
|
||||
return tmp;
|
||||
};
|
||||
|
||||
auto listToExp = [](QStringList &stringList) {
|
||||
if (stringList.size() > 1)
|
||||
return QString("[" + stringList.join(",") + "]");
|
||||
|
||||
if (stringList.size() == 1)
|
||||
return stringList.first();
|
||||
|
||||
return QString();
|
||||
};
|
||||
QStringList matList = expToList(qmlObjNode.expression("materials"));
|
||||
matList.append(newMatNode.id());
|
||||
QString updatedExp = listToExp(matList);
|
||||
qmlObjNode.setBindingProperty("materials", updatedExp);
|
||||
} else {
|
||||
qmlObjNode.setBindingProperty("materials", newMatNode.id());
|
||||
}
|
||||
m_bundleMaterialDropTarget = {};
|
||||
}
|
||||
|
||||
m_bundleMaterialAddToSelected = false;
|
||||
});
|
||||
applyBundleMaterialToDropTarget({}, metaInfo);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,6 +156,72 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
||||
tr("Material Browser"));
|
||||
}
|
||||
|
||||
void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundleMat,
|
||||
const NodeMetaInfo &metaInfo)
|
||||
{
|
||||
if (!bundleMat.isValid() && !metaInfo.isValid())
|
||||
return;
|
||||
|
||||
ModelNode matLib = materialLibraryNode();
|
||||
if (!matLib.isValid())
|
||||
return;
|
||||
|
||||
executeInTransaction("MaterialBrowserView::applyBundleMaterialToDropTarget", [&] {
|
||||
ModelNode newMatNode;
|
||||
if (metaInfo.isValid()) {
|
||||
newMatNode = createModelNode(metaInfo.typeName(), metaInfo.majorVersion(),
|
||||
metaInfo.minorVersion());
|
||||
matLib.defaultNodeListProperty().reparentHere(newMatNode);
|
||||
|
||||
static QRegularExpression rgx("([A-Z])([a-z]*)");
|
||||
QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed();
|
||||
QString newId = model()->generateIdFromName(newName, "material");
|
||||
newMatNode.setIdWithRefactoring(newId);
|
||||
|
||||
VariantProperty objNameProp = newMatNode.variantProperty("objectName");
|
||||
objNameProp.setValue(newName);
|
||||
} else {
|
||||
newMatNode = bundleMat;
|
||||
}
|
||||
|
||||
if (m_bundleMaterialDropTarget.isValid()) {
|
||||
QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
|
||||
if (m_bundleMaterialAddToSelected) {
|
||||
// TODO: unify this logic as it exist elsewhere also
|
||||
auto expToList = [](const QString &exp) {
|
||||
QString copy = exp;
|
||||
copy = copy.remove("[").remove("]");
|
||||
|
||||
QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
|
||||
for (QString &str : tmp)
|
||||
str = str.trimmed();
|
||||
|
||||
return tmp;
|
||||
};
|
||||
|
||||
auto listToExp = [](QStringList &stringList) {
|
||||
if (stringList.size() > 1)
|
||||
return QString("[" + stringList.join(",") + "]");
|
||||
|
||||
if (stringList.size() == 1)
|
||||
return stringList.first();
|
||||
|
||||
return QString();
|
||||
};
|
||||
QStringList matList = expToList(qmlObjNode.expression("materials"));
|
||||
matList.append(newMatNode.id());
|
||||
QString updatedExp = listToExp(matList);
|
||||
qmlObjNode.setBindingProperty("materials", updatedExp);
|
||||
} else {
|
||||
qmlObjNode.setBindingProperty("materials", newMatNode.id());
|
||||
}
|
||||
|
||||
m_bundleMaterialDropTarget = {};
|
||||
m_bundleMaterialAddToSelected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MaterialBrowserView::modelAttached(Model *model)
|
||||
{
|
||||
AbstractView::modelAttached(model);
|
||||
@@ -382,6 +401,28 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
|
||||
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
|
||||
}
|
||||
|
||||
ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type)
|
||||
{
|
||||
const QList<ModelNode> materials = m_widget->materialBrowserModel()->materials();
|
||||
for (const ModelNode &mat : materials) {
|
||||
if (mat.type() == type) {
|
||||
bool isDefault = true;
|
||||
const QList<AbstractProperty> props = mat.properties();
|
||||
for (const AbstractProperty &prop : props) {
|
||||
if (prop.name() != "objectName") {
|
||||
isDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefault)
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void MaterialBrowserView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports)
|
||||
{
|
||||
Q_UNUSED(addedImports)
|
||||
@@ -420,7 +461,14 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt
|
||||
m_widget->materialBrowserModel()->deleteSelectedMaterial();
|
||||
} else if (identifier == "drop_bundle_material") {
|
||||
m_bundleMaterialDropTarget = nodeList.first();
|
||||
m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial);
|
||||
|
||||
|
||||
ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
|
||||
if (defaultMat.isValid())
|
||||
applyBundleMaterialToDropTarget(defaultMat);
|
||||
else
|
||||
m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial);
|
||||
|
||||
m_draggedBundleMaterial = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user