QmlDesigner: Remove TextureEditor view
Task-number: QDS-14625 Change-Id: I44f5289161b1c62a38a3fe4ec10f0a91384dce50 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
@@ -1,53 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import HelperWidgets
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
PropertyEditorPane {
|
||||
id: root
|
||||
|
||||
width: 420
|
||||
height: 420
|
||||
|
||||
signal toolBarAction(int action)
|
||||
|
||||
// Called from C++, dummy method to avoid warnings
|
||||
function closeContextMenu() {}
|
||||
|
||||
Column {
|
||||
id: col
|
||||
|
||||
TextureEditorToolBar {
|
||||
width: root.width
|
||||
|
||||
onToolBarAction: (action) => root.toolBarAction(action)
|
||||
}
|
||||
|
||||
Item {
|
||||
width: root.width - 2 * col.padding
|
||||
height: 150
|
||||
|
||||
Text {
|
||||
text: {
|
||||
if (!isQt6Project)
|
||||
qsTr("<b>Texture Editor</b> is not supported in Qt5 projects.")
|
||||
else if (!hasQuick3DImport)
|
||||
qsTr("To use <b>Texture Editor</b>, first add the QtQuick3D module in the <b>Components</b> view.")
|
||||
else if (!hasMaterialLibrary)
|
||||
qsTr("<b>Texture Editor</b> is disabled inside a non-visual component.")
|
||||
else
|
||||
qsTr("There are no textures in this project.<br>Select '<b>+</b>' to create one.")
|
||||
}
|
||||
textFormat: Text.RichText
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: StudioTheme.Values.mediumFontSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
width: root.width
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import HelperWidgets
|
||||
|
||||
PropertyEditorPane {
|
||||
id: itemPane
|
||||
|
||||
width: 420
|
||||
height: 420
|
||||
|
||||
signal toolBarAction(int action)
|
||||
|
||||
// invoked from C++ to refresh material preview image
|
||||
function refreshPreview()
|
||||
{
|
||||
topSection.refreshPreview()
|
||||
}
|
||||
|
||||
// Called from C++ to close context menu on focus out
|
||||
function closeContextMenu()
|
||||
{
|
||||
Controller.closeContextMenu()
|
||||
}
|
||||
|
||||
TextureEditorTopSection {
|
||||
id: topSection
|
||||
|
||||
onToolBarAction: (action) => itemPane.toolBarAction(action)
|
||||
}
|
||||
|
||||
Item { width: 1; height: 10 }
|
||||
|
||||
DynamicPropertiesSection {
|
||||
propertiesModel: TextureEditorDynamicPropertiesModel {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: specificsTwo
|
||||
|
||||
property string theSource: specificQmlData
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: specificsTwo.theSource !== ""
|
||||
sourceComponent: specificQmlComponent
|
||||
|
||||
onTheSourceChanged: {
|
||||
specificsTwo.active = false
|
||||
specificsTwo.active = true
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 1
|
||||
height: 10
|
||||
visible: specificsTwo.visible
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: specificsOne
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
source: specificsUrl
|
||||
}
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioTheme as StudioTheme
|
||||
import TextureToolBarAction
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
color: StudioTheme.Values.themeToolbarBackground
|
||||
height: StudioTheme.Values.toolbarHeight
|
||||
width: row.width
|
||||
|
||||
signal toolBarAction(int action)
|
||||
|
||||
Row {
|
||||
id: row
|
||||
spacing: StudioTheme.Values.toolbarSpacing
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
leftPadding: 6
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.apply_medium
|
||||
enabled: hasTexture && hasSingleModelSelection && hasQuick3DImport && hasMaterialLibrary
|
||||
tooltip: qsTr("Apply texture to selected model's material.")
|
||||
onClicked: root.toolBarAction(ToolBarAction.ApplyToSelected)
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.create_medium
|
||||
enabled: hasQuick3DImport && hasMaterialLibrary
|
||||
tooltip: qsTr("Create new texture.")
|
||||
onClicked: root.toolBarAction(ToolBarAction.AddNewTexture)
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.delete_medium
|
||||
enabled: hasTexture && hasQuick3DImport && hasMaterialLibrary
|
||||
tooltip: qsTr("Delete current texture.")
|
||||
onClicked: root.toolBarAction(ToolBarAction.DeleteCurrentTexture)
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.materialBrowser_medium
|
||||
enabled: hasTexture && hasQuick3DImport && hasMaterialLibrary
|
||||
tooltip: qsTr("Open material browser.")
|
||||
onClicked: root.toolBarAction(ToolBarAction.OpenMaterialBrowser)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
signal toolBarAction(int action)
|
||||
|
||||
function refreshPreview()
|
||||
{
|
||||
texturePreview.source = ""
|
||||
texturePreview.source = "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString)
|
||||
}
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
TextureEditorToolBar {
|
||||
width: root.width
|
||||
|
||||
onToolBarAction: (action) => root.toolBarAction(action)
|
||||
}
|
||||
|
||||
Item { width: 1; height: 10 } // spacer
|
||||
|
||||
Rectangle {
|
||||
id: previewRect
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 152
|
||||
height: 152
|
||||
color: "#000000"
|
||||
|
||||
Image {
|
||||
id: texturePreview
|
||||
asynchronous: true
|
||||
width: 150
|
||||
height: 150
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
source: "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString)
|
||||
}
|
||||
}
|
||||
|
||||
HelperWidgets.Section {
|
||||
id: nameSection
|
||||
|
||||
// Section with hidden header is used so properties are aligned with the other sections' properties
|
||||
hideHeader: true
|
||||
implicitWidth: root.width
|
||||
bottomPadding: StudioTheme.Values.sectionPadding * 2
|
||||
collapsible: false
|
||||
|
||||
HelperWidgets.SectionLayout {
|
||||
HelperWidgets.PropertyLabel { text: qsTr("Name") }
|
||||
|
||||
HelperWidgets.SecondColumnLayout {
|
||||
HelperWidgets.Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
||||
|
||||
HelperWidgets.LineEdit {
|
||||
id: texName
|
||||
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
width: StudioTheme.Values.singleControlColumnWidth
|
||||
placeholderText: qsTr("Texture name")
|
||||
showTranslateCheckBox: false
|
||||
showExtendedFunctionButton: false
|
||||
|
||||
Timer {
|
||||
running: true
|
||||
interval: 0
|
||||
onTriggered: texName.backendValue = backendValues.objectName
|
||||
// backendValues.objectName is not available yet without the Timer
|
||||
}
|
||||
|
||||
// allow only alphanumeric characters, underscores, no space at start, and 1 space between words
|
||||
validator: RegularExpressionValidator { regularExpression: /^(\w+\s)*\w+$/ }
|
||||
}
|
||||
|
||||
HelperWidgets.ExpandingSpacer {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -52,7 +52,6 @@
|
||||
<splitter orientation="Vertical" count="2">
|
||||
<area tabs="3" current="Properties">
|
||||
<widget name="Properties" closed="false"/>
|
||||
<widget name="TextureEditor" closed="false"/>
|
||||
</area>
|
||||
<area tabs="3" current="MaterialBrowser">
|
||||
<widget name="MaterialBrowser" closed="false"/>
|
||||
|
@@ -42,7 +42,6 @@
|
||||
<splitter count="2" orientation="Vertical">
|
||||
<area current="Properties" tabs="4">
|
||||
<widget closed="false" name="Properties"/>
|
||||
<widget closed="false" name="TextureEditor"/>
|
||||
<widget closed="true" name="ConnectionView"/>
|
||||
</area>
|
||||
<area current="MaterialBrowser" tabs="1">
|
||||
|
@@ -82,7 +82,6 @@ add_qtc_plugin(QmlDesigner
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/integration
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/itemlibrary
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/materialbrowser
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/textureeditor
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/navigator
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/propertyeditor
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/stateseditor
|
||||
@@ -461,17 +460,6 @@ extend_qtc_plugin(QmlDesigner
|
||||
usertexturecategory.cpp usertexturecategory.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/textureeditor
|
||||
SOURCES
|
||||
textureeditorcontextobject.cpp textureeditorcontextobject.h
|
||||
textureeditordynamicpropertiesproxymodel.cpp textureeditordynamicpropertiesproxymodel.h
|
||||
textureeditorqmlbackend.cpp textureeditorqmlbackend.h
|
||||
textureeditortransaction.cpp textureeditortransaction.h
|
||||
textureeditorview.cpp textureeditorview.h
|
||||
textureeditor.qrc
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/materialbrowser
|
||||
SOURCES
|
||||
|
@@ -88,7 +88,7 @@ ModelNode CreateTexture::execute()
|
||||
});
|
||||
|
||||
QTimer::singleShot(0, m_view, [newTextureNode]() {
|
||||
Utils3D::selectTexture(newTextureNode);
|
||||
Utils3D::openNodeInPropertyEditor(newTextureNode);
|
||||
});
|
||||
|
||||
return newTextureNode;
|
||||
@@ -120,7 +120,7 @@ ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, i
|
||||
QTimer::singleShot(0, m_view, [view = m_view, texture]() {
|
||||
if (view && view->model() && texture.isValid()) {
|
||||
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser");
|
||||
Utils3D::selectTexture(texture);
|
||||
Utils3D::openNodeInPropertyEditor(texture);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -187,25 +187,6 @@ ModelNode getMaterialOfModel(const ModelNode &model, int idx)
|
||||
return mat;
|
||||
}
|
||||
|
||||
void selectTexture(const ModelNode &texture)
|
||||
{
|
||||
if (texture.metaInfo().isQtQuick3DTexture()) {
|
||||
texture.model()->rootModelNode().setAuxiliaryData(Utils3D::matLibSelectedTextureProperty,
|
||||
texture.id());
|
||||
}
|
||||
}
|
||||
|
||||
ModelNode selectedTexture(AbstractView *view)
|
||||
{
|
||||
if (!view)
|
||||
return {};
|
||||
|
||||
ModelNode root = view->rootModelNode();
|
||||
if (auto selectedProperty = root.auxiliaryData(Utils3D::matLibSelectedTextureProperty))
|
||||
return view->modelNodeForId(selectedProperty->toString());
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<ModelNode> getSelectedModels(AbstractView *view)
|
||||
{
|
||||
if (!view || !view->model())
|
||||
|
@@ -15,9 +15,6 @@ namespace Utils3D {
|
||||
|
||||
inline constexpr AuxiliaryDataKeyView active3dSceneProperty{AuxiliaryDataType::Temporary,
|
||||
"active3dScene"};
|
||||
inline constexpr AuxiliaryDataKeyView matLibSelectedTextureProperty{AuxiliaryDataType::Temporary,
|
||||
"matLibSelTex"};
|
||||
|
||||
ModelNode active3DSceneNode(AbstractView *view);
|
||||
qint32 active3DSceneId(Model *model);
|
||||
|
||||
@@ -30,12 +27,6 @@ ModelNode activeView3dNode(AbstractView *view);
|
||||
QString activeView3dId(AbstractView *view);
|
||||
|
||||
ModelNode getMaterialOfModel(const ModelNode &model, int idx = 0);
|
||||
|
||||
// These methods handle selection of material library items for various material library views.
|
||||
// This is separate selection from the normal selection handling.
|
||||
void selectTexture(const ModelNode &texture);
|
||||
ModelNode selectedTexture(AbstractView *view);
|
||||
|
||||
ModelNode resolveSceneEnv(AbstractView *view, int sceneId);
|
||||
|
||||
QList<ModelNode> getSelectedModels(AbstractView *view);
|
||||
|
@@ -28,7 +28,6 @@
|
||||
#include <rewriterview.h>
|
||||
#include <stateseditorview.h>
|
||||
#include <texteditorview.h>
|
||||
#include <textureeditorview.h>
|
||||
|
||||
#include <qmldesignerbase/settings/designersettings.h>
|
||||
|
||||
@@ -73,7 +72,6 @@ public:
|
||||
, propertyEditorView(imageCache, externalDependencies)
|
||||
#ifndef QTC_USE_QML_DESIGNER_LITE
|
||||
, materialBrowserView{imageCache, externalDependencies}
|
||||
, textureEditorView{imageCache, externalDependencies}
|
||||
#endif
|
||||
, statesEditorView{externalDependencies}
|
||||
{}
|
||||
@@ -102,7 +100,6 @@ public:
|
||||
PropertyEditorView propertyEditorView;
|
||||
#ifndef QTC_USE_QML_DESIGNER_LITE
|
||||
MaterialBrowserView materialBrowserView;
|
||||
TextureEditorView textureEditorView;
|
||||
#endif
|
||||
StatesEditorView statesEditorView;
|
||||
|
||||
@@ -231,7 +228,6 @@ QList<AbstractView *> ViewManager::standardViews() const
|
||||
&d->navigatorView,
|
||||
&d->propertyEditorView,
|
||||
&d->materialBrowserView,
|
||||
&d->textureEditorView,
|
||||
&d->statesEditorView,
|
||||
&d->designerActionManagerView};
|
||||
#else
|
||||
@@ -457,7 +453,6 @@ QList<WidgetInfo> ViewManager::widgetInfos() const
|
||||
widgetInfoList.append(d->propertyEditorView.widgetInfo());
|
||||
#ifndef QTC_USE_QML_DESIGNER_LITE
|
||||
widgetInfoList.append(d->materialBrowserView.widgetInfo());
|
||||
widgetInfoList.append(d->textureEditorView.widgetInfo());
|
||||
#endif
|
||||
widgetInfoList.append(d->statesEditorView.widgetInfo());
|
||||
|
||||
|
@@ -179,21 +179,6 @@ void ComponentView::ensureMatLibTriggered()
|
||||
DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (doc && !doc->inFileComponentModelActive())
|
||||
Utils3D::ensureMaterialLibraryNode(this);
|
||||
|
||||
matLib = Utils3D::materialLibraryNode(this);
|
||||
if (!matLib.isValid())
|
||||
return;
|
||||
|
||||
bool texSelected = Utils3D::selectedTexture(this).isValid();
|
||||
if (!texSelected) {
|
||||
const QList<ModelNode> matLibNodes = matLib.directSubModelNodes();
|
||||
for (const ModelNode &node : matLibNodes) {
|
||||
if (node.metaInfo().isQtQuick3DTexture()) {
|
||||
Utils3D::selectTexture(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentView::modelAttached(Model *model)
|
||||
@@ -263,30 +248,11 @@ void ComponentView::nodeReparented(const ModelNode &node, const NodeAbstractProp
|
||||
updateDescription(node);
|
||||
}
|
||||
|
||||
void ComponentView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId)
|
||||
void ComponentView::nodeIdChanged(const ModelNode &node,
|
||||
[[maybe_unused]] const QString &newId,
|
||||
[[maybe_unused]] const QString &oldId)
|
||||
{
|
||||
updateDescription(node);
|
||||
|
||||
if (oldId.isEmpty())
|
||||
return;
|
||||
|
||||
// Material/texture id handling is done here as ComponentView is guaranteed to always be
|
||||
// attached, unlike the views actually related to material/texture handling.
|
||||
|
||||
auto maybeSetAuxData = [this, &oldId, &newId](AuxiliaryDataKeyView key) {
|
||||
auto rootNode = rootModelNode();
|
||||
if (auto property = rootNode.auxiliaryData(key)) {
|
||||
if (oldId == property->toString()) {
|
||||
QTimer::singleShot(0, this, [rootNode, newId, key]() {
|
||||
rootNode.setAuxiliaryData(key, newId);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto metaInfo = node.metaInfo();
|
||||
if (metaInfo.isQtQuick3DTexture())
|
||||
maybeSetAuxData(Utils3D::matLibSelectedTextureProperty);
|
||||
}
|
||||
|
||||
void ComponentView::nodeSourceChanged(const ModelNode &node, const QString &/*newNodeSource*/)
|
||||
|
@@ -40,7 +40,7 @@ public:
|
||||
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
AbstractView::PropertyChangeFlags propertyChange) override;
|
||||
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
|
||||
void nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) override;
|
||||
void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override;
|
||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
||||
|
@@ -180,7 +180,6 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
||||
});
|
||||
});
|
||||
|
||||
// custom notifications below are sent to the TextureEditor
|
||||
MaterialBrowserTexturesModel *texturesModel = m_widget->materialBrowserTexturesModel().data();
|
||||
connect(texturesModel,
|
||||
&MaterialBrowserTexturesModel::duplicateTextureTriggered,
|
||||
@@ -315,9 +314,14 @@ void MaterialBrowserView::updatePropertyList(const QList<T> &propertyList)
|
||||
else if (property.name() == "objectName")
|
||||
m_widget->materialBrowserTexturesModel()->updateTextureName(node);
|
||||
} else {
|
||||
QmlObjectNode selectedTex = Utils3D::selectedTexture(this);
|
||||
if (property.name() == "source" && selectedTex.propertyChangeForCurrentState() == node)
|
||||
m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex);
|
||||
if (property.name() == "source") {
|
||||
const ModelNodes textures = m_widget->materialBrowserTexturesModel()->textures();
|
||||
for (const ModelNode &textureNode : textures) {
|
||||
const QmlObjectNode textureQmlNode{textureNode};
|
||||
if (textureQmlNode.propertyChangeForCurrentState() == node)
|
||||
m_widget->materialBrowserTexturesModel()->updateTextureSource(textureQmlNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -135,11 +135,13 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
if (suffix == "hdr")
|
||||
pixmap = HdrImage{iconPath}.toPixmap();
|
||||
else if (suffix == "ktx")
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_ktx.png");
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(
|
||||
":/propertyeditor/images/texture_ktx.png");
|
||||
else
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(iconPath);
|
||||
if (pixmap.isNull())
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png");
|
||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(
|
||||
":/propertyeditor/images/texture_default.png");
|
||||
model->startDrag(std::move(mimeData), pixmap.scaled({128, 128}), this);
|
||||
}
|
||||
m_materialToDrag = {};
|
||||
@@ -166,7 +168,8 @@ MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache,
|
||||
, m_bundleHelper(std::make_unique<BundleHelper>(view, this))
|
||||
{
|
||||
QImage defaultImage;
|
||||
defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"));
|
||||
defaultImage.load(
|
||||
Utils::StyleHelper::dpiSpecificImageFile(":/propertyeditor/images/texture_default.png"));
|
||||
m_textureImageProvider = new AssetImageProvider(imageCache, defaultImage);
|
||||
|
||||
setWindowTitle(tr("Material Browser", "Title of material browser widget"));
|
||||
|
@@ -31,7 +31,8 @@ QQuickImageResponse *AssetImageProvider::requestImageResponse(const QString &id,
|
||||
response.get(),
|
||||
[response = QPointer<ImageCacheImageResponse>(response.get()), requestedSize] {
|
||||
QImage ktxImage;
|
||||
ktxImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_ktx.png"));
|
||||
ktxImage.load(Utils::StyleHelper::dpiSpecificImageFile(
|
||||
":/propertyeditor/images/texture_ktx.png"));
|
||||
if (ktxImage.isNull())
|
||||
ktxImage = response->image();
|
||||
if (requestedSize.isValid())
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
@@ -1,5 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="/propertyeditor">
|
||||
<file>images/defaultmaterialpreview.png</file>
|
||||
<file>images/texture_default.png</file>
|
||||
<file>images/texture_default@2x.png</file>
|
||||
<file>images/texture_ktx.png</file>
|
||||
<file>images/texture_ktx@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -90,6 +90,9 @@ bool QmlTextureNodeProxy::selectedNodeAcceptsMaterial() const
|
||||
|
||||
QString QmlTextureNodeProxy::resolveResourcePath(const QString &path) const
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return ":/propertyeditor/images/texture_default.png";
|
||||
|
||||
if (Utils::FilePath::fromString(path).isAbsolutePath())
|
||||
return path;
|
||||
|
||||
|
@@ -1,8 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/textureeditor">
|
||||
<file>images/texture_default.png</file>
|
||||
<file>images/texture_default@2x.png</file>
|
||||
<file>images/texture_ktx.png</file>
|
||||
<file>images/texture_ktx@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@@ -1,351 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textureeditorcontextobject.h"
|
||||
|
||||
#include "abstractview.h"
|
||||
#include "documentmanager.h"
|
||||
#include "model.h"
|
||||
#include "qmldesignerplugin.h"
|
||||
#include "qmlobjectnode.h"
|
||||
#include "qmltimeline.h"
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
#include <QMessageBox>
|
||||
#include <QQmlContext>
|
||||
#include <QWindow>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TextureEditorContextObject::TextureEditorContextObject(QQmlContext *context, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_qmlContext(context)
|
||||
{
|
||||
qmlRegisterUncreatableType<TextureEditorContextObject>("TextureToolBarAction", 1, 0, "ToolBarAction", "Enum type");
|
||||
}
|
||||
|
||||
QQmlComponent *TextureEditorContextObject::specificQmlComponent()
|
||||
{
|
||||
if (m_specificQmlComponent)
|
||||
return m_specificQmlComponent;
|
||||
|
||||
m_specificQmlComponent = new QQmlComponent(m_qmlContext->engine(), this);
|
||||
m_specificQmlComponent->setData(m_specificQmlData.toUtf8(), QUrl::fromLocalFile("specifics.qml"));
|
||||
|
||||
return m_specificQmlComponent;
|
||||
}
|
||||
|
||||
QString TextureEditorContextObject::convertColorToString(const QVariant &color)
|
||||
{
|
||||
QString colorString;
|
||||
QColor theColor;
|
||||
if (color.canConvert(QMetaType(QMetaType::QColor))) {
|
||||
theColor = color.value<QColor>();
|
||||
} else if (color.canConvert(QMetaType(QMetaType::QVector3D))) {
|
||||
auto vec = color.value<QVector3D>();
|
||||
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
||||
}
|
||||
|
||||
colorString = theColor.name();
|
||||
|
||||
if (theColor.alpha() != 255) {
|
||||
QString hexAlpha = QString("%1").arg(theColor.alpha(), 2, 16, QLatin1Char('0'));
|
||||
colorString.remove(0, 1);
|
||||
colorString.prepend(hexAlpha);
|
||||
colorString.prepend(QStringLiteral("#"));
|
||||
}
|
||||
return colorString;
|
||||
}
|
||||
|
||||
// TODO: this method is used by the ColorEditor helper widget, check if at all needed?
|
||||
QColor TextureEditorContextObject::colorFromString(const QString &colorString)
|
||||
{
|
||||
return colorString;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::insertKeyframe(const QString &propertyName)
|
||||
{
|
||||
QTC_ASSERT(m_model && m_model->rewriterView(), return);
|
||||
QTC_ASSERT(m_selectedTexture.isValid(), return);
|
||||
|
||||
// Ideally we should not missuse the rewriterView
|
||||
// If we add more code here we have to forward the material editor view
|
||||
RewriterView *rewriterView = m_model->rewriterView();
|
||||
|
||||
QmlTimeline timeline = rewriterView->currentTimelineNode();
|
||||
|
||||
QTC_ASSERT(timeline.isValid(), return);
|
||||
|
||||
rewriterView->executeInTransaction("TextureEditorContextObject::insertKeyframe", [&] {
|
||||
timeline.insertKeyframe(m_selectedTexture, propertyName.toUtf8());
|
||||
});
|
||||
}
|
||||
|
||||
int TextureEditorContextObject::majorVersion() const
|
||||
{
|
||||
return m_majorVersion;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setMajorVersion(int majorVersion)
|
||||
{
|
||||
if (m_majorVersion == majorVersion)
|
||||
return;
|
||||
|
||||
m_majorVersion = majorVersion;
|
||||
|
||||
emit majorVersionChanged();
|
||||
}
|
||||
|
||||
QString TextureEditorContextObject::activeDragSuffix() const
|
||||
{
|
||||
return m_activeDragSuffix;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setActiveDragSuffix(const QString &suffix)
|
||||
{
|
||||
if (m_activeDragSuffix != suffix) {
|
||||
m_activeDragSuffix = suffix;
|
||||
emit activeDragSuffixChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::hasActiveTimeline() const
|
||||
{
|
||||
return m_hasActiveTimeline;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setHasActiveTimeline(bool b)
|
||||
{
|
||||
if (b == m_hasActiveTimeline)
|
||||
return;
|
||||
|
||||
m_hasActiveTimeline = b;
|
||||
emit hasActiveTimelineChanged();
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::hasQuick3DImport() const
|
||||
{
|
||||
return m_hasQuick3DImport;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setHasQuick3DImport(bool b)
|
||||
{
|
||||
if (b == m_hasQuick3DImport)
|
||||
return;
|
||||
|
||||
m_hasQuick3DImport = b;
|
||||
emit hasQuick3DImportChanged();
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::hasMaterialLibrary() const
|
||||
{
|
||||
return m_hasMaterialLibrary;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setHasMaterialLibrary(bool b)
|
||||
{
|
||||
if (b == m_hasMaterialLibrary)
|
||||
return;
|
||||
|
||||
m_hasMaterialLibrary = b;
|
||||
emit hasMaterialLibraryChanged();
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::isQt6Project() const
|
||||
{
|
||||
return m_isQt6Project;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setIsQt6Project(bool b)
|
||||
{
|
||||
if (m_isQt6Project == b)
|
||||
return;
|
||||
|
||||
m_isQt6Project = b;
|
||||
emit isQt6ProjectChanged();
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::hasSingleModelSelection() const
|
||||
{
|
||||
return m_hasSingleModelSelection;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setHasSingleModelSelection(bool b)
|
||||
{
|
||||
if (b == m_hasSingleModelSelection)
|
||||
return;
|
||||
|
||||
m_hasSingleModelSelection = b;
|
||||
emit hasSingleModelSelectionChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setSelectedMaterial(const ModelNode &matNode)
|
||||
{
|
||||
m_selectedTexture = matNode;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setSpecificsUrl(const QUrl &newSpecificsUrl)
|
||||
{
|
||||
if (newSpecificsUrl == m_specificsUrl)
|
||||
return;
|
||||
|
||||
m_specificsUrl = newSpecificsUrl;
|
||||
emit specificsUrlChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setSpecificQmlData(const QString &newSpecificQmlData)
|
||||
{
|
||||
if (newSpecificQmlData == m_specificQmlData)
|
||||
return;
|
||||
|
||||
m_specificQmlData = newSpecificQmlData;
|
||||
|
||||
delete m_specificQmlComponent;
|
||||
m_specificQmlComponent = nullptr;
|
||||
|
||||
emit specificQmlComponentChanged();
|
||||
emit specificQmlDataChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setStateName(const QString &newStateName)
|
||||
{
|
||||
if (newStateName == m_stateName)
|
||||
return;
|
||||
|
||||
m_stateName = newStateName;
|
||||
emit stateNameChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setAllStateNames(const QStringList &allStates)
|
||||
{
|
||||
if (allStates == m_allStateNames)
|
||||
return;
|
||||
|
||||
m_allStateNames = allStates;
|
||||
emit allStateNamesChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setIsBaseState(bool newIsBaseState)
|
||||
{
|
||||
if (newIsBaseState == m_isBaseState)
|
||||
return;
|
||||
|
||||
m_isBaseState = newIsBaseState;
|
||||
emit isBaseStateChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setSelectionChanged(bool newSelectionChanged)
|
||||
{
|
||||
if (newSelectionChanged == m_selectionChanged)
|
||||
return;
|
||||
|
||||
m_selectionChanged = newSelectionChanged;
|
||||
emit selectionChangedChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setBackendValues(QQmlPropertyMap *newBackendValues)
|
||||
{
|
||||
if (newBackendValues == m_backendValues)
|
||||
return;
|
||||
|
||||
m_backendValues = newBackendValues;
|
||||
emit backendValuesChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setModel(Model *model)
|
||||
{
|
||||
m_model = model;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::triggerSelectionChanged()
|
||||
{
|
||||
setSelectionChanged(!m_selectionChanged);
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::setHasAliasExport(bool hasAliasExport)
|
||||
{
|
||||
if (m_aliasExport == hasAliasExport)
|
||||
return;
|
||||
|
||||
m_aliasExport = hasAliasExport;
|
||||
emit hasAliasExportChanged();
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::hideCursor()
|
||||
{
|
||||
if (QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
m_lastPos = QCursor::pos(w->screen());
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::restoreCursor()
|
||||
{
|
||||
if (!QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::holdCursorInPlace()
|
||||
{
|
||||
if (!QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
int TextureEditorContextObject::devicePixelRatio()
|
||||
{
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
return w->devicePixelRatio();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
QStringList TextureEditorContextObject::allStatesForId(const QString &id)
|
||||
{
|
||||
if (m_model && m_model->rewriterView()) {
|
||||
const QmlObjectNode node = m_model->rewriterView()->modelNodeForId(id);
|
||||
if (node.isValid())
|
||||
return node.allStateNames();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool TextureEditorContextObject::isBlocked(const QString &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextureEditorContextObject::goIntoComponent()
|
||||
{
|
||||
QTC_ASSERT(m_model, return);
|
||||
DocumentManager::goIntoComponent(m_selectedTexture);
|
||||
}
|
||||
|
||||
QString TextureEditorContextObject::resolveResourcePath(const QString &path)
|
||||
{
|
||||
if (Utils::FilePath::fromString(path).isAbsolutePath())
|
||||
return path;
|
||||
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()
|
||||
->fileName().absolutePath().pathAppended(path).cleanPath().toUrlishString();
|
||||
}
|
||||
|
||||
} // QmlDesigner
|
@@ -1,172 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <modelnode.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QObject>
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlPropertyMap>
|
||||
#include <QColor>
|
||||
#include <QPoint>
|
||||
#include <QUrl>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Model;
|
||||
|
||||
class TextureEditorContextObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QUrl specificsUrl READ specificsUrl WRITE setSpecificsUrl NOTIFY specificsUrlChanged)
|
||||
Q_PROPERTY(QString specificQmlData READ specificQmlData WRITE setSpecificQmlData NOTIFY specificQmlDataChanged)
|
||||
Q_PROPERTY(QQmlComponent *specificQmlComponent READ specificQmlComponent NOTIFY specificQmlComponentChanged)
|
||||
|
||||
Q_PROPERTY(QString stateName READ stateName WRITE setStateName NOTIFY stateNameChanged)
|
||||
Q_PROPERTY(QStringList allStateNames READ allStateNames WRITE setAllStateNames NOTIFY allStateNamesChanged)
|
||||
|
||||
Q_PROPERTY(bool isBaseState READ isBaseState WRITE setIsBaseState NOTIFY isBaseStateChanged)
|
||||
Q_PROPERTY(bool selectionChanged READ selectionChanged WRITE setSelectionChanged NOTIFY selectionChangedChanged)
|
||||
|
||||
Q_PROPERTY(int majorVersion READ majorVersion WRITE setMajorVersion NOTIFY majorVersionChanged)
|
||||
|
||||
Q_PROPERTY(bool hasAliasExport READ hasAliasExport NOTIFY hasAliasExportChanged)
|
||||
Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged)
|
||||
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
||||
Q_PROPERTY(bool hasSingleModelSelection READ hasSingleModelSelection WRITE setHasSingleModelSelection
|
||||
NOTIFY hasSingleModelSelectionChanged)
|
||||
Q_PROPERTY(bool hasMaterialLibrary READ hasMaterialLibrary WRITE setHasMaterialLibrary NOTIFY hasMaterialLibraryChanged)
|
||||
Q_PROPERTY(bool isQt6Project READ isQt6Project NOTIFY isQt6ProjectChanged)
|
||||
|
||||
Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
|
||||
|
||||
Q_PROPERTY(QString activeDragSuffix READ activeDragSuffix NOTIFY activeDragSuffixChanged)
|
||||
|
||||
public:
|
||||
TextureEditorContextObject(QQmlContext *context, QObject *parent = nullptr);
|
||||
|
||||
QUrl specificsUrl() const { return m_specificsUrl; }
|
||||
QString specificQmlData() const {return m_specificQmlData; }
|
||||
QQmlComponent *specificQmlComponent();
|
||||
QString stateName() const { return m_stateName; }
|
||||
QStringList allStateNames() const { return m_allStateNames; }
|
||||
|
||||
bool isBaseState() const { return m_isBaseState; }
|
||||
bool selectionChanged() const { return m_selectionChanged; }
|
||||
|
||||
QQmlPropertyMap *backendValues() const { return m_backendValues; }
|
||||
|
||||
Q_INVOKABLE QString convertColorToString(const QVariant &color);
|
||||
Q_INVOKABLE QColor colorFromString(const QString &colorString);
|
||||
|
||||
Q_INVOKABLE void insertKeyframe(const QString &propertyName);
|
||||
|
||||
Q_INVOKABLE void hideCursor();
|
||||
Q_INVOKABLE void restoreCursor();
|
||||
Q_INVOKABLE void holdCursorInPlace();
|
||||
|
||||
Q_INVOKABLE int devicePixelRatio();
|
||||
|
||||
Q_INVOKABLE QStringList allStatesForId(const QString &id);
|
||||
|
||||
Q_INVOKABLE bool isBlocked(const QString &propName) const;
|
||||
Q_INVOKABLE void goIntoComponent();
|
||||
Q_INVOKABLE QString resolveResourcePath(const QString &path);
|
||||
|
||||
enum ToolBarAction {
|
||||
ApplyToSelected,
|
||||
AddNewTexture,
|
||||
DeleteCurrentTexture,
|
||||
OpenMaterialBrowser
|
||||
};
|
||||
Q_ENUM(ToolBarAction)
|
||||
|
||||
int majorVersion() const;
|
||||
void setMajorVersion(int majorVersion);
|
||||
|
||||
bool hasActiveTimeline() const;
|
||||
void setHasActiveTimeline(bool b);
|
||||
|
||||
bool hasQuick3DImport() const;
|
||||
void setHasQuick3DImport(bool b);
|
||||
|
||||
bool hasMaterialLibrary() const;
|
||||
void setHasMaterialLibrary(bool b);
|
||||
|
||||
bool isQt6Project() const;
|
||||
void setIsQt6Project(bool b);
|
||||
|
||||
bool hasSingleModelSelection() const;
|
||||
void setHasSingleModelSelection(bool b);
|
||||
|
||||
QString activeDragSuffix() const;
|
||||
void setActiveDragSuffix(const QString &suffix);
|
||||
|
||||
bool hasAliasExport() const { return m_aliasExport; }
|
||||
|
||||
void setSelectedMaterial(const ModelNode &matNode);
|
||||
|
||||
void setSpecificsUrl(const QUrl &newSpecificsUrl);
|
||||
void setSpecificQmlData(const QString &newSpecificQmlData);
|
||||
void setStateName(const QString &newStateName);
|
||||
void setAllStateNames(const QStringList &allStates);
|
||||
void setIsBaseState(bool newIsBaseState);
|
||||
void setSelectionChanged(bool newSelectionChanged);
|
||||
void setBackendValues(QQmlPropertyMap *newBackendValues);
|
||||
void setModel(Model *model);
|
||||
|
||||
void triggerSelectionChanged();
|
||||
void setHasAliasExport(bool hasAliasExport);
|
||||
|
||||
signals:
|
||||
void specificsUrlChanged();
|
||||
void specificQmlDataChanged();
|
||||
void specificQmlComponentChanged();
|
||||
void stateNameChanged();
|
||||
void allStateNamesChanged();
|
||||
void isBaseStateChanged();
|
||||
void selectionChangedChanged();
|
||||
void backendValuesChanged();
|
||||
void majorVersionChanged();
|
||||
void hasAliasExportChanged();
|
||||
void hasActiveTimelineChanged();
|
||||
void hasQuick3DImportChanged();
|
||||
void hasMaterialLibraryChanged();
|
||||
void hasSingleModelSelectionChanged();
|
||||
void activeDragSuffixChanged();
|
||||
void isQt6ProjectChanged();
|
||||
|
||||
private:
|
||||
QUrl m_specificsUrl;
|
||||
QString m_specificQmlData;
|
||||
QQmlComponent *m_specificQmlComponent = nullptr;
|
||||
QQmlContext *m_qmlContext = nullptr;
|
||||
|
||||
QString m_stateName;
|
||||
QStringList m_allStateNames;
|
||||
|
||||
int m_majorVersion = 1;
|
||||
|
||||
QQmlPropertyMap *m_backendValues = nullptr;
|
||||
Model *m_model = nullptr;
|
||||
|
||||
QPoint m_lastPos;
|
||||
|
||||
bool m_isBaseState = false;
|
||||
bool m_selectionChanged = false;
|
||||
bool m_aliasExport = false;
|
||||
bool m_hasActiveTimeline = false;
|
||||
bool m_hasQuick3DImport = false;
|
||||
bool m_hasMaterialLibrary = false;
|
||||
bool m_hasSingleModelSelection = false;
|
||||
bool m_isQt6Project = false;
|
||||
|
||||
ModelNode m_selectedTexture;
|
||||
|
||||
QString m_activeDragSuffix;
|
||||
};
|
||||
|
||||
} // QmlDesigner
|
@@ -1,24 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textureeditordynamicpropertiesproxymodel.h"
|
||||
|
||||
#include "dynamicpropertiesmodel.h"
|
||||
#include "textureeditorview.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TextureEditorDynamicPropertiesProxyModel::TextureEditorDynamicPropertiesProxyModel(QObject *parent)
|
||||
: DynamicPropertiesProxyModel(parent)
|
||||
{
|
||||
if (TextureEditorView::instance())
|
||||
initModel(TextureEditorView::instance()->dynamicPropertiesModel());
|
||||
}
|
||||
|
||||
void TextureEditorDynamicPropertiesProxyModel::registerDeclarativeType()
|
||||
{
|
||||
DynamicPropertiesProxyModel::registerDeclarativeType();
|
||||
qmlRegisterType<TextureEditorDynamicPropertiesProxyModel>("HelperWidgets", 2, 0, "TextureEditorDynamicPropertiesModel");
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,20 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dynamicpropertiesproxymodel.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TextureEditorDynamicPropertiesProxyModel : public DynamicPropertiesProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TextureEditorDynamicPropertiesProxyModel(QObject *parent = nullptr);
|
||||
|
||||
static void registerDeclarativeType();
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,292 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textureeditorqmlbackend.h"
|
||||
|
||||
#include "assetimageprovider.h"
|
||||
#include "bindingproperty.h"
|
||||
#include "nodemetainfo.h"
|
||||
#include "propertyeditorvalue.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
#include "qmlobjectnode.h"
|
||||
#include "qmltimeline.h"
|
||||
#include "textureeditorcontextobject.h"
|
||||
#include "textureeditortransaction.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QQuickImageProvider>
|
||||
#include <QQuickWidget>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QVector4D>
|
||||
|
||||
static QObject *variantToQObject(const QVariant &value)
|
||||
{
|
||||
if (value.typeId() == QMetaType::QObjectStar || value.typeId() > QMetaType::User)
|
||||
return *(QObject **)value.constData();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TextureEditorQmlBackend::TextureEditorQmlBackend(TextureEditorView *textureEditor,
|
||||
AsynchronousImageCache &imageCache)
|
||||
: m_quickWidget(Utils::makeUniqueObjectPtr<QQuickWidget>())
|
||||
, m_textureEditorTransaction(std::make_unique<TextureEditorTransaction>(textureEditor))
|
||||
, m_contextObject(std::make_unique<TextureEditorContextObject>(m_quickWidget->rootContext()))
|
||||
{
|
||||
QImage defaultImage;
|
||||
defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"));
|
||||
m_textureEditorImageProvider = new AssetImageProvider(imageCache, defaultImage);
|
||||
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_quickWidget->setObjectName(Constants::OBJECT_NAME_TEXTURE_EDITOR);
|
||||
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
m_quickWidget->engine()->addImageProvider("qmldesigner_thumbnails", m_textureEditorImageProvider);
|
||||
m_contextObject->setBackendValues(&m_backendValuesPropertyMap);
|
||||
m_contextObject->setModel(textureEditor->model());
|
||||
context()->setContextObject(m_contextObject.get());
|
||||
context()->setContextProperty("hasTexture", QVariant(false));
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
|
||||
QObject::connect(&m_backendValuesPropertyMap, &DesignerPropertyMap::valueChanged,
|
||||
textureEditor, &TextureEditorView::changeValue);
|
||||
}
|
||||
|
||||
TextureEditorQmlBackend::~TextureEditorQmlBackend()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyName TextureEditorQmlBackend::auxNamePostFix(PropertyNameView propertyName)
|
||||
{
|
||||
return propertyName + "__AUX";
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
|
||||
PropertyNameView name,
|
||||
const QVariant &value,
|
||||
TextureEditorView *textureEditor)
|
||||
{
|
||||
PropertyName propertyName(name.toByteArray());
|
||||
propertyName.replace('.', '_');
|
||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(backendValuesPropertyMap().value(QString::fromUtf8(propertyName))));
|
||||
if (!valueObject) {
|
||||
valueObject = new PropertyEditorValue(&backendValuesPropertyMap());
|
||||
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
||||
QObject::connect(valueObject, &PropertyEditorValue::expressionChanged, textureEditor, &TextureEditorView::changeExpression);
|
||||
QObject::connect(valueObject, &PropertyEditorValue::exportPropertyAsAliasRequested, textureEditor, &TextureEditorView::exportPropertyAsAlias);
|
||||
QObject::connect(valueObject, &PropertyEditorValue::removeAliasExportRequested, textureEditor, &TextureEditorView::removeAliasExport);
|
||||
backendValuesPropertyMap().insert(QString::fromUtf8(propertyName), QVariant::fromValue(valueObject));
|
||||
}
|
||||
valueObject->setName(name);
|
||||
valueObject->setModelNode(qmlObjectNode);
|
||||
|
||||
if (qmlObjectNode.propertyAffectedByCurrentState(name) && !(qmlObjectNode.modelNode().property(name).isBindingProperty()))
|
||||
valueObject->setValue(qmlObjectNode.modelValue(name));
|
||||
else
|
||||
valueObject->setValue(value);
|
||||
|
||||
if (propertyName != "id" && qmlObjectNode.currentState().isBaseState()
|
||||
&& qmlObjectNode.modelNode().property(propertyName).isBindingProperty()) {
|
||||
valueObject->setExpression(qmlObjectNode.modelNode().bindingProperty(propertyName).expression());
|
||||
} else {
|
||||
if (qmlObjectNode.hasBindingProperty(name))
|
||||
valueObject->setExpression(qmlObjectNode.expression(name));
|
||||
else
|
||||
valueObject->setExpression(qmlObjectNode.instanceValue(name).toString());
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::setValue(const QmlObjectNode &,
|
||||
PropertyNameView name,
|
||||
const QVariant &value)
|
||||
{
|
||||
// Vector*D values need to be split into their subcomponents
|
||||
if (value.typeId() == QMetaType::QVector2D) {
|
||||
const char *suffix[2] = {"_x", "_y"};
|
||||
auto vecValue = value.value<QVector2D>();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
PropertyName subPropName(name.size() + 2, '\0');
|
||||
subPropName.replace(0, name.size(), name);
|
||||
subPropName.replace(name.size(), 2, suffix[i]);
|
||||
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(QVariant(vecValue[i]));
|
||||
}
|
||||
} else if (value.typeId() == QMetaType::QVector3D) {
|
||||
const char *suffix[3] = {"_x", "_y", "_z"};
|
||||
auto vecValue = value.value<QVector3D>();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
PropertyName subPropName(name.size() + 2, '\0');
|
||||
subPropName.replace(0, name.size(), name);
|
||||
subPropName.replace(name.size(), 2, suffix[i]);
|
||||
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(QVariant(vecValue[i]));
|
||||
}
|
||||
} else if (value.typeId() == QMetaType::QVector4D) {
|
||||
const char *suffix[4] = {"_x", "_y", "_z", "_w"};
|
||||
auto vecValue = value.value<QVector4D>();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
PropertyName subPropName(name.size() + 2, '\0');
|
||||
subPropName.replace(0, name.size(), name);
|
||||
subPropName.replace(name.size(), 2, suffix[i]);
|
||||
auto propertyValue = qobject_cast<PropertyEditorValue *>(
|
||||
variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(QVariant(vecValue[i]));
|
||||
}
|
||||
} else {
|
||||
PropertyName propertyName = name.toByteArray();
|
||||
propertyName.replace('.', '_');
|
||||
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName))));
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::setExpression(PropertyNameView propName, const QString &exp)
|
||||
{
|
||||
PropertyEditorValue *propertyValue = propertyValueForName(QString::fromUtf8(propName));
|
||||
if (propertyValue)
|
||||
propertyValue->setExpression(exp);
|
||||
}
|
||||
|
||||
QQmlContext *TextureEditorQmlBackend::context() const
|
||||
{
|
||||
return m_quickWidget->rootContext();
|
||||
}
|
||||
|
||||
TextureEditorContextObject *TextureEditorQmlBackend::contextObject() const
|
||||
{
|
||||
return m_contextObject.get();
|
||||
}
|
||||
|
||||
QQuickWidget *TextureEditorQmlBackend::widget() const
|
||||
{
|
||||
return m_quickWidget.get();
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::setSource(const QUrl &url)
|
||||
{
|
||||
m_quickWidget->setSource(url);
|
||||
}
|
||||
|
||||
QmlAnchorBindingProxy &TextureEditorQmlBackend::backendAnchorBinding()
|
||||
{
|
||||
return m_backendAnchorBinding;
|
||||
}
|
||||
|
||||
DesignerPropertyMap &TextureEditorQmlBackend::backendValuesPropertyMap()
|
||||
{
|
||||
return m_backendValuesPropertyMap;
|
||||
}
|
||||
|
||||
TextureEditorTransaction *TextureEditorQmlBackend::textureEditorTransaction() const
|
||||
{
|
||||
return m_textureEditorTransaction.get();
|
||||
}
|
||||
|
||||
PropertyEditorValue *TextureEditorQmlBackend::propertyValueForName(const QString &propertyName)
|
||||
{
|
||||
return qobject_cast<PropertyEditorValue *>(variantToQObject(backendValuesPropertyMap().value(propertyName)));
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::setup(const QmlObjectNode &selectedTextureNode, const QString &stateName,
|
||||
const QUrl &qmlSpecificsFile, TextureEditorView *textureEditor)
|
||||
{
|
||||
if (selectedTextureNode.isValid()) {
|
||||
m_contextObject->setModel(textureEditor->model());
|
||||
|
||||
for (const auto &property : selectedTextureNode.modelNode().metaInfo().properties()) {
|
||||
createPropertyEditorValue(selectedTextureNode,
|
||||
property.name(),
|
||||
selectedTextureNode.instanceValue(property.name()),
|
||||
textureEditor);
|
||||
}
|
||||
|
||||
// model node
|
||||
m_backendModelNode.setup(selectedTextureNode);
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
context()->setContextProperty("hasTexture", QVariant(true));
|
||||
|
||||
// className
|
||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
||||
m_backendValuesPropertyMap.value(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)));
|
||||
if (!valueObject)
|
||||
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
|
||||
valueObject->setName(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY);
|
||||
valueObject->setModelNode(selectedTextureNode.modelNode());
|
||||
valueObject->setValue(m_backendModelNode.simplifiedTypeName());
|
||||
QObject::connect(valueObject,
|
||||
&PropertyEditorValue::valueChanged,
|
||||
&backendValuesPropertyMap(),
|
||||
&DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY,
|
||||
QVariant::fromValue(valueObject));
|
||||
|
||||
// anchors
|
||||
m_backendAnchorBinding.setup(selectedTextureNode.modelNode());
|
||||
context()->setContextProperties(QVector<QQmlContext::PropertyPair>{
|
||||
{{"anchorBackend"}, QVariant::fromValue(&m_backendAnchorBinding)},
|
||||
{{"transaction"}, QVariant::fromValue(m_textureEditorTransaction.get())}});
|
||||
|
||||
contextObject()->setSpecificsUrl(qmlSpecificsFile);
|
||||
contextObject()->setStateName(stateName);
|
||||
|
||||
QStringList stateNames = selectedTextureNode.allStateNames();
|
||||
stateNames.prepend("base state");
|
||||
contextObject()->setAllStateNames(stateNames);
|
||||
contextObject()->setSelectedMaterial(selectedTextureNode);
|
||||
contextObject()->setIsBaseState(selectedTextureNode.isInBaseState());
|
||||
contextObject()->setHasAliasExport(selectedTextureNode.isAliasExported());
|
||||
contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(selectedTextureNode.view()));
|
||||
|
||||
contextObject()->setSelectionChanged(false);
|
||||
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
NodeMetaInfo metaInfo = selectedTextureNode.modelNode().metaInfo();
|
||||
contextObject()->setMajorVersion(metaInfo.isValid() ? metaInfo.majorVersion() : -1);
|
||||
#endif
|
||||
} else {
|
||||
context()->setContextProperty("hasTexture", QVariant(false));
|
||||
}
|
||||
}
|
||||
|
||||
QString TextureEditorQmlBackend::propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toUrlishString();
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::emitSelectionToBeChanged()
|
||||
{
|
||||
m_backendModelNode.emitSelectionToBeChanged();
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::emitSelectionChanged()
|
||||
{
|
||||
m_backendModelNode.emitSelectionChanged();
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
|
||||
AuxiliaryDataKeyView key)
|
||||
{
|
||||
const PropertyName propertyName = auxNamePostFix(key.name.toByteArray());
|
||||
setValue(qmlObjectNode, propertyName, qmlObjectNode.modelNode().auxiliaryDataWithDefault(key));
|
||||
}
|
||||
|
||||
void TextureEditorQmlBackend::refreshBackendModel()
|
||||
{
|
||||
m_backendModelNode.refresh();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,80 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "designerpropertymap.h"
|
||||
#include "qmlanchorbindingproxy.h"
|
||||
#include "qmlmodelnodeproxy.h"
|
||||
|
||||
#include <utils/uniqueobjectptr.h>
|
||||
|
||||
#include <nodemetainfo.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class PropertyEditorValue;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QQuickWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AssetImageProvider;
|
||||
class TextureEditorContextObject;
|
||||
class TextureEditorTransaction;
|
||||
class TextureEditorView;
|
||||
|
||||
class TextureEditorQmlBackend
|
||||
{
|
||||
Q_DISABLE_COPY(TextureEditorQmlBackend)
|
||||
|
||||
public:
|
||||
TextureEditorQmlBackend(TextureEditorView *textureEditor,
|
||||
class AsynchronousImageCache &imageCache);
|
||||
~TextureEditorQmlBackend();
|
||||
|
||||
void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile,
|
||||
TextureEditorView *textureEditor);
|
||||
void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value);
|
||||
void setExpression(PropertyNameView propName, const QString &exp);
|
||||
|
||||
QQmlContext *context() const;
|
||||
TextureEditorContextObject *contextObject() const;
|
||||
QQuickWidget *widget() const;
|
||||
void setSource(const QUrl &url);
|
||||
QmlAnchorBindingProxy &backendAnchorBinding();
|
||||
DesignerPropertyMap &backendValuesPropertyMap();
|
||||
TextureEditorTransaction *textureEditorTransaction() const;
|
||||
|
||||
PropertyEditorValue *propertyValueForName(const QString &propertyName);
|
||||
|
||||
static QString propertyEditorResourcesPath();
|
||||
|
||||
void emitSelectionToBeChanged();
|
||||
void emitSelectionChanged();
|
||||
|
||||
void setValueforAuxiliaryProperties(const QmlObjectNode &qmlObjectNode, AuxiliaryDataKeyView key);
|
||||
void refreshBackendModel();
|
||||
|
||||
private:
|
||||
void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
|
||||
PropertyNameView name,
|
||||
const QVariant &value,
|
||||
TextureEditorView *textureEditor);
|
||||
PropertyName auxNamePostFix(PropertyNameView propertyName);
|
||||
|
||||
// to avoid a crash while destructing DesignerPropertyMap in the QQmlData
|
||||
// this needs be destructed after m_quickWidget->engine() is destructed
|
||||
DesignerPropertyMap m_backendValuesPropertyMap;
|
||||
|
||||
Utils::UniqueObjectPtr<QQuickWidget> m_quickWidget;
|
||||
QmlAnchorBindingProxy m_backendAnchorBinding;
|
||||
QmlModelNodeProxy m_backendModelNode;
|
||||
std::unique_ptr<TextureEditorTransaction> m_textureEditorTransaction;
|
||||
std::unique_ptr<TextureEditorContextObject> m_contextObject;
|
||||
AssetImageProvider *m_textureEditorImageProvider = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textureeditortransaction.h"
|
||||
|
||||
#include <QTimerEvent>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TextureEditorTransaction::TextureEditorTransaction(TextureEditorView *textureEditor)
|
||||
: QObject(textureEditor),
|
||||
m_textureEditor(textureEditor)
|
||||
{
|
||||
}
|
||||
|
||||
void TextureEditorTransaction::start()
|
||||
{
|
||||
if (!m_textureEditor->model())
|
||||
return;
|
||||
if (m_rewriterTransaction.isValid())
|
||||
m_rewriterTransaction.commit();
|
||||
m_rewriterTransaction = m_textureEditor->beginRewriterTransaction(
|
||||
QByteArrayLiteral("TextureEditorTransaction::start"));
|
||||
m_timerId = startTimer(10000);
|
||||
}
|
||||
|
||||
void TextureEditorTransaction::end()
|
||||
{
|
||||
if (m_rewriterTransaction.isValid() && m_textureEditor->model()) {
|
||||
killTimer(m_timerId);
|
||||
m_rewriterTransaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureEditorTransaction::active() const
|
||||
{
|
||||
return m_rewriterTransaction.isValid();
|
||||
}
|
||||
|
||||
void TextureEditorTransaction::timerEvent(QTimerEvent *timerEvent)
|
||||
{
|
||||
if (timerEvent->timerId() != m_timerId)
|
||||
return;
|
||||
killTimer(timerEvent->timerId());
|
||||
if (m_rewriterTransaction.isValid())
|
||||
m_rewriterTransaction.commit();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,32 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rewritertransaction.h"
|
||||
#include "textureeditorview.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TextureEditorTransaction : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TextureEditorTransaction(TextureEditorView *textureEditor);
|
||||
|
||||
Q_INVOKABLE void start();
|
||||
Q_INVOKABLE void end();
|
||||
|
||||
Q_INVOKABLE bool active() const;
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
TextureEditorView *m_textureEditor = nullptr;
|
||||
RewriterTransaction m_rewriterTransaction;
|
||||
int m_timerId = -1;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,972 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "textureeditorview.h"
|
||||
|
||||
#include "textureeditorqmlbackend.h"
|
||||
#include "textureeditorcontextobject.h"
|
||||
#include "textureeditordynamicpropertiesproxymodel.h"
|
||||
#include "propertyeditorvalue.h"
|
||||
#include "textureeditortransaction.h"
|
||||
#include "assetslibrarywidget.h"
|
||||
|
||||
#include <auxiliarydataproperties.h>
|
||||
#include <bindingproperty.h>
|
||||
#include <createtexture.h>
|
||||
#include <dynamicpropertiesmodel.h>
|
||||
#include <externaldependenciesinterface.h>
|
||||
#include <nodeinstanceview.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <nodemetainfo.h>
|
||||
#include <nodeproperty.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmltimeline.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <sourcepathcacheinterface.h>
|
||||
#include <variantproperty.h>
|
||||
|
||||
#include <sourcepathstorage/sourcepathcache.h>
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <designdocument.h>
|
||||
#include <designmodewidget.h>
|
||||
#include <propertyeditorqmlbackend.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils3d.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QQuickWidget>
|
||||
#include <QQuickItem>
|
||||
#include <QStackedWidget>
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QColorDialog>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache,
|
||||
ExternalDependenciesInterface &externalDependencies)
|
||||
: AbstractView{externalDependencies}
|
||||
, m_imageCache(imageCache)
|
||||
, m_stackedWidget(new QStackedWidget)
|
||||
, m_propertyComponentGenerator{PropertyEditorQmlBackend::propertyEditorResourcesPath(), model()}
|
||||
, m_dynamicPropertiesModel(new DynamicPropertiesModel(true, this))
|
||||
{
|
||||
m_updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F12), m_stackedWidget);
|
||||
connect(m_updateShortcut, &QShortcut::activated, this, &TextureEditorView::reloadQml);
|
||||
|
||||
m_stackedWidget->setStyleSheet(Theme::replaceCssColors(
|
||||
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||
m_stackedWidget->setMinimumWidth(250);
|
||||
QmlDesignerPlugin::trackWidgetFocusTime(m_stackedWidget, Constants::EVENT_TEXTUREEDITOR_TIME);
|
||||
|
||||
TextureEditorDynamicPropertiesProxyModel::registerDeclarativeType();
|
||||
}
|
||||
|
||||
TextureEditorView::~TextureEditorView()
|
||||
{
|
||||
qDeleteAll(m_qmlBackendHash);
|
||||
}
|
||||
|
||||
// from texture editor to model
|
||||
void TextureEditorView::changeValue(const QString &name)
|
||||
{
|
||||
PropertyName propertyName = name.toUtf8();
|
||||
|
||||
if (propertyName.isNull() || locked() || noValidSelection() || propertyName == "id"
|
||||
|| propertyName == Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY) {
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyName underscoreName(propertyName);
|
||||
underscoreName.replace('.', '_');
|
||||
PropertyEditorValue *value = m_qmlBackEnd->propertyValueForName(QString::fromLatin1(underscoreName));
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
if (propertyName == "objectName") {
|
||||
QTC_ASSERT(m_selectedTexture.isValid(), return);
|
||||
QmlObjectNode(m_selectedTexture).setNameAndId(value->value().toString(), "texture");
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyName.endsWith("__AUX")) {
|
||||
commitAuxValueToModel(propertyName, value->value());
|
||||
return;
|
||||
}
|
||||
|
||||
const NodeMetaInfo metaInfo = m_selectedTexture.metaInfo();
|
||||
|
||||
QVariant castedValue;
|
||||
|
||||
if (auto property = metaInfo.property(propertyName)) {
|
||||
castedValue = property.castedValue(value->value());
|
||||
} else {
|
||||
qWarning() << __FUNCTION__ << propertyName << "cannot be casted (metainfo)";
|
||||
return;
|
||||
}
|
||||
|
||||
if (value->value().isValid() && !castedValue.isValid()) {
|
||||
qWarning() << __FUNCTION__ << propertyName << "not properly casted (metainfo)";
|
||||
return;
|
||||
}
|
||||
|
||||
bool propertyTypeUrl = false;
|
||||
|
||||
if (auto property = metaInfo.property(propertyName)) {
|
||||
if (property.propertyType().isUrl()) {
|
||||
// turn absolute local file paths into relative paths
|
||||
propertyTypeUrl = true;
|
||||
QString filePath = castedValue.toUrl().toString();
|
||||
QFileInfo fi(filePath);
|
||||
if (fi.exists() && fi.isAbsolute()) {
|
||||
QDir fileDir(QFileInfo(model()->fileUrl().toLocalFile()).absolutePath());
|
||||
castedValue = QUrl(fileDir.relativeFilePath(filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "state" && castedValue.toString() == "base state")
|
||||
castedValue = "";
|
||||
|
||||
if (castedValue.typeId() == QMetaType::QColor) {
|
||||
QColor color = castedValue.value<QColor>();
|
||||
QColor newColor = QColor(color.name());
|
||||
newColor.setAlpha(color.alpha());
|
||||
castedValue = QVariant(newColor);
|
||||
}
|
||||
|
||||
if (!value->value().isValid() || (propertyTypeUrl && value->value().toString().isEmpty())) { // reset
|
||||
removePropertyFromModel(propertyName);
|
||||
} else {
|
||||
// QVector*D(0, 0, 0) detects as null variant though it is valid value
|
||||
if (castedValue.isValid()
|
||||
&& (!castedValue.isNull() || castedValue.typeId() == QMetaType::QVector2D
|
||||
|| castedValue.typeId() == QMetaType::QVector3D
|
||||
|| castedValue.typeId() == QMetaType::QVector4D)) {
|
||||
commitVariantValueToModel(propertyName, castedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isTrueFalseLiteral(const QString &expression)
|
||||
{
|
||||
return (expression.compare("false", Qt::CaseInsensitive) == 0)
|
||||
|| (expression.compare("true", Qt::CaseInsensitive) == 0);
|
||||
}
|
||||
|
||||
void TextureEditorView::changeExpression(const QString &propertyName)
|
||||
{
|
||||
PropertyName name = propertyName.toUtf8();
|
||||
|
||||
if (name.isNull() || locked() || noValidSelection())
|
||||
return;
|
||||
|
||||
executeInTransaction("TextureEditorView::changeExpression", [this, name] {
|
||||
PropertyName underscoreName(name);
|
||||
underscoreName.replace('.', '_');
|
||||
|
||||
QmlObjectNode qmlObjectNode(m_selectedTexture);
|
||||
PropertyEditorValue *value = m_qmlBackEnd->propertyValueForName(QString::fromLatin1(underscoreName));
|
||||
|
||||
if (!value) {
|
||||
qWarning() << __FUNCTION__ << "no value for " << underscoreName;
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto property = m_selectedTexture.metaInfo().property(name)) {
|
||||
auto propertyType = property.propertyType();
|
||||
if (propertyType.isColor()) {
|
||||
if (QColor(value->expression().remove('"')).isValid()) {
|
||||
qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
|
||||
return;
|
||||
}
|
||||
} else if (propertyType.isBool()) {
|
||||
if (isTrueFalseLiteral(value->expression())) {
|
||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||
qmlObjectNode.setVariantProperty(name, true);
|
||||
else
|
||||
qmlObjectNode.setVariantProperty(name, false);
|
||||
return;
|
||||
}
|
||||
} else if (propertyType.isInteger()) {
|
||||
bool ok;
|
||||
int intValue = value->expression().toInt(&ok);
|
||||
if (ok) {
|
||||
qmlObjectNode.setVariantProperty(name, intValue);
|
||||
return;
|
||||
}
|
||||
} else if (propertyType.isFloat()) {
|
||||
bool ok;
|
||||
qreal realValue = value->expression().toDouble(&ok);
|
||||
if (ok) {
|
||||
qmlObjectNode.setVariantProperty(name, realValue);
|
||||
return;
|
||||
}
|
||||
} else if (propertyType.isVariant()) {
|
||||
bool ok;
|
||||
qreal realValue = value->expression().toDouble(&ok);
|
||||
if (ok) {
|
||||
qmlObjectNode.setVariantProperty(name, realValue);
|
||||
return;
|
||||
} else if (isTrueFalseLiteral(value->expression())) {
|
||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||
qmlObjectNode.setVariantProperty(name, true);
|
||||
else
|
||||
qmlObjectNode.setVariantProperty(name, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value->expression().isEmpty()) {
|
||||
value->resetValue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (qmlObjectNode.expression(name) != value->expression() || !qmlObjectNode.propertyAffectedByCurrentState(name))
|
||||
qmlObjectNode.setBindingProperty(name, value->expression());
|
||||
});
|
||||
}
|
||||
|
||||
void TextureEditorView::exportPropertyAsAlias(const QString &name)
|
||||
{
|
||||
if (name.isNull() || locked() || noValidSelection())
|
||||
return;
|
||||
|
||||
executeInTransaction("TextureEditorView::exportPopertyAsAlias", [this, name] {
|
||||
const QString id = m_selectedTexture.validId();
|
||||
QString upperCasePropertyName = name;
|
||||
upperCasePropertyName.replace(0, 1, upperCasePropertyName.at(0).toUpper());
|
||||
QString aliasName = id + upperCasePropertyName;
|
||||
aliasName.replace(".", ""); //remove all dots
|
||||
|
||||
PropertyName propertyName = aliasName.toUtf8();
|
||||
if (rootModelNode().hasProperty(propertyName)) {
|
||||
Core::AsynchronousMessageBox::warning(tr("Cannot Export Property as Alias"),
|
||||
tr("Property %1 does already exist for root component.").arg(aliasName));
|
||||
return;
|
||||
}
|
||||
rootModelNode().bindingProperty(propertyName).setDynamicTypeNameAndExpression("alias", id + "." + name);
|
||||
});
|
||||
}
|
||||
|
||||
void TextureEditorView::removeAliasExport(const QString &name)
|
||||
{
|
||||
if (name.isNull() || locked() || noValidSelection())
|
||||
return;
|
||||
|
||||
executeInTransaction("TextureEditorView::removeAliasExport", [this, name] {
|
||||
const QString id = m_selectedTexture.validId();
|
||||
|
||||
const QList<BindingProperty> bindingProps = rootModelNode().bindingProperties();
|
||||
for (const BindingProperty &property : bindingProps) {
|
||||
if (property.expression() == (id + "." + name)) {
|
||||
rootModelNode().removeProperty(property.name());
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool TextureEditorView::locked() const
|
||||
{
|
||||
return m_locked;
|
||||
}
|
||||
|
||||
void TextureEditorView::currentTimelineChanged(const ModelNode &)
|
||||
{
|
||||
if (m_qmlBackEnd)
|
||||
m_qmlBackEnd->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this));
|
||||
}
|
||||
|
||||
void TextureEditorView::refreshMetaInfos(const TypeIds &deletedTypeIds)
|
||||
{
|
||||
m_propertyComponentGenerator.refreshMetaInfos(deletedTypeIds);
|
||||
}
|
||||
|
||||
DynamicPropertiesModel *TextureEditorView::dynamicPropertiesModel() const
|
||||
{
|
||||
return m_dynamicPropertiesModel;
|
||||
}
|
||||
|
||||
TextureEditorView *TextureEditorView::instance()
|
||||
{
|
||||
static TextureEditorView *s_instance = nullptr;
|
||||
|
||||
if (s_instance)
|
||||
return s_instance;
|
||||
|
||||
const auto views = QmlDesignerPlugin::instance()->viewManager().views();
|
||||
for (auto *view : views) {
|
||||
TextureEditorView *myView = qobject_cast<TextureEditorView *>(view);
|
||||
if (myView)
|
||||
s_instance = myView;
|
||||
}
|
||||
|
||||
QTC_ASSERT(s_instance, return nullptr);
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void TextureEditorView::timerEvent(QTimerEvent *timerEvent)
|
||||
{
|
||||
if (m_timerId == timerEvent->timerId()) {
|
||||
if (m_selectedTextureChanged) {
|
||||
m_selectedTextureChanged = false;
|
||||
Utils3D::selectTexture(m_newSelectedTexture);
|
||||
m_newSelectedTexture = {};
|
||||
} else {
|
||||
resetView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::resetView()
|
||||
{
|
||||
if (!model())
|
||||
return;
|
||||
|
||||
m_locked = true;
|
||||
|
||||
if (m_timerId)
|
||||
killTimer(m_timerId);
|
||||
|
||||
setupQmlBackend();
|
||||
|
||||
if (m_qmlBackEnd)
|
||||
m_qmlBackEnd->emitSelectionChanged();
|
||||
|
||||
m_locked = false;
|
||||
|
||||
if (m_timerId)
|
||||
m_timerId = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
QString TextureEditorView::textureEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/textureEditorQmlSource";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/textureEditorQmlSource").toUrlishString();
|
||||
}
|
||||
|
||||
void TextureEditorView::applyTextureToSelectedModel(const ModelNode &texture)
|
||||
{
|
||||
if (!m_selectedModel.isValid())
|
||||
return;
|
||||
|
||||
QTC_ASSERT(texture.isValid(), return);
|
||||
|
||||
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser");
|
||||
emitCustomNotification("apply_texture_to_model3D", {m_selectedModel, m_selectedTexture});
|
||||
}
|
||||
|
||||
void TextureEditorView::handleToolBarAction(int action)
|
||||
{
|
||||
QTC_ASSERT(m_hasQuick3DImport, return);
|
||||
|
||||
switch (action) {
|
||||
case TextureEditorContextObject::ApplyToSelected: {
|
||||
applyTextureToSelectedModel(m_selectedTexture);
|
||||
break;
|
||||
}
|
||||
|
||||
case TextureEditorContextObject::AddNewTexture: {
|
||||
if (!model())
|
||||
break;
|
||||
CreateTexture(this).execute();
|
||||
break;
|
||||
}
|
||||
|
||||
case TextureEditorContextObject::DeleteCurrentTexture: {
|
||||
if (m_selectedTexture.isValid()) {
|
||||
executeInTransaction(__FUNCTION__, [&] {
|
||||
m_selectedTexture.destroy();
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TextureEditorContextObject::OpenMaterialBrowser: {
|
||||
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
QUrl getSpecificsUrl(const NodeMetaInfos &prototypes, const SourcePathCacheInterface &pathCache)
|
||||
{
|
||||
Utils::PathString specificsPath;
|
||||
|
||||
for (const NodeMetaInfo &prototype : prototypes) {
|
||||
auto sourceId = prototype.propertyEditorPathId();
|
||||
if (sourceId) {
|
||||
auto path = pathCache.sourcePath(sourceId);
|
||||
if (path.endsWith("Specifics.qml")) {
|
||||
specificsPath = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QUrl::fromLocalFile(specificsPath.toQString());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
TextureEditorQmlBackend *TextureEditorView::getQmlBackend(const QUrl &qmlFileUrl)
|
||||
{
|
||||
auto qmlFileName = qmlFileUrl.toString();
|
||||
TextureEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlFileName);
|
||||
|
||||
if (!currentQmlBackend) {
|
||||
currentQmlBackend = new TextureEditorQmlBackend(this, m_imageCache);
|
||||
|
||||
m_stackedWidget->addWidget(currentQmlBackend->widget());
|
||||
m_qmlBackendHash.insert(qmlFileName, currentQmlBackend);
|
||||
|
||||
currentQmlBackend->setSource(qmlFileUrl);
|
||||
|
||||
QObject *rootObj = currentQmlBackend->widget()->rootObject();
|
||||
QObject::connect(rootObj, SIGNAL(toolBarAction(int)), this, SLOT(handleToolBarAction(int)));
|
||||
}
|
||||
|
||||
return currentQmlBackend;
|
||||
}
|
||||
|
||||
QUrl TextureEditorView::getPaneUrl()
|
||||
{
|
||||
QString panePath = textureEditorResourcesPath();
|
||||
if (m_selectedTexture.isValid() && m_hasQuick3DImport
|
||||
&& (Utils3D::materialLibraryNode(this).isValid() || m_hasTextureRoot))
|
||||
panePath.append("/TextureEditorPane.qml");
|
||||
else {
|
||||
panePath.append("/EmptyTextureEditorPane.qml");
|
||||
}
|
||||
|
||||
return QUrl::fromLocalFile(panePath);
|
||||
}
|
||||
|
||||
void TextureEditorView::setupCurrentQmlBackend(const ModelNode &selectedNode,
|
||||
const QUrl &qmlSpecificsFile,
|
||||
const QString &specificQmlData)
|
||||
{
|
||||
QmlModelState currState = currentStateNode();
|
||||
QString currStateName = currState.isBaseState() ? QStringLiteral("invalid state")
|
||||
: currState.name();
|
||||
QmlObjectNode qmlObjectNode{selectedNode};
|
||||
m_qmlBackEnd->setup(qmlObjectNode, currStateName, qmlSpecificsFile, this);
|
||||
m_qmlBackEnd->contextObject()->setSpecificQmlData(specificQmlData);
|
||||
}
|
||||
|
||||
void TextureEditorView::setupWidget()
|
||||
{
|
||||
m_qmlBackEnd->widget()->installEventFilter(this);
|
||||
m_stackedWidget->setCurrentWidget(m_qmlBackEnd->widget());
|
||||
m_stackedWidget->setMinimumSize({400, 300});
|
||||
}
|
||||
|
||||
void TextureEditorView::setupQmlBackend()
|
||||
{
|
||||
QUrl qmlPaneUrl = getPaneUrl();
|
||||
QUrl qmlSpecificsUrl;
|
||||
QString specificQmlData;
|
||||
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
auto selfAndPrototypes = m_selectedTexture.metaInfo().selfAndPrototypes();
|
||||
bool isEditableComponent = m_selectedTexture.isComponent()
|
||||
&& !QmlItemNode(m_selectedTexture).isEffectItem();
|
||||
specificQmlData = m_propertyEditorComponentGenerator.create(selfAndPrototypes, isEditableComponent);
|
||||
qmlSpecificsUrl = getSpecificsUrl(selfAndPrototypes, model()->pathCache());
|
||||
#else
|
||||
TypeName diffClassName;
|
||||
if (NodeMetaInfo metaInfo = m_selectedTexture.metaInfo()) {
|
||||
diffClassName = metaInfo.typeName();
|
||||
for (const NodeMetaInfo &metaInfo : metaInfo.selfAndPrototypes()) {
|
||||
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
|
||||
break;
|
||||
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + "Specifics", metaInfo);
|
||||
diffClassName = metaInfo.typeName();
|
||||
}
|
||||
|
||||
if (diffClassName != m_selectedTexture.type()) {
|
||||
specificQmlData = PropertyEditorQmlBackend::templateGeneration(
|
||||
metaInfo, model()->metaInfo(diffClassName), m_selectedTexture);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_qmlBackEnd = getQmlBackend(qmlPaneUrl);
|
||||
setupCurrentQmlBackend(m_selectedTexture, qmlSpecificsUrl, specificQmlData);
|
||||
setupWidget();
|
||||
|
||||
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
||||
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(Utils3D::materialLibraryNode(this).isValid());
|
||||
bool hasValidSelection = QmlObjectNode(m_selectedModel).hasBindingProperty("materials");
|
||||
m_qmlBackEnd->contextObject()->setHasSingleModelSelection(hasValidSelection);
|
||||
m_qmlBackEnd->contextObject()->setIsQt6Project(externalDependencies().isQt6Project());
|
||||
|
||||
m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture);
|
||||
}
|
||||
|
||||
void TextureEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value)
|
||||
{
|
||||
m_locked = true;
|
||||
executeInTransaction("TextureEditorView:commitVariantValueToModel", [&] {
|
||||
QmlObjectNode(m_selectedTexture).setVariantProperty(propertyName, value);
|
||||
});
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void TextureEditorView::commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value)
|
||||
{
|
||||
m_locked = true;
|
||||
|
||||
PropertyNameView name = propertyName;
|
||||
name.chop(5);
|
||||
|
||||
try {
|
||||
if (value.isValid())
|
||||
m_selectedTexture.setAuxiliaryData(AuxiliaryDataType::Document, name, value);
|
||||
else
|
||||
m_selectedTexture.removeAuxiliaryData(AuxiliaryDataType::Document, name);
|
||||
}
|
||||
catch (const Exception &e) {
|
||||
e.showException();
|
||||
}
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void TextureEditorView::removePropertyFromModel(PropertyNameView propertyName)
|
||||
{
|
||||
m_locked = true;
|
||||
executeInTransaction(__FUNCTION__,
|
||||
[&] { QmlObjectNode(m_selectedTexture).removeProperty(propertyName); });
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
bool TextureEditorView::noValidSelection() const
|
||||
{
|
||||
QTC_ASSERT(m_qmlBackEnd, return true);
|
||||
return !QmlObjectNode::isValidQmlObjectNode(m_selectedTexture);
|
||||
}
|
||||
|
||||
void TextureEditorView::asyncResetView()
|
||||
{
|
||||
if (m_timerId)
|
||||
killTimer(m_timerId);
|
||||
m_timerId = startTimer(0);
|
||||
}
|
||||
|
||||
void TextureEditorView::modelAttached(Model *model)
|
||||
{
|
||||
AbstractView::modelAttached(model);
|
||||
|
||||
if constexpr (useProjectStorage())
|
||||
m_propertyComponentGenerator.setModel(model);
|
||||
|
||||
m_locked = true;
|
||||
|
||||
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
||||
m_hasTextureRoot = rootModelNode().metaInfo().isQtQuick3DTexture();
|
||||
|
||||
if (m_hasTextureRoot) {
|
||||
m_selectedTexture = rootModelNode();
|
||||
} else if (m_hasQuick3DImport) {
|
||||
// Creating the material library node on model attach causes errors as long as the type
|
||||
// information is not complete yet, so we keep checking until type info is complete.
|
||||
m_selectedTexture = Utils3D::selectedTexture(this);
|
||||
}
|
||||
|
||||
if (!m_setupCompleted) {
|
||||
reloadQml();
|
||||
m_setupCompleted = true;
|
||||
}
|
||||
resetView();
|
||||
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void TextureEditorView::modelAboutToBeDetached(Model *model)
|
||||
{
|
||||
AbstractView::modelAboutToBeDetached(model);
|
||||
m_dynamicPropertiesModel->reset();
|
||||
if (m_qmlBackEnd) {
|
||||
m_qmlBackEnd->textureEditorTransaction()->end();
|
||||
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::propertiesRemoved(const QList<AbstractProperty> &propertyList)
|
||||
{
|
||||
if (noValidSelection())
|
||||
return;
|
||||
|
||||
for (const AbstractProperty &property : propertyList) {
|
||||
ModelNode node(property.parentModelNode());
|
||||
|
||||
if (node.isRootNode())
|
||||
m_qmlBackEnd->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedTexture).isAliasExported());
|
||||
|
||||
auto propertyName = property.name().toByteArray();
|
||||
if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) {
|
||||
// TODO: workaround for bug QDS-8539. To be removed once it is fixed.
|
||||
if (node.metaInfo().property(property.name()).propertyType().isUrl()) {
|
||||
resetPuppet();
|
||||
} else {
|
||||
m_locked = true;
|
||||
|
||||
const PropertyName propertyName = property.name().toByteArray();
|
||||
PropertyName convertedpropertyName = propertyName;
|
||||
|
||||
convertedpropertyName.replace('.', '_');
|
||||
|
||||
PropertyEditorValue *value = m_qmlBackEnd->propertyValueForName(
|
||||
QString::fromUtf8(convertedpropertyName));
|
||||
|
||||
if (value) {
|
||||
value->resetValue();
|
||||
m_qmlBackEnd
|
||||
->setValue(m_selectedTexture,
|
||||
propertyName,
|
||||
QmlObjectNode(m_selectedTexture).instanceValue(propertyName));
|
||||
}
|
||||
m_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyName == "materials"
|
||||
&& (node == m_selectedModel
|
||||
|| QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) {
|
||||
m_qmlBackEnd->contextObject()->setHasSingleModelSelection(false);
|
||||
}
|
||||
|
||||
dynamicPropertiesModel()->dispatchPropertyChanges(property);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList, PropertyChangeFlags /*propertyChange*/)
|
||||
{
|
||||
if (noValidSelection())
|
||||
return;
|
||||
|
||||
for (const VariantProperty &property : propertyList) {
|
||||
ModelNode node(property.parentModelNode());
|
||||
if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) {
|
||||
if (property.isDynamic())
|
||||
m_dynamicPropertiesModel->updateItem(property);
|
||||
auto propertyName = property.name().toByteArray();
|
||||
if (m_selectedTexture.property(propertyName).isBindingProperty()) {
|
||||
setValue(m_selectedTexture,
|
||||
propertyName,
|
||||
QmlObjectNode(m_selectedTexture).instanceValue(propertyName));
|
||||
} else {
|
||||
setValue(m_selectedTexture,
|
||||
propertyName,
|
||||
QmlObjectNode(m_selectedTexture).modelValue(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
dynamicPropertiesModel()->dispatchPropertyChanges(property);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags /*propertyChange*/)
|
||||
{
|
||||
if (noValidSelection())
|
||||
return;
|
||||
|
||||
for (const BindingProperty &property : propertyList) {
|
||||
ModelNode node(property.parentModelNode());
|
||||
|
||||
if (property.isAliasExport())
|
||||
m_qmlBackEnd->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedTexture).isAliasExported());
|
||||
|
||||
auto propertyName = property.name().toByteArray();
|
||||
|
||||
if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) {
|
||||
if (property.isDynamic())
|
||||
m_dynamicPropertiesModel->updateItem(property);
|
||||
m_locked = true;
|
||||
QString exp = QmlObjectNode(m_selectedTexture).bindingProperty(property.name()).expression();
|
||||
m_qmlBackEnd->setExpression(property.name(), exp);
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
if (propertyName == "materials"
|
||||
&& (node == m_selectedModel
|
||||
|| QmlObjectNode(m_selectedModel).propertyChangeForCurrentState() == node)) {
|
||||
bool hasMaterials = QmlObjectNode(m_selectedModel).hasBindingProperty("materials");
|
||||
m_qmlBackEnd->contextObject()->setHasSingleModelSelection(hasMaterials);
|
||||
}
|
||||
|
||||
dynamicPropertiesModel()->dispatchPropertyChanges(property);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::auxiliaryDataChanged(const ModelNode &node,
|
||||
AuxiliaryDataKeyView key,
|
||||
const QVariant &)
|
||||
{
|
||||
if (!noValidSelection() && node.isSelected())
|
||||
m_qmlBackEnd->setValueforAuxiliaryProperties(m_selectedTexture, key);
|
||||
|
||||
if (!m_hasTextureRoot) {
|
||||
if (key == Utils3D::matLibSelectedTextureProperty) {
|
||||
if (ModelNode selNode = Utils3D::selectedTexture(this)) {
|
||||
m_selectedTexture = selNode;
|
||||
m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture);
|
||||
asyncResetView();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
|
||||
{
|
||||
for (const auto &property : propertyList)
|
||||
m_dynamicPropertiesModel->removeItem(property);
|
||||
}
|
||||
|
||||
void TextureEditorView::nodeReparented(const ModelNode &node,
|
||||
[[maybe_unused]] const NodeAbstractProperty &newPropertyParent,
|
||||
[[maybe_unused]] const NodeAbstractProperty &oldPropertyParent,
|
||||
[[maybe_unused]] PropertyChangeFlags propertyChange)
|
||||
{
|
||||
if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) {
|
||||
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(true);
|
||||
asyncResetView();
|
||||
} else {
|
||||
if (!m_selectedTexture && node.metaInfo().isQtQuick3DTexture()
|
||||
&& node.parentProperty().parentModelNode() == Utils3D::materialLibraryNode(this)) {
|
||||
ModelNode currentSelection = Utils3D::selectedTexture(this);
|
||||
if (currentSelection) {
|
||||
m_selectedTexture = currentSelection;
|
||||
asyncResetView();
|
||||
} else {
|
||||
QTimer::singleShot(0, this, [node]() {
|
||||
Utils3D::selectTexture(node);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
|
||||
{
|
||||
if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) {
|
||||
m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false);
|
||||
asyncResetView();
|
||||
} else if (removedNode == m_selectedTexture) {
|
||||
ModelNode matLib = Utils3D::materialLibraryNode(this);
|
||||
QTC_ASSERT(matLib.isValid(), return);
|
||||
|
||||
const QList<ModelNode> textures = matLib.directSubModelNodesOfType(
|
||||
model()->qtQuick3DTextureMetaInfo());
|
||||
bool selectedNodeFound = false;
|
||||
m_newSelectedTexture = {};
|
||||
for (const ModelNode &tex : textures) {
|
||||
if (selectedNodeFound) {
|
||||
m_newSelectedTexture = tex;
|
||||
break;
|
||||
}
|
||||
if (m_selectedTexture == tex)
|
||||
selectedNodeFound = true;
|
||||
else
|
||||
m_newSelectedTexture = tex;
|
||||
}
|
||||
m_selectedTextureChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNode,
|
||||
[[maybe_unused]] const NodeAbstractProperty &parentProperty,
|
||||
[[maybe_unused]] PropertyChangeFlags propertyChange)
|
||||
{
|
||||
if (m_selectedTextureChanged)
|
||||
asyncResetView();
|
||||
|
||||
m_qmlBackEnd->refreshBackendModel();
|
||||
}
|
||||
|
||||
void TextureEditorView::nodeIdChanged([[maybe_unused]] const ModelNode &node,
|
||||
[[maybe_unused]] const QString &newId,
|
||||
[[maybe_unused]] const QString &oldId)
|
||||
{
|
||||
m_qmlBackEnd->refreshBackendModel();
|
||||
}
|
||||
|
||||
bool TextureEditorView::hasWidget() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
WidgetInfo TextureEditorView::widgetInfo()
|
||||
{
|
||||
return createWidgetInfo(m_stackedWidget,
|
||||
"TextureEditor",
|
||||
WidgetInfo::RightPane,
|
||||
tr("Texture Editor"),
|
||||
tr("Texture Editor view"));
|
||||
}
|
||||
|
||||
void TextureEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||
[[maybe_unused]] const QList<ModelNode> &lastSelectedNodeList)
|
||||
{
|
||||
m_selectedModel = {};
|
||||
|
||||
if (selectedNodeList.size() == 1 && selectedNodeList.at(0).metaInfo().isQtQuick3DModel())
|
||||
m_selectedModel = selectedNodeList.at(0);
|
||||
|
||||
bool hasValidSelection = QmlObjectNode(m_selectedModel).hasBindingProperty("materials");
|
||||
if (m_qmlBackEnd)
|
||||
m_qmlBackEnd->contextObject()->setHasSingleModelSelection(hasValidSelection);
|
||||
}
|
||||
|
||||
void TextureEditorView::currentStateChanged(const ModelNode &node)
|
||||
{
|
||||
QmlModelState newQmlModelState(node);
|
||||
Q_ASSERT(newQmlModelState.isValid());
|
||||
resetView();
|
||||
}
|
||||
|
||||
void TextureEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName>> &propertyList)
|
||||
{
|
||||
if (!m_selectedTexture.isValid() || !m_qmlBackEnd)
|
||||
return;
|
||||
|
||||
m_locked = true;
|
||||
|
||||
for (const QPair<ModelNode, PropertyName> &propertyPair : propertyList) {
|
||||
const ModelNode modelNode = propertyPair.first;
|
||||
const QmlObjectNode qmlObjectNode(modelNode);
|
||||
const PropertyName propertyName = propertyPair.second;
|
||||
|
||||
if (qmlObjectNode.isValid() && modelNode == m_selectedTexture && qmlObjectNode.currentState().isValid()) {
|
||||
const AbstractProperty property = modelNode.property(propertyName);
|
||||
if (!modelNode.hasProperty(propertyName) || modelNode.property(property.name()).isBindingProperty())
|
||||
setValue(modelNode, property.name(), qmlObjectNode.instanceValue(property.name()));
|
||||
else
|
||||
setValue(modelNode, property.name(), qmlObjectNode.modelValue(property.name()));
|
||||
}
|
||||
}
|
||||
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void TextureEditorView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||
[[maybe_unused]] const Imports &removedImports)
|
||||
{
|
||||
m_hasQuick3DImport = model()->hasImport("QtQuick3D");
|
||||
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
||||
|
||||
resetView();
|
||||
}
|
||||
|
||||
void TextureEditorView::duplicateTexture(const ModelNode &texture)
|
||||
{
|
||||
QTC_ASSERT(texture.isValid(), return);
|
||||
CreateTexture(this).execute(texture);
|
||||
}
|
||||
|
||||
void QmlDesigner::TextureEditorView::highlightSupportedProperties(bool highlight)
|
||||
{
|
||||
if (!m_selectedTexture.isValid())
|
||||
return;
|
||||
|
||||
DesignerPropertyMap &propMap = m_qmlBackEnd->backendValuesPropertyMap();
|
||||
const QStringList propNames = propMap.keys();
|
||||
NodeMetaInfo metaInfo = m_selectedTexture.metaInfo();
|
||||
QTC_ASSERT(metaInfo.isValid(), return);
|
||||
|
||||
for (const QString &propName : propNames) {
|
||||
if (metaInfo.property(propName.toUtf8()).propertyType().isQtQuick3DTexture()) {
|
||||
QObject *propEditorValObj = propMap.value(propName).value<QObject *>();
|
||||
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
|
||||
propEditorVal->setHasActiveDrag(highlight);
|
||||
} else if (metaInfo.property(propName.toUtf8()).propertyType().isUrl()) {
|
||||
QObject *propEditorValObj = propMap.value(propName).value<QObject *>();
|
||||
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
|
||||
if (propEditorVal)
|
||||
propEditorVal->setHasActiveDrag(highlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureEditorView::dragStarted(QMimeData *mimeData)
|
||||
{
|
||||
if (!mimeData->hasFormat(Constants::MIME_TYPE_ASSETS))
|
||||
return;
|
||||
|
||||
const QString assetPath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',')[0];
|
||||
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||
|
||||
// Currently only image assets have dnd-supported properties
|
||||
if (assetType != Constants::MIME_TYPE_ASSET_IMAGE
|
||||
&& assetType != Constants::MIME_TYPE_ASSET_TEXTURE3D) {
|
||||
return;
|
||||
}
|
||||
|
||||
highlightSupportedProperties();
|
||||
|
||||
const QString suffix = "*." + assetPath.split('.').last().toLower();
|
||||
m_qmlBackEnd->contextObject()->setActiveDragSuffix(suffix);
|
||||
}
|
||||
|
||||
void TextureEditorView::dragEnded()
|
||||
{
|
||||
highlightSupportedProperties(false);
|
||||
m_qmlBackEnd->contextObject()->setActiveDragSuffix("");
|
||||
}
|
||||
|
||||
// from model to texture editor
|
||||
void TextureEditorView::setValue(const QmlObjectNode &qmlObjectNode,
|
||||
PropertyNameView name,
|
||||
const QVariant &value)
|
||||
{
|
||||
m_locked = true;
|
||||
m_qmlBackEnd->setValue(qmlObjectNode, name, value);
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
bool TextureEditorView::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FocusOut) {
|
||||
if (m_qmlBackEnd && m_qmlBackEnd->widget() == obj)
|
||||
QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(), "closeContextMenu");
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void TextureEditorView::reloadQml()
|
||||
{
|
||||
m_qmlBackendHash.clear();
|
||||
while (QWidget *widget = m_stackedWidget->widget(0)) {
|
||||
m_stackedWidget->removeWidget(widget);
|
||||
delete widget;
|
||||
}
|
||||
m_qmlBackEnd = nullptr;
|
||||
|
||||
resetView();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -1,139 +0,0 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <abstractview.h>
|
||||
|
||||
#include <propertyeditorcomponentgenerator.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QShortcut;
|
||||
class QStackedWidget;
|
||||
class QColorDialog;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class DynamicPropertiesModel;
|
||||
class ModelNode;
|
||||
class QmlObjectNode;
|
||||
class TextureEditorQmlBackend;
|
||||
class SourcePathCacheInterface;
|
||||
|
||||
class TextureEditorView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TextureEditorView(class AsynchronousImageCache &imageCache,
|
||||
ExternalDependenciesInterface &externalDependencies);
|
||||
~TextureEditorView() override;
|
||||
|
||||
bool hasWidget() const override;
|
||||
WidgetInfo widgetInfo() override;
|
||||
|
||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||
|
||||
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||
|
||||
void modelAttached(Model *model) override;
|
||||
void modelAboutToBeDetached(Model *model) override;
|
||||
|
||||
void variantPropertiesChanged(const QList<VariantProperty> &propertyList, PropertyChangeFlags propertyChange) override;
|
||||
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags propertyChange) override;
|
||||
void auxiliaryDataChanged(const ModelNode &node,
|
||||
AuxiliaryDataKeyView key,
|
||||
const QVariant &data) override;
|
||||
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
AbstractView::PropertyChangeFlags propertyChange) override;
|
||||
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||
void nodeRemoved(const ModelNode &removedNode,
|
||||
const NodeAbstractProperty &parentProperty,
|
||||
PropertyChangeFlags propertyChange) override;
|
||||
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
|
||||
void resetView();
|
||||
void currentStateChanged(const ModelNode &node) override;
|
||||
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
||||
|
||||
void importsChanged(const Imports &addedImports, const Imports &removedImports) override;
|
||||
|
||||
void dragStarted(QMimeData *mimeData) override;
|
||||
void dragEnded() override;
|
||||
|
||||
void changeValue(const QString &name);
|
||||
void changeExpression(const QString &name);
|
||||
void exportPropertyAsAlias(const QString &name);
|
||||
void removeAliasExport(const QString &name);
|
||||
|
||||
bool locked() const;
|
||||
|
||||
void currentTimelineChanged(const ModelNode &node) override;
|
||||
|
||||
void refreshMetaInfos(const TypeIds &deletedTypeIds) override;
|
||||
|
||||
DynamicPropertiesModel *dynamicPropertiesModel() const;
|
||||
|
||||
static TextureEditorView *instance();
|
||||
|
||||
public slots:
|
||||
void handleToolBarAction(int action);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value);
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
static QString textureEditorResourcesPath();
|
||||
|
||||
void reloadQml();
|
||||
void highlightSupportedProperties(bool highlight = true);
|
||||
|
||||
void applyTextureToSelectedModel(const ModelNode &texture);
|
||||
|
||||
void setupQmlBackend();
|
||||
TextureEditorQmlBackend *getQmlBackend(const QUrl &qmlFileUrl);
|
||||
QUrl getPaneUrl();
|
||||
void setupCurrentQmlBackend(const ModelNode &selectedNode,
|
||||
const QUrl &qmlSpecificsFile,
|
||||
const QString &specificQmlData);
|
||||
void setupWidget();
|
||||
|
||||
void commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value);
|
||||
void commitAuxValueToModel(PropertyNameView propertyName, const QVariant &value);
|
||||
void removePropertyFromModel(PropertyNameView propertyName);
|
||||
void duplicateTexture(const ModelNode &texture);
|
||||
|
||||
bool noValidSelection() const;
|
||||
void asyncResetView();
|
||||
|
||||
AsynchronousImageCache &m_imageCache;
|
||||
ModelNode m_selectedTexture;
|
||||
QShortcut *m_updateShortcut = nullptr;
|
||||
int m_timerId = 0;
|
||||
QStackedWidget *m_stackedWidget = nullptr;
|
||||
ModelNode m_selectedModel;
|
||||
QHash<QString, TextureEditorQmlBackend *> m_qmlBackendHash;
|
||||
TextureEditorQmlBackend *m_qmlBackEnd = nullptr;
|
||||
PropertyComponentGenerator m_propertyComponentGenerator;
|
||||
PropertyEditorComponentGenerator m_propertyEditorComponentGenerator{m_propertyComponentGenerator};
|
||||
bool m_locked = false;
|
||||
bool m_setupCompleted = false;
|
||||
bool m_hasQuick3DImport = false;
|
||||
bool m_hasTextureRoot = false;
|
||||
bool m_initializingPreviewData = false;
|
||||
ModelNode m_newSelectedTexture;
|
||||
bool m_selectedTextureChanged = false;
|
||||
|
||||
QPointer<QColorDialog> m_colorDialog;
|
||||
DynamicPropertiesModel *m_dynamicPropertiesModel = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -515,7 +515,6 @@ static bool isMcuDisabledView(const QString viewId)
|
||||
static const QStringList mcuDisabledViews = {
|
||||
"Editor3D",
|
||||
"MaterialBrowser",
|
||||
"TextureEditor",
|
||||
"EffectComposer",
|
||||
};
|
||||
return mcuDisabledViews.contains(viewId);
|
||||
|
@@ -116,7 +116,6 @@ inline constexpr char EVENT_CURVEDITOR_TIME[] = "curveEditor";
|
||||
inline constexpr char EVENT_STATESEDITOR_TIME[] = "statesEditor";
|
||||
inline constexpr char EVENT_DESIGNSYSTEM_TIME[] = "designSystem";
|
||||
inline constexpr char EVENT_TEXTEDITOR_TIME[] = "textEditor";
|
||||
inline constexpr char EVENT_TEXTUREEDITOR_TIME[] = "textureEditor";
|
||||
inline constexpr char EVENT_PROPERTYEDITOR_TIME[] = "propertyEditor";
|
||||
inline constexpr char EVENT_ASSETSLIBRARY_TIME[] = "assetsLibrary";
|
||||
inline constexpr char EVENT_EFFECTCOMPOSER_NODE[] = "effectComposerNode";
|
||||
@@ -178,7 +177,6 @@ inline constexpr char OBJECT_NAME_EFFECT_COMPOSER[] = "QQuickWidgetEffectCompose
|
||||
inline constexpr char OBJECT_NAME_MATERIAL_BROWSER[] = "QQuickWidgetMaterialBrowser";
|
||||
inline constexpr char OBJECT_NAME_PROPERTY_EDITOR[] = "QQuickWidgetPropertyEditor";
|
||||
inline constexpr char OBJECT_NAME_STATES_EDITOR[] = "QQuickWidgetStatesEditor";
|
||||
inline constexpr char OBJECT_NAME_TEXTURE_EDITOR[] = "QQuickWidgetTextureEditor";
|
||||
inline constexpr char OBJECT_NAME_TOP_TOOLBAR[] = "QQuickWidgetTopToolbar";
|
||||
inline constexpr char OBJECT_NAME_STATUSBAR[] = "QQuickWidgetStatusbar";
|
||||
inline constexpr char OBJECT_NAME_TOP_FEEDBACK[] = "QQuickWidgetQDSFeedback";
|
||||
|