diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/ToolBar.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/ToolBar.qml new file mode 100644 index 00000000000..36ed80d6ca8 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/ToolBar.qml @@ -0,0 +1,54 @@ +// Copyright (C) 2025 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 2.0 +import StudioTheme as StudioTheme + +Rectangle { + id: root + + property QmlTextureNodeProxy backend: textureNodeBackend + + color: StudioTheme.Values.themeToolbarBackground + implicitHeight: StudioTheme.Values.toolbarHeight + + Row { + id: row + spacing: StudioTheme.Values.toolbarSpacing + anchors.verticalCenter: parent.verticalCenter + leftPadding: 6 + + AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.apply_medium + enabled: backend.hasTexture && backend.selectedNodeAcceptsMaterial && hasQuick3DImport && hasMaterialLibrary + tooltip: qsTr("Apply texture to selected model's material.") + onClicked: backend.toolbarAction(QmlTextureNodeProxy.ApplyToSelected) + } + + AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.create_medium + enabled: hasQuick3DImport && hasMaterialLibrary + tooltip: qsTr("Create new texture.") + onClicked: backend.toolbarAction(QmlTextureNodeProxy.AddNewTexture) + } + + AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.delete_medium + enabled: backend.hasTexture && hasQuick3DImport && hasMaterialLibrary + tooltip: qsTr("Delete current texture.") + onClicked: backend.toolbarAction(QmlTextureNodeProxy.DeleteCurrentTexture) + } + + AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.materialBrowser_medium + enabled: backend.hasTexture && hasQuick3DImport && hasMaterialLibrary + tooltip: qsTr("Open material browser.") + onClicked: backend.toolbarAction(QmlTextureNodeProxy.OpenMaterialBrowser) + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/TopSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/TopSection.qml new file mode 100644 index 00000000000..0ac948ddedc --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Texture/TopSection.qml @@ -0,0 +1,88 @@ +// Copyright (C) 2025 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 2.0 as HelperWidgets +import StudioTheme as StudioTheme + +Rectangle { + id: root + + property HelperWidgets.QmlTextureNodeProxy backend: textureNodeBackend + + readonly property string sourcePath: backendValues.source ? backendValues.source.valueToString : "" + readonly property string previewPath: "image://qmldesigner_thumbnails/" + backend.resolveResourcePath(root.sourcePath) + + function refreshPreview() + { + texturePreview.source = "" + texturePreview.source = root.previewPath + } + + color: StudioTheme.Values.themePanelBackground + implicitHeight: column.height + + Column { + id: column + + Item { implicitWidth: 1; implicitHeight: 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: root.previewPath + } + } + + 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 {} + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml new file mode 100644 index 00000000000..a78be386859 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml @@ -0,0 +1,82 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets 2.0 +import StudioTheme as StudioTheme +import "Texture" as Texture + +Rectangle { + id: itemPane + + width: 420 + height: 420 + color: StudioTheme.Values.themePanelBackground + + // 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() + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + Texture.ToolBar { + Layout.fillWidth: true + } + + Texture.TopSection { + id: topSection + + Layout.fillWidth: true + } + + PropertyEditorPane { + Layout.fillWidth: true + Layout.fillHeight: true + + DynamicPropertiesSection { + propertiesModel: SelectionDynamicPropertiesModel {} + visible: !hasMultiSelection + } + + 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 + } + } + } +}