forked from qt-creator/qt-creator
QmlDesigner: Add backend for textures in PropertyEditor
Task-number: QDS-14805 Change-Id: I71a5935af3c2cddbeb87f496d2e15464244639c2 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -424,6 +424,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
qmlanchorbindingproxy.cpp qmlanchorbindingproxy.h
|
qmlanchorbindingproxy.cpp qmlanchorbindingproxy.h
|
||||||
qmlmaterialnodeproxy.cpp qmlmaterialnodeproxy.h
|
qmlmaterialnodeproxy.cpp qmlmaterialnodeproxy.h
|
||||||
qmlmodelnodeproxy.cpp qmlmodelnodeproxy.h
|
qmlmodelnodeproxy.cpp qmlmodelnodeproxy.h
|
||||||
|
qmltexturenodeproxy.cpp qmltexturenodeproxy.h
|
||||||
quick2propertyeditorview.cpp quick2propertyeditorview.h
|
quick2propertyeditorview.cpp quick2propertyeditorview.h
|
||||||
propertyeditorutils.cpp propertyeditorutils.h
|
propertyeditorutils.cpp propertyeditorutils.h
|
||||||
)
|
)
|
||||||
|
@@ -339,6 +339,7 @@ void PropertyEditorQmlBackend::handleVariantPropertyChangedInModelNodeProxy(cons
|
|||||||
void PropertyEditorQmlBackend::handleBindingPropertyChangedInModelNodeProxy(const BindingProperty &property)
|
void PropertyEditorQmlBackend::handleBindingPropertyChangedInModelNodeProxy(const BindingProperty &property)
|
||||||
{
|
{
|
||||||
m_backendModelNode.handleBindingPropertyChanged(property);
|
m_backendModelNode.handleBindingPropertyChanged(property);
|
||||||
|
m_backendTextureNode.handleBindingPropertyChanged(property);
|
||||||
updateInstanceImage();
|
updateInstanceImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,11 +351,13 @@ void PropertyEditorQmlBackend::handleBindingPropertyInModelNodeProxyAboutToChang
|
|||||||
if (expressionNode.metaInfo().isQtQuick3DTexture())
|
if (expressionNode.metaInfo().isQtQuick3DTexture())
|
||||||
updateInstanceImage();
|
updateInstanceImage();
|
||||||
}
|
}
|
||||||
|
m_backendTextureNode.handleBindingPropertyChanged(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyEditorQmlBackend::handlePropertiesRemovedInModelNodeProxy(const AbstractProperty &property)
|
void PropertyEditorQmlBackend::handlePropertiesRemovedInModelNodeProxy(const AbstractProperty &property)
|
||||||
{
|
{
|
||||||
m_backendModelNode.handlePropertiesRemoved(property);
|
m_backendModelNode.handlePropertiesRemoved(property);
|
||||||
|
m_backendTextureNode.handlePropertiesRemoved(property);
|
||||||
updateInstanceImage();
|
updateInstanceImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,6 +562,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
|
|||||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||||
|
|
||||||
m_backendMaterialNode.setup(qmlObjectNode);
|
m_backendMaterialNode.setup(qmlObjectNode);
|
||||||
|
m_backendTextureNode.setup(qmlObjectNode);
|
||||||
|
|
||||||
// className
|
// className
|
||||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
||||||
@@ -995,6 +999,7 @@ void PropertyEditorQmlBackend::setupContextProperties()
|
|||||||
context()->setContextProperties({
|
context()->setContextProperties({
|
||||||
{"modelNodeBackend", QVariant::fromValue(&m_backendModelNode)},
|
{"modelNodeBackend", QVariant::fromValue(&m_backendModelNode)},
|
||||||
{"materialNodeBackend", QVariant::fromValue(&m_backendMaterialNode)},
|
{"materialNodeBackend", QVariant::fromValue(&m_backendMaterialNode)},
|
||||||
|
{"textureNodeBackend", QVariant::fromValue(&m_backendTextureNode)},
|
||||||
{"anchorBackend", QVariant::fromValue(&m_backendAnchorBinding)},
|
{"anchorBackend", QVariant::fromValue(&m_backendAnchorBinding)},
|
||||||
{"transaction", QVariant::fromValue(m_propertyEditorTransaction.get())},
|
{"transaction", QVariant::fromValue(m_propertyEditorTransaction.get())},
|
||||||
{"dummyBackendValue", QVariant::fromValue(m_dummyPropertyEditorValue.get())},
|
{"dummyBackendValue", QVariant::fromValue(m_dummyPropertyEditorValue.get())},
|
||||||
@@ -1051,6 +1056,7 @@ bool PropertyEditorQmlBackend::checkIfUrlExists(const QUrl &url)
|
|||||||
void PropertyEditorQmlBackend::emitSelectionToBeChanged()
|
void PropertyEditorQmlBackend::emitSelectionToBeChanged()
|
||||||
{
|
{
|
||||||
m_backendModelNode.emitSelectionToBeChanged();
|
m_backendModelNode.emitSelectionToBeChanged();
|
||||||
|
m_backendTextureNode.updateSelectionDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyEditorQmlBackend::emitSelectionChanged()
|
void PropertyEditorQmlBackend::emitSelectionChanged()
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "qmlanchorbindingproxy.h"
|
#include "qmlanchorbindingproxy.h"
|
||||||
#include "qmlmaterialnodeproxy.h"
|
#include "qmlmaterialnodeproxy.h"
|
||||||
#include "qmlmodelnodeproxy.h"
|
#include "qmlmodelnodeproxy.h"
|
||||||
|
#include "qmltexturenodeproxy.h"
|
||||||
#include "quick2propertyeditorview.h"
|
#include "quick2propertyeditorview.h"
|
||||||
|
|
||||||
#include <utils/uniqueobjectptr.h>
|
#include <utils/uniqueobjectptr.h>
|
||||||
@@ -129,6 +130,7 @@ private:
|
|||||||
Utils::UniqueObjectPtr<Quick2PropertyEditorView> m_view = nullptr;
|
Utils::UniqueObjectPtr<Quick2PropertyEditorView> m_view = nullptr;
|
||||||
QmlAnchorBindingProxy m_backendAnchorBinding;
|
QmlAnchorBindingProxy m_backendAnchorBinding;
|
||||||
QmlMaterialNodeProxy m_backendMaterialNode;
|
QmlMaterialNodeProxy m_backendMaterialNode;
|
||||||
|
QmlTextureNodeProxy m_backendTextureNode;
|
||||||
QmlModelNodeProxy m_backendModelNode;
|
QmlModelNodeProxy m_backendModelNode;
|
||||||
std::unique_ptr<PropertyEditorTransaction> m_propertyEditorTransaction;
|
std::unique_ptr<PropertyEditorTransaction> m_propertyEditorTransaction;
|
||||||
std::unique_ptr<PropertyEditorValue> m_dummyPropertyEditorValue;
|
std::unique_ptr<PropertyEditorValue> m_dummyPropertyEditorValue;
|
||||||
|
@@ -0,0 +1,170 @@
|
|||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qmltexturenodeproxy.h"
|
||||||
|
|
||||||
|
#include <abstractview.h>
|
||||||
|
#include <createtexture.h>
|
||||||
|
#include <designmodewidget.h>
|
||||||
|
#include <model.h>
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
|
#include <qqml.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
QmlTextureNodeProxy::QmlTextureNodeProxy() = default;
|
||||||
|
|
||||||
|
QmlTextureNodeProxy::~QmlTextureNodeProxy() = default;
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::setup(const QmlObjectNode &objectNode)
|
||||||
|
{
|
||||||
|
const QmlObjectNode texture = objectNode.metaInfo().isQtQuick3DTexture() ? objectNode
|
||||||
|
: QmlObjectNode{};
|
||||||
|
|
||||||
|
setTextureNode(texture);
|
||||||
|
updateSelectionDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::updateSelectionDetails()
|
||||||
|
{
|
||||||
|
QScopeGuard falseSetter{
|
||||||
|
std::bind_front(&QmlTextureNodeProxy::setSelectedNodeAcceptsMaterial, this, false)};
|
||||||
|
|
||||||
|
if (!textureNode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlObjectNode selectedNode = textureNode().view()->singleSelectedModelNode();
|
||||||
|
if (!selectedNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
falseSetter.dismiss();
|
||||||
|
setSelectedNodeAcceptsMaterial(selectedNode.hasBindingProperty("materials"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::handlePropertyChanged(const AbstractProperty &property)
|
||||||
|
{
|
||||||
|
if (!textureNode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlObjectNode node = property.parentModelNode();
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlObjectNode selectedNode = textureNode().view()->singleSelectedModelNode();
|
||||||
|
if (!selectedNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (property.name() == "materials"_L1
|
||||||
|
&& (selectedNode == node || selectedNode.propertyChangeForCurrentState() == node)) {
|
||||||
|
updateSelectionDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::handleBindingPropertyChanged(const BindingProperty &property)
|
||||||
|
{
|
||||||
|
handlePropertyChanged(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::handlePropertiesRemoved(const AbstractProperty &property)
|
||||||
|
{
|
||||||
|
handlePropertyChanged(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlObjectNode QmlTextureNodeProxy::textureNode() const
|
||||||
|
{
|
||||||
|
return m_textureNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlTextureNodeProxy::hasTexture() const
|
||||||
|
{
|
||||||
|
return textureNode().isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlTextureNodeProxy::selectedNodeAcceptsMaterial() const
|
||||||
|
{
|
||||||
|
return m_selectedNodeAcceptsMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlTextureNodeProxy::resolveResourcePath(const QString &path) const
|
||||||
|
{
|
||||||
|
if (Utils::FilePath::fromString(path).isAbsolutePath())
|
||||||
|
return path;
|
||||||
|
|
||||||
|
return QmlDesignerPlugin::instance()
|
||||||
|
->documentManager()
|
||||||
|
.currentDesignDocument()
|
||||||
|
->fileName()
|
||||||
|
.absolutePath()
|
||||||
|
.pathAppended(path)
|
||||||
|
.cleanPath()
|
||||||
|
.toUrlishString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::toolbarAction(int action)
|
||||||
|
{
|
||||||
|
if (!hasQuick3DImport())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case ToolBarAction::ApplyToSelected: {
|
||||||
|
if (!textureNode())
|
||||||
|
return;
|
||||||
|
AbstractView *view = textureNode().view();
|
||||||
|
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser");
|
||||||
|
ModelNode targetNode = view->singleSelectedModelNode();
|
||||||
|
view->emitCustomNotification("apply_texture_to_model3D", {targetNode, textureNode()});
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ToolBarAction::AddNewTexture: {
|
||||||
|
if (!textureNode())
|
||||||
|
break;
|
||||||
|
ModelNode newTexture = CreateTexture(textureNode().view()).execute();
|
||||||
|
QTimer::singleShot(0, this, [newTexture]() {
|
||||||
|
if (newTexture)
|
||||||
|
newTexture.model()->setSelectedModelNodes({newTexture});
|
||||||
|
});
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ToolBarAction::DeleteCurrentTexture: {
|
||||||
|
if (textureNode()) {
|
||||||
|
AbstractView *view = textureNode().view();
|
||||||
|
view->executeInTransaction(__FUNCTION__, [&] { textureNode().destroy(); });
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ToolBarAction::OpenMaterialBrowser: {
|
||||||
|
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser", true);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::registerDeclarativeType()
|
||||||
|
{
|
||||||
|
qmlRegisterType<QmlTextureNodeProxy>("HelperWidgets", 2, 0, "QmlTextureNodeProxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::setTextureNode(const QmlObjectNode &node)
|
||||||
|
{
|
||||||
|
if (m_textureNode == node)
|
||||||
|
return;
|
||||||
|
m_textureNode = node;
|
||||||
|
emit textureNodeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlTextureNodeProxy::setSelectedNodeAcceptsMaterial(bool value)
|
||||||
|
{
|
||||||
|
if (m_selectedNodeAcceptsMaterial == value)
|
||||||
|
return;
|
||||||
|
m_selectedNodeAcceptsMaterial = value;
|
||||||
|
emit selectedNodeAcceptsMaterialChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlTextureNodeProxy::hasQuick3DImport() const
|
||||||
|
{
|
||||||
|
return textureNode().isValid() && textureNode().model()->hasImport("QtQuick3D"_L1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmlobjectnode.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QmlTextureNodeProxy : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QmlObjectNode textureNode READ textureNode NOTIFY textureNodeChanged)
|
||||||
|
Q_PROPERTY(bool hasTexture READ hasTexture NOTIFY textureNodeChanged)
|
||||||
|
Q_PROPERTY(
|
||||||
|
bool selectedNodeAcceptsMaterial
|
||||||
|
READ selectedNodeAcceptsMaterial
|
||||||
|
NOTIFY selectedNodeAcceptsMaterialChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ToolBarAction {
|
||||||
|
ApplyToSelected,
|
||||||
|
AddNewTexture,
|
||||||
|
DeleteCurrentTexture,
|
||||||
|
OpenMaterialBrowser
|
||||||
|
};
|
||||||
|
Q_ENUM(ToolBarAction)
|
||||||
|
|
||||||
|
explicit QmlTextureNodeProxy();
|
||||||
|
~QmlTextureNodeProxy() override;
|
||||||
|
|
||||||
|
void setup(const QmlObjectNode &objectNode);
|
||||||
|
|
||||||
|
void updateSelectionDetails();
|
||||||
|
void handlePropertyChanged(const AbstractProperty &property);
|
||||||
|
void handleBindingPropertyChanged(const BindingProperty &property);
|
||||||
|
void handlePropertiesRemoved(const AbstractProperty &property);
|
||||||
|
|
||||||
|
QmlObjectNode textureNode() const;
|
||||||
|
bool hasTexture() const;
|
||||||
|
bool selectedNodeAcceptsMaterial() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE QString resolveResourcePath(const QString &path) const;
|
||||||
|
Q_INVOKABLE void toolbarAction(int action);
|
||||||
|
|
||||||
|
static void registerDeclarativeType();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textureNodeChanged();
|
||||||
|
void selectedNodeAcceptsMaterialChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setTextureNode(const QmlObjectNode &node);
|
||||||
|
void setSelectedNodeAcceptsMaterial(bool value);
|
||||||
|
bool hasQuick3DImport() const;
|
||||||
|
|
||||||
|
QmlObjectNode m_textureNode;
|
||||||
|
bool m_selectedNodeAcceptsMaterial = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -27,6 +27,7 @@
|
|||||||
#include "propertynamevalidator.h"
|
#include "propertynamevalidator.h"
|
||||||
#include "qmlanchorbindingproxy.h"
|
#include "qmlanchorbindingproxy.h"
|
||||||
#include "qmlmaterialnodeproxy.h"
|
#include "qmlmaterialnodeproxy.h"
|
||||||
|
#include "qmltexturenodeproxy.h"
|
||||||
#include "richtexteditor/richtexteditorproxy.h"
|
#include "richtexteditor/richtexteditorproxy.h"
|
||||||
#include "selectiondynamicpropertiesproxymodel.h"
|
#include "selectiondynamicpropertiesproxymodel.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
@@ -67,6 +68,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
|
|||||||
ColorPaletteBackend::registerDeclarativeType();
|
ColorPaletteBackend::registerDeclarativeType();
|
||||||
QmlAnchorBindingProxy::registerDeclarativeType();
|
QmlAnchorBindingProxy::registerDeclarativeType();
|
||||||
QmlMaterialNodeProxy::registerDeclarativeType();
|
QmlMaterialNodeProxy::registerDeclarativeType();
|
||||||
|
QmlTextureNodeProxy::registerDeclarativeType();
|
||||||
BindingEditor::registerDeclarativeType();
|
BindingEditor::registerDeclarativeType();
|
||||||
ActionEditor::registerDeclarativeType();
|
ActionEditor::registerDeclarativeType();
|
||||||
AnnotationEditor::registerDeclarativeType();
|
AnnotationEditor::registerDeclarativeType();
|
||||||
|
Reference in New Issue
Block a user