forked from qt-creator/qt-creator
QmlDesigner: Implement "duplicate material" feature
Fixes: QDS-7013 Change-Id: I28a11dbd9d6586631c0edcf8003e551917eaac98 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -102,6 +102,12 @@ Item {
|
||||
onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, true)
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Duplicate")
|
||||
enabled: currentMaterial
|
||||
onTriggered: materialBrowserModel.duplicateMaterial(currentMaterialIdx)
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Rename")
|
||||
enabled: currentMaterial
|
||||
@@ -116,7 +122,7 @@ Item {
|
||||
text: qsTr("Delete")
|
||||
enabled: currentMaterial
|
||||
|
||||
onTriggered: materialBrowserModel.deleteMaterial(currentMaterial.materialInternalId)
|
||||
onTriggered: materialBrowserModel.deleteMaterial(currentMaterialIdx)
|
||||
}
|
||||
|
||||
StudioControls.MenuSeparator {}
|
||||
|
@@ -246,11 +246,14 @@ void MaterialBrowserModel::selectMaterial(int idx, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBrowserModel::deleteMaterial(qint32 internalId)
|
||||
void MaterialBrowserModel::duplicateMaterial(int idx)
|
||||
{
|
||||
int idx = m_materialIndexHash.value(internalId);
|
||||
if (isValidIndex(idx))
|
||||
m_materialList[idx].destroy();
|
||||
emit duplicateMaterialTriggered(m_materialList.at(idx));
|
||||
}
|
||||
|
||||
void MaterialBrowserModel::deleteMaterial(int idx)
|
||||
{
|
||||
m_materialList[idx].destroy();
|
||||
}
|
||||
|
||||
void MaterialBrowserModel::renameMaterial(int idx, const QString &newName)
|
||||
|
@@ -68,6 +68,7 @@ public:
|
||||
void resetModel();
|
||||
|
||||
Q_INVOKABLE void selectMaterial(int idx, bool force = false);
|
||||
Q_INVOKABLE void duplicateMaterial(int idx);
|
||||
Q_INVOKABLE void deleteMaterial(int idx);
|
||||
Q_INVOKABLE void renameMaterial(int idx, const QString &newName);
|
||||
Q_INVOKABLE void addNewMaterial();
|
||||
@@ -82,6 +83,7 @@ signals:
|
||||
void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName);
|
||||
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
|
||||
void addNewMaterialTriggered();
|
||||
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
|
||||
|
||||
private:
|
||||
bool isMaterialVisible(int idx) const;
|
||||
|
@@ -54,16 +54,33 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
||||
{
|
||||
if (m_widget.isNull()) {
|
||||
m_widget = new MaterialBrowserWidget;
|
||||
connect(m_widget->materialBrowserModel().data(), SIGNAL(selectedIndexChanged(int)),
|
||||
this, SLOT(handleSelectedMaterialChanged(int)));
|
||||
connect(m_widget->materialBrowserModel().data(),
|
||||
SIGNAL(applyToSelectedTriggered(const QmlDesigner::ModelNode &, bool)),
|
||||
this, SLOT(handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &, bool)));
|
||||
connect(m_widget->materialBrowserModel().data(),
|
||||
SIGNAL(renameMaterialTriggered(const QmlDesigner::ModelNode &, const QString &)),
|
||||
this, SLOT(handleRenameMaterial(const QmlDesigner::ModelNode &, const QString &)));
|
||||
connect(m_widget->materialBrowserModel().data(), SIGNAL(addNewMaterialTriggered()),
|
||||
this, SLOT(handleAddNewMaterial()));
|
||||
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
|
||||
|
||||
// custom notifications below are sent to the MaterialEditor
|
||||
|
||||
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});
|
||||
});
|
||||
}
|
||||
|
||||
return createWidgetInfo(m_widget.data(),
|
||||
@@ -240,29 +257,4 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBrowserView::handleSelectedMaterialChanged(int idx)
|
||||
{
|
||||
ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx);
|
||||
// to MaterialEditor...
|
||||
emitCustomNotification("selected_material_changed", {matNode}, {});
|
||||
}
|
||||
|
||||
void MaterialBrowserView::handleApplyToSelectedTriggered(const ModelNode &material, bool add)
|
||||
{
|
||||
// to MaterialEditor...
|
||||
emitCustomNotification("apply_to_selected_triggered", {material}, {add});
|
||||
}
|
||||
|
||||
void MaterialBrowserView::handleRenameMaterial(const ModelNode &material, const QString &newName)
|
||||
{
|
||||
// to MaterialEditor...
|
||||
emitCustomNotification("rename_material", {material}, {newName});
|
||||
}
|
||||
|
||||
void MaterialBrowserView::handleAddNewMaterial()
|
||||
{
|
||||
// to MaterialEditor...
|
||||
emitCustomNotification("add_new_material");
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -68,12 +68,6 @@ private:
|
||||
QPointer<MaterialBrowserWidget> m_widget;
|
||||
bool m_hasQuick3DImport = false;
|
||||
bool m_autoSelectModelMaterial = false; // TODO: wire this to some action
|
||||
|
||||
private slots:
|
||||
void handleSelectedMaterialChanged(int idx);
|
||||
void handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
|
||||
void handleRenameMaterial(const QmlDesigner::ModelNode &material, const QString &newName);
|
||||
void handleAddNewMaterial();
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -745,6 +745,41 @@ void MaterialEditorView::renameMaterial(ModelNode &material, const QString &newN
|
||||
});
|
||||
}
|
||||
|
||||
void MaterialEditorView::duplicateMaterial(const ModelNode &material)
|
||||
{
|
||||
QTC_ASSERT(material.isValid(), return);
|
||||
|
||||
ensureMaterialLibraryNode();
|
||||
|
||||
TypeName matType = material.type();
|
||||
QmlObjectNode sourceMat(material);
|
||||
|
||||
executeInTransaction(__FUNCTION__, [&] {
|
||||
// create the duplicate material
|
||||
NodeMetaInfo metaInfo = model()->metaInfo(matType);
|
||||
QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion());
|
||||
|
||||
// set name and id
|
||||
QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy";
|
||||
duplicateMat.modelNode().variantProperty("objectName").setValue(newName);
|
||||
duplicateMat.modelNode().setIdWithoutRefactoring(generateIdFromName(newName));
|
||||
|
||||
// sync properties
|
||||
const QList<AbstractProperty> props = material.properties();
|
||||
for (const AbstractProperty &prop : props) {
|
||||
if (prop.name() == "objectName")
|
||||
continue;
|
||||
|
||||
if (prop.isVariantProperty())
|
||||
duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value());
|
||||
else if (prop.isBindingProperty())
|
||||
duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
|
||||
}
|
||||
|
||||
m_materialLibrary.defaultNodeListProperty().reparentHere(duplicateMat);
|
||||
});
|
||||
}
|
||||
|
||||
void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier,
|
||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||
{
|
||||
@@ -758,6 +793,8 @@ void MaterialEditorView::customNotification(const AbstractView *view, const QStr
|
||||
renameMaterial(m_selectedMaterial, data.first().toString());
|
||||
} else if (identifier == "add_new_material") {
|
||||
handleToolBarAction(MaterialEditorContextObject::AddNewMaterial);
|
||||
} else if (identifier == "duplicate_material") {
|
||||
duplicateMaterial(nodeList.first());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -106,6 +106,7 @@ private:
|
||||
void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value);
|
||||
void removePropertyFromModel(const PropertyName &propertyName);
|
||||
void renameMaterial(ModelNode &material, const QString &newName);
|
||||
void duplicateMaterial(const ModelNode &material);
|
||||
|
||||
bool noValidSelection() const;
|
||||
|
||||
|
Reference in New Issue
Block a user