forked from qt-creator/qt-creator
QmlDesigner: Fix on-drag binding of created nodes to properties
Generic matching for dragged item to bindable properties didn't work properly, missing appropriate matches. Now supported cases are hardcoded with the expectation that in the future this will be handled via metainfo hints. Also fixed related issues with dragging images and shaders into navigator. Fixes: QDS-6198 Change-Id: Ide9360ef037997cbb388f4c2db35b79eded67aa6 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -34,35 +34,64 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|
|||||||
const NodeMetaInfo &parentInfo,
|
const NodeMetaInfo &parentInfo,
|
||||||
bool breakOnFirst)
|
bool breakOnFirst)
|
||||||
{
|
{
|
||||||
TypeName typeName = insertInfo.typeName();
|
// TODO: Metainfo based matching system (QDS-6240)
|
||||||
TypeName superClass = insertInfo.directSuperClass().typeName();
|
|
||||||
TypeName nodePackage = insertInfo.typeName().replace(insertInfo.simplifiedTypeName(), "");
|
|
||||||
TypeName targetPackage = parentInfo.typeName().replace(parentInfo.simplifiedTypeName(), "");
|
|
||||||
if (!nodePackage.contains(targetPackage))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Common base types cause too many rarely valid matches, so they are ignored
|
// Fall back to a hardcoded list of supported cases:
|
||||||
const QSet<TypeName> ignoredTypes {"<cpp>.QObject",
|
// Texture
|
||||||
"<cpp>.QQuickItem",
|
// -> DefaultMaterial
|
||||||
"<cpp>.QQuick3DObject",
|
// -> PrincipledMaterial
|
||||||
"QtQuick.Item",
|
// -> SpriteParticle3D
|
||||||
"QtQuick3D.Object3D",
|
// -> TextureInput
|
||||||
"QtQuick3D.Node",
|
// -> SceneEnvironment
|
||||||
"QtQuick3D.Particles3D.ParticleSystem3D"};
|
// Effect
|
||||||
const PropertyNameList targetNodeNameList = parentInfo.propertyNames();
|
// -> SceneEnvironment
|
||||||
for (const PropertyName &name : targetNodeNameList) {
|
// Shader, Command, Buffer
|
||||||
if (!name.contains('.')) {
|
// -> Pass
|
||||||
TypeName propType = parentInfo.propertyTypeName(name).replace("<cpp>.", targetPackage);
|
// InstanceListEntry
|
||||||
// Skip properties that are not sub classes of anything
|
// -> InstanceList
|
||||||
if (propType.contains('.')
|
// Pass
|
||||||
&& !ignoredTypes.contains(propType)
|
// -> Effect
|
||||||
&& (typeName == propType || propType == superClass)
|
|
||||||
&& parentInfo.propertyIsWritable(propType)) {
|
const TypeName textureType = "QtQuick3D.Texture";
|
||||||
propertyList.append(QString::fromLatin1(name));
|
if (insertInfo.isSubclassOf(textureType)) {
|
||||||
if (breakOnFirst)
|
const TypeName textureTypeCpp = "<cpp>.QQuick3DTexture";
|
||||||
break;
|
if (parentInfo.isSubclassOf("QtQuick3D.DefaultMaterial")
|
||||||
|
|| parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
||||||
|
// All texture properties are valid targets
|
||||||
|
const PropertyNameList targetNodeNameList = parentInfo.propertyNames();
|
||||||
|
for (const PropertyName &name : targetNodeNameList) {
|
||||||
|
TypeName propType = parentInfo.propertyTypeName(name);
|
||||||
|
if (propType == textureType || propType == textureTypeCpp) {
|
||||||
|
propertyList.append(QString::fromLatin1(name));
|
||||||
|
if (breakOnFirst)
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (parentInfo.isSubclassOf("QtQuick3D.Particles3D.SpriteParticle3D")) {
|
||||||
|
propertyList.append("sprite");
|
||||||
|
} else if (parentInfo.isSubclassOf("QtQuick3D.TextureInput")) {
|
||||||
|
propertyList.append("texture");
|
||||||
|
} else if (parentInfo.isSubclassOf("QtQuick3D.SceneEnvironment")) {
|
||||||
|
propertyList.append("lightProbe");
|
||||||
}
|
}
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.Effect")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.SceneEnvironment"))
|
||||||
|
propertyList.append("effects");
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.Shader")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.Pass"))
|
||||||
|
propertyList.append("shaders");
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.Command")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.Pass"))
|
||||||
|
propertyList.append("commands");
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.Buffer")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.Pass"))
|
||||||
|
propertyList.append("output");
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.InstanceListEntry")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.InstanceList"))
|
||||||
|
propertyList.append("instances");
|
||||||
|
} else if (insertInfo.isSubclassOf("QtQuick3D.Pass")) {
|
||||||
|
if (parentInfo.isSubclassOf("QtQuick3D.Effect"))
|
||||||
|
propertyList.append("passes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,14 +139,6 @@ TypeName ChooseFromPropertyListDialog::selectedProperty() const
|
|||||||
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
||||||
const ModelNode &targetNode, const ModelNode &newNode, QWidget *parent)
|
const ModelNode &targetNode, const ModelNode &newNode, QWidget *parent)
|
||||||
{
|
{
|
||||||
TypeName typeName = newNode.type();
|
|
||||||
|
|
||||||
// Component matches cases where you don't want to insert a plain component,
|
|
||||||
// such as layer.effect. Also, default property is often a Component (typically 'delegate'),
|
|
||||||
// and inserting into such property will silently overwrite implicit component, if any.
|
|
||||||
if (typeName == "QtQml.Component")
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const NodeMetaInfo info = newNode.metaInfo();
|
const NodeMetaInfo info = newNode.metaInfo();
|
||||||
const NodeMetaInfo targetInfo = targetNode.metaInfo();
|
const NodeMetaInfo targetInfo = targetNode.metaInfo();
|
||||||
ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(info, targetInfo);
|
ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(info, targetInfo);
|
||||||
|
|||||||
@@ -581,21 +581,29 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
addImport(import);
|
addImport(import);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool moveNodesAfter = true;
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::dropMimeData", [&] {
|
m_view->executeInTransaction("NavigatorTreeModel::dropMimeData", [&] {
|
||||||
for (const QString &assetPath : assetsPaths) {
|
for (const QString &assetPath : assetsPaths) {
|
||||||
auto assetTypeAndData = AssetsLibraryWidget::getAssetTypeAndData(assetPath);
|
auto assetTypeAndData = AssetsLibraryWidget::getAssetTypeAndData(assetPath);
|
||||||
QString assetType = assetTypeAndData.first;
|
QString assetType = assetTypeAndData.first;
|
||||||
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
||||||
if (assetType == "application/vnd.bauhaus.libraryresource.image")
|
if (assetType == "application/vnd.bauhaus.libraryresource.image") {
|
||||||
currNode = handleItemLibraryImageDrop(assetPath, targetProperty, rowModelIndex);
|
currNode = handleItemLibraryImageDrop(assetPath, targetProperty,
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.font")
|
rowModelIndex, moveNodesAfter);
|
||||||
currNode = handleItemLibraryFontDrop(assetData, targetProperty, rowModelIndex); // assetData is fontFamily
|
} else if (assetType == "application/vnd.bauhaus.libraryresource.font") {
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.shader")
|
currNode = handleItemLibraryFontDrop(assetData, // assetData is fontFamily
|
||||||
currNode = handleItemLibraryShaderDrop(assetPath, assetData == "f", targetProperty, rowModelIndex);
|
targetProperty, rowModelIndex);
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.sound")
|
} else if (assetType == "application/vnd.bauhaus.libraryresource.shader") {
|
||||||
currNode = handleItemLibrarySoundDrop(assetPath, targetProperty, rowModelIndex);
|
currNode = handleItemLibraryShaderDrop(assetPath, assetData == "f",
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.texture3d")
|
targetProperty, rowModelIndex,
|
||||||
currNode = handleItemLibraryTexture3dDrop(assetPath, targetProperty, rowModelIndex);
|
moveNodesAfter);
|
||||||
|
} else if (assetType == "application/vnd.bauhaus.libraryresource.sound") {
|
||||||
|
currNode = handleItemLibrarySoundDrop(assetPath, targetProperty,
|
||||||
|
rowModelIndex);
|
||||||
|
} else if (assetType == "application/vnd.bauhaus.libraryresource.texture3d") {
|
||||||
|
currNode = handleItemLibraryTexture3dDrop(assetPath, targetProperty,
|
||||||
|
rowModelIndex, moveNodesAfter);
|
||||||
|
}
|
||||||
|
|
||||||
if (currNode.isValid())
|
if (currNode.isValid())
|
||||||
addedNodes.append(currNode);
|
addedNodes.append(currNode);
|
||||||
@@ -603,7 +611,8 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!addedNodes.isEmpty()) {
|
if (!addedNodes.isEmpty()) {
|
||||||
moveNodesInteractive(targetProperty, addedNodes, rowNumber);
|
if (moveNodesAfter)
|
||||||
|
moveNodesInteractive(targetProperty, addedNodes, rowNumber);
|
||||||
m_view->setSelectedModelNodes(addedNodes);
|
m_view->setSelectedModelNodes(addedNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,21 +691,22 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
|||||||
dialog->exec();
|
dialog->exec();
|
||||||
if (soloProperty || dialog->result() == QDialog::Accepted) {
|
if (soloProperty || dialog->result() == QDialog::Accepted) {
|
||||||
TypeName selectedProp = dialog->selectedProperty();
|
TypeName selectedProp = dialog->selectedProperty();
|
||||||
BindingProperty listProp = targetNode.bindingProperty(selectedProp);
|
|
||||||
if (targetNode.metaInfo().propertyIsListProperty(selectedProp)) {
|
// Pass and TextureInput can't have children, so we have to move nodes under parent
|
||||||
if ((newModelNode.isSubclassOf("QtQuick3D.Shader") || newModelNode.isSubclassOf("QtQuick3D.Command"))
|
if (((newModelNode.isSubclassOf("QtQuick3D.Shader")
|
||||||
&& targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass")) {
|
|| newModelNode.isSubclassOf("QtQuick3D.Command")
|
||||||
NodeAbstractProperty parentProp = targetProperty.parentProperty();
|
|| newModelNode.isSubclassOf("QtQuick3D.Buffer"))
|
||||||
if (parentProp.isValid()) {
|
&& targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass"))
|
||||||
targetProperty = parentProp;
|
|| (newModelNode.isSubclassOf("QtQuick3D.Texture")
|
||||||
ModelNode targetModel = targetProperty.parentModelNode();
|
&& targetProperty.parentModelNode().isSubclassOf("QtQuick3D.TextureInput"))) {
|
||||||
targetRowNumber = rowCount(indexForModelNode(targetModel));
|
if (moveNodeToParent(targetProperty, newQmlObjectNode)) {
|
||||||
// Move node to new parent within the same transaction as we don't
|
targetProperty = targetProperty.parentProperty();
|
||||||
// want undo to place the node under invalid parent
|
moveNodesAfter = false;
|
||||||
moveNodesInteractive(targetProperty, {newQmlObjectNode}, targetRowNumber, false);
|
|
||||||
moveNodesAfter = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetNode.metaInfo().propertyIsListProperty(selectedProp)) {
|
||||||
|
BindingProperty listProp = targetNode.bindingProperty(selectedProp);
|
||||||
listProp.addModelNodeToArray(newModelNode);
|
listProp.addModelNodeToArray(newModelNode);
|
||||||
validContainer = true;
|
validContainer = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -778,7 +788,8 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
|||||||
|
|
||||||
ModelNode NavigatorTreeModel::handleItemLibraryImageDrop(const QString &imagePath,
|
ModelNode NavigatorTreeModel::handleItemLibraryImageDrop(const QString &imagePath,
|
||||||
NodeAbstractProperty targetProperty,
|
NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex)
|
const QModelIndex &rowModelIndex,
|
||||||
|
bool &outMoveNodesAfter)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_view, return {});
|
QTC_ASSERT(m_view, return {});
|
||||||
|
|
||||||
@@ -788,7 +799,7 @@ ModelNode NavigatorTreeModel::handleItemLibraryImageDrop(const QString &imagePat
|
|||||||
|
|
||||||
ModelNode newModelNode;
|
ModelNode newModelNode;
|
||||||
|
|
||||||
if (!dropAsImage3dTexture(targetNode, targetProperty, imagePathRelative, newModelNode)) {
|
if (!dropAsImage3dTexture(targetNode, targetProperty, imagePathRelative, newModelNode, outMoveNodesAfter)) {
|
||||||
if (targetNode.isSubclassOf("QtQuick.Image") || targetNode.isSubclassOf("QtQuick.BorderImage")) {
|
if (targetNode.isSubclassOf("QtQuick.Image") || targetNode.isSubclassOf("QtQuick.BorderImage")) {
|
||||||
// if dropping an image on an existing image, set the source
|
// if dropping an image on an existing image, set the source
|
||||||
targetNode.variantProperty("source").setValue(imagePathRelative);
|
targetNode.variantProperty("source").setValue(imagePathRelative);
|
||||||
@@ -846,9 +857,23 @@ void NavigatorTreeModel::addImport(const QString &importName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmlDesigner::NavigatorTreeModel::moveNodeToParent(const NodeAbstractProperty &targetProperty,
|
||||||
|
const ModelNode &node)
|
||||||
|
{
|
||||||
|
NodeAbstractProperty parentProp = targetProperty.parentProperty();
|
||||||
|
if (parentProp.isValid()) {
|
||||||
|
ModelNode targetModel = parentProp.parentModelNode();
|
||||||
|
int targetRowNumber = rowCount(indexForModelNode(targetModel));
|
||||||
|
moveNodesInteractive(parentProp, {node}, targetRowNumber, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
||||||
NodeAbstractProperty targetProperty,
|
NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex)
|
const QModelIndex &rowModelIndex,
|
||||||
|
bool &outMoveNodesAfter)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_view, return {});
|
QTC_ASSERT(m_view, return {});
|
||||||
|
|
||||||
@@ -863,29 +888,37 @@ ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderP
|
|||||||
: "Shader.Vertex");
|
: "Shader.Vertex");
|
||||||
targetNode.variantProperty("shader").setValue(relPath);
|
targetNode.variantProperty("shader").setValue(relPath);
|
||||||
} else {
|
} else {
|
||||||
// create a new Shader
|
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryShaderDrop", [&] {
|
||||||
ItemLibraryEntry itemLibraryEntry;
|
// create a new Shader
|
||||||
itemLibraryEntry.setName("Shader");
|
ItemLibraryEntry itemLibraryEntry;
|
||||||
itemLibraryEntry.setType("QtQuick3D.Shader", 1, 0);
|
itemLibraryEntry.setName("Shader");
|
||||||
|
itemLibraryEntry.setType("QtQuick3D.Shader", 1, 0);
|
||||||
|
|
||||||
// set shader properties
|
// set shader properties
|
||||||
PropertyName prop = "shader";
|
PropertyName prop = "shader";
|
||||||
QString type = "QByteArray";
|
QString type = "QByteArray";
|
||||||
QVariant val = relPath;
|
QVariant val = relPath;
|
||||||
itemLibraryEntry.addProperty(prop, type, val);
|
itemLibraryEntry.addProperty(prop, type, val);
|
||||||
prop = "stage";
|
prop = "stage";
|
||||||
type = "enum";
|
type = "enum";
|
||||||
val = isFragShader ? "Shader.Fragment" : "Shader.Vertex";
|
val = isFragShader ? "Shader.Fragment" : "Shader.Vertex";
|
||||||
itemLibraryEntry.addProperty(prop, type, val);
|
itemLibraryEntry.addProperty(prop, type, val);
|
||||||
|
|
||||||
// create a texture
|
// create a texture
|
||||||
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {},
|
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {},
|
||||||
targetProperty, false);
|
targetProperty, false);
|
||||||
|
|
||||||
// Rename the node based on shader source
|
// Rename the node based on shader source
|
||||||
QFileInfo fi(relPath);
|
QFileInfo fi(relPath);
|
||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
||||||
"shader"));
|
"shader"));
|
||||||
|
// Passes can't have children, so move shader node under parent
|
||||||
|
if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass")) {
|
||||||
|
BindingProperty listProp = targetNode.bindingProperty("shaders");
|
||||||
|
listProp.addModelNodeToArray(newModelNode);
|
||||||
|
outMoveNodesAfter = !moveNodeToParent(targetProperty, newModelNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
@@ -932,7 +965,8 @@ ModelNode NavigatorTreeModel::handleItemLibrarySoundDrop(const QString &soundPat
|
|||||||
|
|
||||||
ModelNode NavigatorTreeModel::handleItemLibraryTexture3dDrop(const QString &tex3DPath,
|
ModelNode NavigatorTreeModel::handleItemLibraryTexture3dDrop(const QString &tex3DPath,
|
||||||
NodeAbstractProperty targetProperty,
|
NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex)
|
const QModelIndex &rowModelIndex,
|
||||||
|
bool &outMoveNodesAfter)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_view, return {});
|
QTC_ASSERT(m_view, return {});
|
||||||
|
|
||||||
@@ -947,7 +981,7 @@ ModelNode NavigatorTreeModel::handleItemLibraryTexture3dDrop(const QString &tex3
|
|||||||
|
|
||||||
ModelNode newModelNode;
|
ModelNode newModelNode;
|
||||||
|
|
||||||
if (!dropAsImage3dTexture(targetNode, targetProperty, imagePath, newModelNode)) {
|
if (!dropAsImage3dTexture(targetNode, targetProperty, imagePath, newModelNode, outMoveNodesAfter)) {
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryTexture3dDrop", [&] {
|
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryTexture3dDrop", [&] {
|
||||||
// create a standalone Texture3D at drop location
|
// create a standalone Texture3D at drop location
|
||||||
newModelNode = createTextureNode(targetProperty, imagePath);
|
newModelNode = createTextureNode(targetProperty, imagePath);
|
||||||
@@ -962,8 +996,23 @@ ModelNode NavigatorTreeModel::handleItemLibraryTexture3dDrop(const QString &tex3
|
|||||||
bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|
bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|
||||||
const NodeAbstractProperty &targetProp,
|
const NodeAbstractProperty &targetProp,
|
||||||
const QString &imagePath,
|
const QString &imagePath,
|
||||||
ModelNode &newNode)
|
ModelNode &newNode,
|
||||||
|
bool &outMoveNodesAfter)
|
||||||
{
|
{
|
||||||
|
auto bindToProperty = [&](const PropertyName &propName, bool sibling) {
|
||||||
|
m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
|
||||||
|
newNode = createTextureNode(targetProp, imagePath);
|
||||||
|
if (newNode.isValid()) {
|
||||||
|
targetNode.bindingProperty(propName).setExpression(newNode.validId());
|
||||||
|
|
||||||
|
// If dropping an image on e.g. TextureInput, create a texture on the same level as
|
||||||
|
// target, as the target doesn't support Texture children (QTBUG-86219)
|
||||||
|
if (sibling)
|
||||||
|
outMoveNodesAfter = !moveNodeToParent(targetProp, newNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial")
|
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial")
|
||||||
|| targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
|| targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
||||||
// if dropping an image on a material, create a texture instead of image
|
// if dropping an image on a material, create a texture instead of image
|
||||||
@@ -986,16 +1035,13 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|
|||||||
delete dialog;
|
delete dialog;
|
||||||
return true;
|
return true;
|
||||||
} else if (targetNode.isSubclassOf("QtQuick3D.TextureInput")) {
|
} else if (targetNode.isSubclassOf("QtQuick3D.TextureInput")) {
|
||||||
// If dropping an image on a TextureInput, create a texture on the same level as
|
bindToProperty("texture", true);
|
||||||
// TextureInput, as the TextureInput doesn't support Texture children (QTBUG-86219)
|
return newNode.isValid();
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
|
} else if (targetNode.isSubclassOf("QtQuick3D.Particles3D.SpriteParticle3D")) {
|
||||||
NodeAbstractProperty parentProp = targetProp.parentProperty();
|
bindToProperty("sprite", false);
|
||||||
newNode = createTextureNode(parentProp, imagePath);
|
return newNode.isValid();
|
||||||
if (newNode.isValid()) {
|
} else if (targetNode.isSubclassOf("QtQuick3D.SceneEnvironment")) {
|
||||||
// Automatically set the texture to texture property
|
bindToProperty("lightProbe", false);
|
||||||
targetNode.bindingProperty("texture").setExpression(newNode.validId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return newNode.isValid();
|
return newNode.isValid();
|
||||||
} else if (targetNode.isSubclassOf("QtQuick3D.Texture")) {
|
} else if (targetNode.isSubclassOf("QtQuick3D.Texture")) {
|
||||||
// if dropping an image on an existing texture, set the source
|
// if dropping an image on an existing texture, set the source
|
||||||
|
|||||||
@@ -115,21 +115,24 @@ private:
|
|||||||
void handleInternalDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
|
void handleInternalDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
|
||||||
void handleItemLibraryItemDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
|
void handleItemLibraryItemDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
|
||||||
ModelNode handleItemLibraryImageDrop(const QString &imagePath, NodeAbstractProperty targetProperty,
|
ModelNode handleItemLibraryImageDrop(const QString &imagePath, NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex);
|
const QModelIndex &rowModelIndex, bool &outMoveNodesAfter);
|
||||||
ModelNode handleItemLibraryFontDrop(const QString &fontFamily, NodeAbstractProperty targetProperty,
|
ModelNode handleItemLibraryFontDrop(const QString &fontFamily, NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex);
|
const QModelIndex &rowModelIndex);
|
||||||
ModelNode handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
ModelNode handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
||||||
NodeAbstractProperty targetProperty, const QModelIndex &rowModelIndex);
|
NodeAbstractProperty targetProperty,
|
||||||
|
const QModelIndex &rowModelIndex,
|
||||||
|
bool &outMoveNodesAfter);
|
||||||
ModelNode handleItemLibrarySoundDrop(const QString &soundPath, NodeAbstractProperty targetProperty,
|
ModelNode handleItemLibrarySoundDrop(const QString &soundPath, NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex);
|
const QModelIndex &rowModelIndex);
|
||||||
ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath, NodeAbstractProperty targetProperty,
|
ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath, NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex);
|
const QModelIndex &rowModelIndex, bool &outMoveNodesAfter);
|
||||||
bool dropAsImage3dTexture(const ModelNode &targetNode, const NodeAbstractProperty &targetProp,
|
bool dropAsImage3dTexture(const ModelNode &targetNode, const NodeAbstractProperty &targetProp,
|
||||||
const QString &imagePath, ModelNode &newNode);
|
const QString &imagePath, ModelNode &newNode, bool &outMoveNodesAfter);
|
||||||
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
||||||
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
||||||
void addImport(const QString &importName);
|
void addImport(const QString &importName);
|
||||||
QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, bool reverseOrder) const;
|
QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, bool reverseOrder) const;
|
||||||
|
bool moveNodeToParent(const NodeAbstractProperty &targetProperty, const ModelNode &newModelNode);
|
||||||
|
|
||||||
QPointer<NavigatorView> m_view;
|
QPointer<NavigatorView> m_view;
|
||||||
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
||||||
|
|||||||
Reference in New Issue
Block a user