QmlDesigner: Unify texture creation

Textures should be created only by CreateTexture.

Fixes: QDS-13739
Change-Id: I82b2b3a1cdbdb711e1a4b69493e12252d40ff2f8
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Ali Kianian
2024-09-26 11:10:07 +03:00
parent 3886205424
commit 3ba561e6f8
5 changed files with 38 additions and 122 deletions

View File

@@ -6,6 +6,7 @@
#include "addimagesdialog.h" #include "addimagesdialog.h"
#include "addsignalhandlerdialog.h" #include "addsignalhandlerdialog.h"
#include "componentcore_constants.h" #include "componentcore_constants.h"
#include "createtexture.h"
#include "findimplementation.h" #include "findimplementation.h"
#include "layoutingridlayout.h" #include "layoutingridlayout.h"
#include "modelnodecontextmenu_helper.h" #include "modelnodecontextmenu_helper.h"
@@ -87,11 +88,14 @@ Utils::SmallString auxPropertyString(Utils::SmallStringView name)
{ {
return auxDataString + name; return auxDataString + name;
} }
} // namespace
inline static void reparentTo(const ModelNode &node, const QmlItemNode &parent) QString relativePathToQmlFile(const QString &absolutePath)
{ {
return DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(absolutePath);
}
inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
{
if (parent.isValid() && node.isValid()) { if (parent.isValid() && node.isValid()) {
NodeAbstractProperty parentProperty; NodeAbstractProperty parentProperty;
@@ -104,7 +108,7 @@ inline static void reparentTo(const ModelNode &node, const QmlItemNode &parent)
} }
} }
inline static QPointF getUpperLeftPosition(const QList<ModelNode> &modelNodeList) inline QPointF getUpperLeftPosition(const QList<ModelNode> &modelNodeList)
{ {
QPointF postion(std::numeric_limits<qreal>::max(), std::numeric_limits<qreal>::max()); QPointF postion(std::numeric_limits<qreal>::max(), std::numeric_limits<qreal>::max());
for (const ModelNode &modelNode : modelNodeList) { for (const ModelNode &modelNode : modelNodeList) {
@@ -120,13 +124,15 @@ inline static QPointF getUpperLeftPosition(const QList<ModelNode> &modelNodeList
return postion; return postion;
} }
static void setUpperLeftPostionToNode(const ModelNode &layoutNode, const QList<ModelNode> &modelNodeList) void setUpperLeftPostionToNode(const ModelNode &layoutNode, const QList<ModelNode> &modelNodeList)
{ {
QPointF upperLeftPosition = getUpperLeftPosition(modelNodeList); QPointF upperLeftPosition = getUpperLeftPosition(modelNodeList);
layoutNode.variantProperty("x").setValue(qRound(upperLeftPosition.x())); layoutNode.variantProperty("x").setValue(qRound(upperLeftPosition.x()));
layoutNode.variantProperty("y") .setValue(qRound(upperLeftPosition.y())); layoutNode.variantProperty("y") .setValue(qRound(upperLeftPosition.y()));
} }
} // namespace
namespace ModelNodeOperations { namespace ModelNodeOperations {
bool goIntoComponent(const ModelNode &modelNode) bool goIntoComponent(const ModelNode &modelNode)
@@ -1905,41 +1911,17 @@ static bool moveNodeToParent(const NodeAbstractProperty &targetProperty, const M
return false; return false;
} }
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath) ModelNode createTextureNode(AbstractView *view, const QString &imagePath)
{ {
AbstractView *view = targetProp.view();
QTC_ASSERT(view, return {}); QTC_ASSERT(view, return {});
if (targetProp.isValid()) { auto textureCreator = new CreateTexture(view);
// create a texture item lib ModelNode texture = textureCreator->execute(imagePath, AddTextureMode::Texture);
ItemLibraryEntry itemLibraryEntry; textureCreator->deleteLater();
itemLibraryEntry.setName("Texture"); return texture;
itemLibraryEntry.setType("QtQuick3D.Texture", 1, 0);
// set texture source
PropertyName prop = "source";
QString type = "QUrl";
QVariant val = imagePath;
itemLibraryEntry.addProperty(prop, type, val);
// create a texture
ModelNode newModelNode = QmlItemNode::createQmlObjectNode(view,
itemLibraryEntry,
{},
targetProp,
false);
// Rename the node based on source image
QFileInfo fi(imagePath);
newModelNode.setIdWithoutRefactoring(
view->model()->generateNewId(fi.baseName(), "textureImage"));
return newModelNode;
}
return {};
} }
bool dropAsImage3dTexture(const ModelNode &targetNode, bool dropAsImage3dTexture(const ModelNode &targetNode,
const NodeAbstractProperty &targetProp,
const QString &imagePath, const QString &imagePath,
ModelNode &newNode, ModelNode &newNode,
bool &outMoveNodesAfter) bool &outMoveNodesAfter)
@@ -1949,16 +1931,11 @@ bool dropAsImage3dTexture(const ModelNode &targetNode,
auto bindToProperty = [&](const PropertyName &propName) { auto bindToProperty = [&](const PropertyName &propName) {
view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] { view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
newNode = createTextureNode(targetProp, imagePath); newNode = createTextureNode(view, imagePath);
if (newNode.isValid()) { if (newNode.isValid()) {
BindingProperty bindProp = targetNode.bindingProperty(propName); BindingProperty bindProp = targetNode.bindingProperty(propName);
bindProp.setExpression(newNode.validId()); bindProp.setExpression(newNode.validId());
ModelNode matLib = Utils3D::materialLibraryNode(view); outMoveNodesAfter = false;
if (matLib.isValid()) {
NodeAbstractProperty matLibProp = matLib.defaultNodeAbstractProperty();
matLibProp.reparentHere(newNode);
outMoveNodesAfter = false;
}
} }
}); });
}; };
@@ -1979,7 +1956,7 @@ bool dropAsImage3dTexture(const ModelNode &targetNode,
if (dialog->result() == QDialog::Accepted) { if (dialog->result() == QDialog::Accepted) {
view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] { view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
newNode = createTextureNode(targetProp, imagePath); newNode = createTextureNode(view, imagePath);
if (newNode.isValid()) // Automatically set the texture to selected property if (newNode.isValid()) // Automatically set the texture to selected property
targetNode.bindingProperty(dialog->selectedProperty()) targetNode.bindingProperty(dialog->selectedProperty())
.setExpression(newNode.validId()); .setExpression(newNode.validId());
@@ -1999,10 +1976,11 @@ bool dropAsImage3dTexture(const ModelNode &targetNode,
return newNode.isValid(); return newNode.isValid();
} else if (targetNode.metaInfo().isQtQuick3DTexture()) { } else if (targetNode.metaInfo().isQtQuick3DTexture()) {
// if dropping an image on an existing texture, set the source // if dropping an image on an existing texture, set the source
targetNode.variantProperty("source").setValue(imagePath); targetNode.variantProperty("source").setValue(relativePathToQmlFile(imagePath));
return true; return true;
} else if (targetNode.metaInfo().isQtQuick3DModel()) { } else if (targetNode.metaInfo().isQtQuick3DModel()) {
QTimer::singleShot(0, view, [targetNode, imagePath, view]() { const QString relImagePath = relativePathToQmlFile(imagePath);
QTimer::singleShot(0, view, [targetNode, relImagePath, view]() {
if (view && targetNode.isValid()) { if (view && targetNode.isValid()) {
// To MaterialBrowserView. Done async to avoid custom notification in transaction // To MaterialBrowserView. Done async to avoid custom notification in transaction
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser");
@@ -2010,7 +1988,7 @@ bool dropAsImage3dTexture(const ModelNode &targetNode,
{targetNode}, {targetNode},
{DocumentManager::currentFilePath() {DocumentManager::currentFilePath()
.absolutePath() .absolutePath()
.pathAppended(imagePath) .pathAppended(relImagePath)
.cleanPath() .cleanPath()
.toString()}); .toString()});
} }
@@ -2102,20 +2080,12 @@ ModelNode handleItemLibraryImageDrop(const QString &imagePath,
AbstractView *view = targetNode.view(); AbstractView *view = targetNode.view();
QTC_ASSERT(view, return {}); QTC_ASSERT(view, return {});
const QString imagePathRelative
= DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(
imagePath); // relative to .ui.qml file
ModelNode newModelNode; ModelNode newModelNode;
if (!dropAsImage3dTexture(targetNode, if (!dropAsImage3dTexture(targetNode, imagePath, newModelNode, outMoveNodesAfter)) {
targetProperty,
imagePathRelative,
newModelNode,
outMoveNodesAfter)) {
if (targetNode.metaInfo().isQtQuickImage() || targetNode.metaInfo().isQtQuickBorderImage()) { if (targetNode.metaInfo().isQtQuickImage() || targetNode.metaInfo().isQtQuickBorderImage()) {
// 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(relativePathToQmlFile(imagePath));
} else { } else {
// create an image // create an image
QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromImage(view, QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromImage(view,
@@ -2176,8 +2146,7 @@ ModelNode handleItemLibraryShaderDrop(const QString &shaderPath,
ModelNode newModelNode; ModelNode newModelNode;
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath( const QString relPath = relativePathToQmlFile(shaderPath);
shaderPath);
if (targetNode.metaInfo().isQtQuick3DShader()) { if (targetNode.metaInfo().isQtQuick3DShader()) {
// if dropping into an existing Shader, update // if dropping into an existing Shader, update
@@ -2233,8 +2202,7 @@ ModelNode handleItemLibrarySoundDrop(const QString &soundPath,
ModelNode newModelNode; ModelNode newModelNode;
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath( const QString relPath = relativePathToQmlFile(soundPath);
soundPath);
if (targetNode.metaInfo().isQtMultimediaSoundEffect()) { if (targetNode.metaInfo().isQtMultimediaSoundEffect()) {
// if dropping into on an existing SoundEffect, update // if dropping into on an existing SoundEffect, update
@@ -2268,7 +2236,6 @@ ModelNode handleItemLibrarySoundDrop(const QString &soundPath,
} }
ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath, ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath,
NodeAbstractProperty targetProperty,
const ModelNode &targetNode, const ModelNode &targetNode,
bool &outMoveNodesAfter) bool &outMoveNodesAfter)
{ {
@@ -2279,24 +2246,9 @@ ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath,
if (!view->model()->hasImport(import, true, true)) if (!view->model()->hasImport(import, true, true))
return {}; return {};
const QString imagePath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(
tex3DPath); // relative to qml file
ModelNode newModelNode; ModelNode newModelNode;
if (!dropAsImage3dTexture(targetNode, dropAsImage3dTexture(targetNode, tex3DPath, newModelNode, outMoveNodesAfter);
targetProperty,
imagePath,
newModelNode,
outMoveNodesAfter)) {
view->executeInTransaction("NavigatorTreeModel::handleItemLibraryTexture3dDrop", [&] {
// create a standalone Texture3D at drop location
newModelNode = createTextureNode(targetProperty, imagePath);
if (!NodeHints::fromModelNode(targetProperty.parentModelNode())
.canBeContainerFor(newModelNode))
newModelNode.destroy();
});
}
return newModelNode; return newModelNode;
} }

View File

@@ -160,7 +160,6 @@ ModelNode handleItemLibrarySoundDrop(const QString &soundPath,
NodeAbstractProperty targetProperty, NodeAbstractProperty targetProperty,
const ModelNode &targetNode); const ModelNode &targetNode);
ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath, ModelNode handleItemLibraryTexture3dDrop(const QString &tex3DPath,
NodeAbstractProperty targetProperty,
const ModelNode &targetNode, const ModelNode &targetNode,
bool &outMoveNodesAfter); bool &outMoveNodesAfter);

View File

@@ -177,8 +177,8 @@ static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty
} }
} }
NavigatorTreeModel::NavigatorTreeModel(QObject *parent) : QAbstractItemModel(parent) NavigatorTreeModel::NavigatorTreeModel(QObject *parent)
, m_createTextures(Utils::makeUniqueObjectPtr<CreateTextures>(m_view)) : QAbstractItemModel(parent)
{ {
m_actionManager = &QmlDesignerPlugin::instance()->viewManager().designerActionManager(); m_actionManager = &QmlDesignerPlugin::instance()->viewManager().designerActionManager();
} }
@@ -583,17 +583,10 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
bool moveNodesAfter = false; bool moveNodesAfter = false;
m_view->executeInTransaction(__FUNCTION__, [&] { m_view->executeInTransaction(__FUNCTION__, [&] {
m_createTextures->execute(QStringList{texturePath}, ModelNodeOperations::handleItemLibraryTexture3dDrop(texturePath,
AddTextureMode::Image, modelNodeForIndex(
Utils3D::active3DSceneId(m_view->model())); rowModelIndex),
QString textureName = Utils::FilePath::fromString(texturePath).fileName(); moveNodesAfter);
QString textureAbsolutePath = DocumentManager::currentResourcePath()
.pathAppended("images/" + textureName).toString();
ModelNodeOperations::handleItemLibraryImageDrop(textureAbsolutePath,
targetProperty,
modelNodeForIndex(
rowModelIndex),
moveNodesAfter);
}); });
} }
} }
@@ -664,7 +657,6 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
} else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { } else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) {
currNode = ModelNodeOperations::handleItemLibraryTexture3dDrop( currNode = ModelNodeOperations::handleItemLibraryTexture3dDrop(
assetPath, assetPath,
targetProperty,
modelNodeForIndex(rowModelIndex), modelNodeForIndex(rowModelIndex),
moveNodesAfter); moveNodesAfter);
} else if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) { } else if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) {
@@ -853,34 +845,6 @@ bool QmlDesigner::NavigatorTreeModel::moveNodeToParent(const NodeAbstractPropert
return false; return false;
} }
ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targetProp,
const QString &imagePath)
{
if (targetProp.isValid()) {
// create a texture item lib
ItemLibraryEntry itemLibraryEntry;
itemLibraryEntry.setName("Texture");
itemLibraryEntry.setType("QtQuick3D.Texture", 1, 0);
// set texture source
PropertyName prop = "source";
QString type = "QUrl";
QVariant val = imagePath;
itemLibraryEntry.addProperty(prop, type, val);
// create a texture
ModelNode newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {},
targetProp, false);
// Rename the node based on source image
QFileInfo fi(imagePath);
newModelNode.setIdWithoutRefactoring(
m_view->model()->generateNewId(fi.baseName(), "textureImage"));
return newModelNode;
}
return {};
}
namespace { namespace {
NodeMetaInfo propertyType(const NodeAbstractProperty &property) NodeMetaInfo propertyType(const NodeAbstractProperty &property)
{ {

View File

@@ -96,9 +96,11 @@ 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);
bool dropAsImage3dTexture(const ModelNode &targetNode, const NodeAbstractProperty &targetProp, bool dropAsImage3dTexture(const ModelNode &targetNode,
const QString &imagePath, ModelNode &newNode, bool &outMoveNodesAfter); const NodeAbstractProperty &targetProp,
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath); const QString &imagePath,
ModelNode &newNode,
bool &outMoveNodesAfter);
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;

View File

@@ -341,7 +341,6 @@ void TextEditorWidget::dropEvent(QDropEvent *dropEvent)
targetNode); targetNode);
} else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { } else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) {
newModelNode = ModelNodeOperations::handleItemLibraryTexture3dDrop(assetPath, newModelNode = ModelNodeOperations::handleItemLibraryTexture3dDrop(assetPath,
targetProperty,
targetNode, targetNode,
moveNodesAfter); moveNodesAfter);
} else if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) { } else if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) {