diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml
new file mode 100644
index 00000000000..bbe9641419e
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml
@@ -0,0 +1,121 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuickDesignerTheme
+import HelperWidgets as HelperWidgets
+import StudioControls as StudioControls
+import StudioTheme as StudioTheme
+
+Item {
+ id: root
+
+ // Called also from C++ to close context menu on focus out
+ function closeContextMenu()
+ {
+ materialsView.closeContextMenu()
+ texturesView.closeContextMenu()
+ environmentsView.closeContextMenu()
+ }
+
+ // Called from C++
+ function clearSearchFilter()
+ {
+ searchBox.clear();
+ }
+
+ Column {
+ id: col
+ y: 5
+ spacing: 5
+
+ StudioControls.SearchBox {
+ id: searchBox
+
+ width: root.width
+ enabled: !materialsModel.hasMaterialRoot && materialsModel.hasQuick3DImport
+
+ onSearchChanged: (searchText) => {
+ rootView.handleSearchFilterChanged(searchText)
+
+ // make sure categories with matches are expanded
+ materialsView.expandVisibleSections()
+ }
+ }
+
+ Text {
+ // TODO: only disable the materials section, textures should be available
+ text: {
+ if (materialsModel.hasMaterialRoot)
+ qsTr("Content Library is disabled inside a material component.")
+ else if (!materialsModel.hasQuick3DImport)
+ qsTr("To use Content Library, first add the QtQuick3D module in the Components view.")
+ else
+ ""
+ }
+
+ textFormat: Text.RichText
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.mediumFontSize
+ topPadding: 30
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ width: root.width
+ visible: text !== ""
+ }
+
+ UnimportBundleMaterialDialog {
+ id: confirmUnimportDialog
+ }
+
+ ContentLibraryTabBar {
+ id: tabBar
+
+ visible: materialsModel.hasQuick3DImport
+ // TODO: update icons
+ tabsModel: [{name: qsTr("Materials"), icon: StudioTheme.Constants.gradient},
+ {name: qsTr("Textures"), icon: StudioTheme.Constants.materialPreviewEnvironment},
+ {name: qsTr("Environments"), icon: StudioTheme.Constants.translationSelectLanguages}]
+ }
+
+ StackLayout {
+ width: root.width
+ height: root.height - y
+ currentIndex: tabBar.currIndex
+ visible: materialsModel.hasQuick3DImport
+
+ ContentLibraryMaterialsView {
+ id: materialsView
+
+ width: root.width
+
+ searchBox: searchBox
+
+ onUnimport: (bundleMat) => {
+ unimportBundleMaterialDialog.targetBundleMaterial = bundleMat
+ unimportBundleMaterialDialog.open()
+ }
+ }
+
+ ContentLibraryTexturesView {
+ id: texturesView
+
+ width: root.width
+ model: texturesModel
+
+ searchBox: searchBox
+ }
+
+ ContentLibraryTexturesView {
+ id: environmentsView
+
+ width: root.width
+ model: environmentsModel
+
+ searchBox: searchBox
+ }
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
similarity index 66%
rename from share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml
rename to share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
index 59541f47d39..4d6377359ce 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
@@ -1,27 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick 2.15
import QtQuick.Layouts 1.15
@@ -45,8 +23,8 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressed: (mouse) => {
- if (mouse.button === Qt.LeftButton && !materialBrowserBundleModel.importerRunning)
- rootView.startDragBundleMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
+ if (mouse.button === Qt.LeftButton && !materialsModel.importerRunning)
+ rootView.startDragMaterial(modelData, mapToGlobal(mouse.x, mouse.y))
else if (mouse.button === Qt.RightButton)
root.showContextMenu()
}
@@ -102,10 +80,10 @@ Item {
pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4)
anchors.right: img.right
anchors.bottom: img.bottom
- enabled: !materialBrowserBundleModel.importerRunning
+ enabled: !materialsModel.importerRunning
onClicked: {
- materialBrowserBundleModel.addToProject(modelData)
+ materialsModel.addToProject(modelData)
}
}
}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialContextMenu.qml
new file mode 100644
index 00000000000..a85699e6dc3
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialContextMenu.qml
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.15
+import HelperWidgets 2.0
+import StudioControls 1.0 as StudioControls
+import StudioTheme 1.0 as StudioTheme
+
+StudioControls.Menu {
+ id: root
+
+ property var targetMaterial: null
+ signal unimport(var bundleMat);
+
+ function popupMenu(targetMaterial = null)
+ {
+ this.targetMaterial = targetMaterial
+ popup()
+ }
+
+ closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
+
+ StudioControls.MenuItem {
+ text: qsTr("Apply to selected (replace)")
+ enabled: root.targetMaterial && materialsModel.hasModelSelection
+ onTriggered: materialsModel.applyToSelected(root.targetMaterial, false)
+ }
+
+ StudioControls.MenuItem {
+ text: qsTr("Apply to selected (add)")
+ enabled: root.targetMaterial && materialsModel.hasModelSelection
+ onTriggered: materialsModel.applyToSelected(root.targetMaterial, true)
+ }
+
+ StudioControls.MenuSeparator {}
+
+ StudioControls.MenuItem {
+ enabled: !materialsModel.importerRunning
+ text: qsTr("Add an instance to project")
+
+ onTriggered: {
+ materialsModel.addToProject(root.targetMaterial)
+ }
+ }
+
+ StudioControls.MenuItem {
+ enabled: !materialsModel.importerRunning && root.targetMaterial && root.targetMaterial.bundleMaterialImported
+ text: qsTr("Remove from project")
+
+ onTriggered: root.unimport(root.targetMaterial);
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml
new file mode 100644
index 00000000000..589e0250b5e
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml
@@ -0,0 +1,91 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import HelperWidgets as HelperWidgets
+import StudioControls as StudioControls
+import StudioTheme as StudioTheme
+
+HelperWidgets.ScrollView {
+ id: root
+
+ clip: true
+
+ readonly property int cellWidth: 100
+ readonly property int cellHeight: 120
+
+ property var currMaterialItem: null
+ property var rootItem: null
+
+ required property var searchBox
+
+ signal unimport(var bundleMat);
+
+ function closeContextMenu()
+ {
+ ctxMenu.close()
+ }
+
+ function expandVisibleSections()
+ {
+ for (let i = 0; i < categoryRepeater.count; ++i) {
+ let cat = categoryRepeater.itemAt(i)
+ if (cat.visible && !cat.expanded)
+ cat.expanded = true
+ }
+ }
+
+ Column {
+ ContentLibraryMaterialContextMenu {
+ id: ctxMenu
+
+ onUnimport: (bundleMat) => root.unimport(bundleMat)
+ }
+
+ Repeater {
+ id: categoryRepeater
+
+ model: materialsModel
+
+ delegate: HelperWidgets.Section {
+ width: root.width
+ caption: bundleCategoryName
+ addTopPadding: false
+ sectionBackgroundColor: "transparent"
+ visible: bundleCategoryVisible
+ expanded: bundleCategoryExpanded
+ expandOnClick: false
+ onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded
+
+ Grid {
+ width: root.width
+ leftPadding: 5
+ rightPadding: 5
+ bottomPadding: 5
+ columns: root.width / root.cellWidth
+
+ Repeater {
+ model: bundleCategoryMaterials
+
+ delegate: ContentLibraryMaterial {
+ width: root.cellWidth
+ height: root.cellHeight
+
+ onShowContextMenu: ctxMenu.popupMenu(modelData)
+ }
+ }
+ }
+ }
+ }
+
+ Text {
+ id: noMatchText
+ text: qsTr("No match found.");
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.baseFontSize
+ topPadding: 10
+ leftPadding: 10
+ visible: materialsModel.isEmpty && !searchBox.isEmpty() && !materialsModel.hasMaterialRoot
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabBar.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabBar.qml
new file mode 100644
index 00000000000..024271d1a23
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabBar.qml
@@ -0,0 +1,33 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import StudioTheme as StudioTheme
+
+Rectangle {
+ id: root
+
+ width: parent.width
+ height: 50
+ color: StudioTheme.Values.themeSectionHeadBackground
+
+ property int currIndex: 0
+ property alias tabsModel: repeater.model
+
+ Row {
+ spacing: 1
+
+ Repeater {
+ id: repeater
+
+ ContentLibraryTabButton {
+ height: root.height
+
+ name: modelData.name
+ icon: modelData.icon
+ selected: root.currIndex === index
+ onClicked: root.currIndex = index
+ }
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabButton.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabButton.qml
new file mode 100644
index 00000000000..cd31f2579d2
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTabButton.qml
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import StudioTheme as StudioTheme
+
+Rectangle {
+ id: root
+
+ signal clicked()
+
+ property alias icon: icon.text
+ property alias name: name.text
+ property bool selected: false
+
+ width: 100
+ height: 100
+ color: root.selected ? StudioTheme.Values.themePanelBackground
+ : mouseArea.containsMouse ? Qt.lighter(StudioTheme.Values.themeSectionHeadBackground, 1.3)
+ : StudioTheme.Values.themeSectionHeadBackground
+
+ Text {
+ id: icon
+
+ color: root.selected ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeTextColor
+
+ font.family: StudioTheme.Constants.iconFont.family
+ font.pixelSize: StudioTheme.Values.mediumIconFontSize
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 8
+ }
+
+ Text {
+ id: name
+
+ font.weight: Font.DemiBold
+ font.pixelSize: StudioTheme.Values.baseFontSize
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 6
+
+ color: root.selected ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeTextColor
+ }
+
+ Rectangle { // strip
+ width: root.width
+ height: 4
+ color: root.selected ? StudioTheme.Values.themeInteraction : "transparent"
+ anchors.bottom: parent.bottom
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: root.clicked()
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml
new file mode 100644
index 00000000000..d6c24d4b2af
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.15
+import QtQuick.Layouts 1.15
+import QtQuickDesignerTheme 1.0
+import HelperWidgets 2.0
+import QtQuick.Controls
+
+import StudioTheme 1.0 as StudioTheme
+
+Image {
+ id: root
+
+ source: modelData.textureIcon
+ visible: modelData.textureVisible
+ cache: false
+
+ signal showContextMenu()
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onPressed: (mouse) => {
+ if (mouse.button === Qt.LeftButton)
+ rootView.startDragTexture(modelData, mapToGlobal(mouse.x, mouse.y))
+ else if (mouse.button === Qt.RightButton)
+ root.showContextMenu()
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml
new file mode 100644
index 00000000000..373b2108084
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.15
+import HelperWidgets 2.0
+import StudioControls 1.0 as StudioControls
+import StudioTheme 1.0 as StudioTheme
+
+StudioControls.Menu {
+ id: root
+
+ property var targetTexture: null
+
+ function popupMenu(targetTexture = null)
+ {
+ this.targetTexture = targetTexture
+ popup()
+ }
+
+ closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
+
+ StudioControls.MenuItem {
+ text: qsTr("Add image")
+ enabled: root.targetTexture
+ onTriggered: rootView.addImage(root.targetTexture)
+ }
+
+ StudioControls.MenuItem {
+ text: qsTr("Add texture")
+ enabled: root.targetTexture
+ onTriggered: rootView.addTexture(root.targetTexture)
+ }
+
+ StudioControls.MenuItem {
+ text: qsTr("Add scene environment")
+ enabled: root.targetTexture
+ onTriggered: rootView.addEnv(root.targetTexture)
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml
new file mode 100644
index 00000000000..469a4170e20
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml
@@ -0,0 +1,92 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import HelperWidgets as HelperWidgets
+import StudioControls as StudioControls
+import StudioTheme as StudioTheme
+
+HelperWidgets.ScrollView {
+ id: root
+
+ clip: true
+
+ readonly property int cellWidth: 100
+ readonly property int cellHeight: 100
+
+ property var currMaterialItem: null
+ property var rootItem: null
+
+ required property var searchBox
+ required property var model
+
+ signal unimport(var bundleMat);
+
+ function closeContextMenu()
+ {
+ ctxMenu.close()
+ }
+
+ function expandVisibleSections()
+ {
+ for (let i = 0; i < categoryRepeater.count; ++i) {
+ let cat = categoryRepeater.itemAt(i)
+ if (cat.visible && !cat.expanded)
+ cat.expanded = true
+ }
+ }
+ Column {
+ ContentLibraryTextureContextMenu {
+ id: ctxMenu
+
+ // TODO
+ }
+
+ Repeater {
+ id: categoryRepeater
+
+ model: root.model
+
+ delegate: HelperWidgets.Section {
+ width: root.width
+ caption: bundleCategoryName
+ addTopPadding: false
+ sectionBackgroundColor: "transparent"
+ visible: bundleCategoryVisible
+ expanded: bundleCategoryExpanded
+ expandOnClick: false
+ onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded
+
+ Grid {
+ width: root.width
+ leftPadding: 5
+ rightPadding: 5
+ bottomPadding: 5
+ spacing: 5
+ columns: root.width / root.cellWidth
+
+ Repeater {
+ model: bundleCategoryTextures
+
+ delegate: ContentLibraryTexture {
+ width: root.cellWidth
+ height: root.cellHeight
+
+ onShowContextMenu: ctxMenu.popupMenu(modelData)
+ }
+ }
+ }
+ }
+ }
+
+ Text {
+ id: noMatchText
+ text: qsTr("No match found.");
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.baseFontSize
+ topPadding: 10
+ leftPadding: 10
+ visible: root.model.isEmpty && !searchBox.isEmpty() && !root.model.hasMaterialRoot
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
similarity index 53%
rename from share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml
rename to share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
index 82708467a8a..1c887ca317f 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
@@ -1,27 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Controls
@@ -69,7 +47,7 @@ Dialog {
text: qsTr("Remove")
onClicked: {
- materialBrowserBundleModel.removeFromProject(root.targetBundleMaterial)
+ materialsModel.removeFromProject(root.targetBundleMaterial)
root.accept()
}
}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
index 2b921374ae6..9edc5019769 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
@@ -19,13 +19,12 @@ Item {
function closeContextMenu()
{
ctxMenu.close()
- ctxMenuBundle.close()
}
// Called from C++ to refresh a preview material after it changes
function refreshPreview(idx)
{
- var item = gridRepeater.itemAt(idx);
+ var item = materialRepeater.itemAt(idx);
if (item)
item.refreshPreview();
}
@@ -44,12 +43,14 @@ Item {
acceptedButtons: Qt.RightButton
onClicked: (mouse) => {
- // root context-menu works only for user materials
- var userMatsSecBottom = mapFromItem(userMaterialsSection, 0, userMaterialsSection.y).y
- + userMaterialsSection.height;
+ if (materialBrowserModel.hasMaterialRoot || !materialBrowserModel.hasQuick3DImport)
+ return;
+
+ var matsSecBottom = mapFromItem(materialsSection, 0, materialsSection.y).y
+ + materialsSection.height;
if (!materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport
- && (!materialBrowserBundleModel.matBundleExists || mouse.y < userMatsSecBottom)) {
+ && mouse.y < matsSecBottom) {
ctxMenu.popupMenu()
}
}
@@ -63,7 +64,7 @@ Item {
if (root.currMaterialItem)
root.currMaterialItem.commitRename();
- root.currMaterialItem = gridRepeater.itemAt(materialBrowserModel.selectedIndex);
+ root.currMaterialItem = materialRepeater.itemAt(materialBrowserModel.selectedIndex);
}
}
@@ -71,19 +72,6 @@ Item {
id: ctxMenu
}
- MaterialBundleContextMenu {
- id: ctxMenuBundle
-
- onUnimport: (bundleMat) => {
- unimportBundleMaterialDialog.targetBundleMaterial = bundleMat
- unimportBundleMaterialDialog.open()
- }
- }
-
- UnimportBundleMaterialDialog {
- id: unimportBundleMaterialDialog
- }
-
Column {
id: col
y: 5
@@ -100,19 +88,6 @@ Item {
onSearchChanged: (searchText) => {
rootView.handleSearchFilterChanged(searchText)
-
- // make sure searched categories that have matches are expanded
- if (!materialBrowserModel.isEmpty && !userMaterialsSection.expanded)
- userMaterialsSection.expanded = true
-
- if (!materialBrowserBundleModel.isEmpty && !bundleMaterialsSection.expanded)
- bundleMaterialsSection.expanded = true
-
- for (let i = 0; i < bundleMaterialsSectionRepeater.count; ++i) {
- let sec = bundleMaterialsSectionRepeater.itemAt(i)
- if (sec.visible && !sec.expanded)
- sec.expanded = true
- }
}
}
@@ -156,29 +131,28 @@ Item {
height: root.height - searchBox.height
clip: true
visible: materialBrowserModel.hasQuick3DImport && !materialBrowserModel.hasMaterialRoot
- interactive: !ctxMenu.opened && !ctxMenuBundle.opened
+ interactive: !ctxMenu.opened
Column {
Section {
- id: userMaterialsSection
+ id: materialsSection
width: root.width
caption: qsTr("Materials")
- hideHeader: !materialBrowserBundleModel.matBundleExists
dropEnabled: true
onDropEnter: (drag) => {
- drag.accepted = rootView.draggedBundleMaterial
- userMaterialsSection.highlight = rootView.draggedBundleMaterial
+ drag.accepted = drag.formats[0] === "application/vnd.qtdesignstudio.bundlematerial"
+ materialsSection.highlight = drag.accepted
}
onDropExit: {
- userMaterialsSection.highlight = false
+ materialsSection.highlight = false
}
onDrop: {
- userMaterialsSection.highlight = false
- materialBrowserBundleModel.addToProject(rootView.draggedBundleMaterial)
+ materialsSection.highlight = false
+ rootView.acceptBundleMaterialDrop()
}
Grid {
@@ -191,7 +165,7 @@ Item {
columns: root.width / root.cellWidth
Repeater {
- id: gridRepeater
+ id: materialRepeater
model: materialBrowserModel
delegate: MaterialItem {
@@ -226,62 +200,51 @@ Item {
}
Section {
- id: bundleMaterialsSection
+ id: texturesSection
width: root.width
- caption: qsTr("Material Library")
- addTopPadding: noMatchText.visible
- visible: materialBrowserBundleModel.matBundleExists
+ caption: qsTr("Textures")
+
+ Grid {
+ width: scrollView.width
+ leftPadding: 5
+ rightPadding: 5
+ bottomPadding: 5
+ spacing: 5
+ columns: root.width / root.cellWidth
- Column {
Repeater {
- id: bundleMaterialsSectionRepeater
+ id: texturesRepeater
- model: materialBrowserBundleModel
+ model: materialBrowserTexturesModel
+ delegate: TextureItem {
+ width: root.cellWidth
+ height: root.cellWidth
- delegate: Section {
- width: root.width
- caption: bundleCategoryName
- addTopPadding: false
- sectionBackgroundColor: "transparent"
- visible: bundleCategoryVisible
- expanded: bundleCategoryExpanded
- expandOnClick: false
- onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded
- onExpand: bundleCategoryExpanded = true
- onCollapse: bundleCategoryExpanded = false
-
- Grid {
- width: scrollView.width
- leftPadding: 5
- rightPadding: 5
- bottomPadding: 5
- columns: root.width / root.cellWidth
-
- Repeater {
- model: bundleCategoryMaterials
-
- delegate: BundleMaterialItem {
- width: root.cellWidth
- height: root.cellHeight
-
- onShowContextMenu: {
- ctxMenuBundle.popupMenu(modelData)
- }
- }
- }
+ onShowContextMenu: {
+// ctxMenuTexture.popupMenu(this, model) // TODO: implement textures context menu
}
}
}
+ }
- Text {
- id: noMatchText
- text: qsTr("No match found.");
- color: StudioTheme.Values.themeTextColor
- font.pixelSize: StudioTheme.Values.baseFontSize
- leftPadding: 10
- visible: materialBrowserBundleModel.isEmpty && !searchBox.isEmpty() && !materialBrowserModel.hasMaterialRoot
- }
+ Text {
+ text: qsTr("No match found.");
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.baseFontSize
+ leftPadding: 10
+ visible: materialBrowserModel.isEmpty && !searchBox.isEmpty() && !materialBrowserModel.hasMaterialRoot
+ }
+
+ Text {
+ text:qsTr("There are no texture in this project.")
+ visible: materialBrowserTexturesModel.isEmpty && searchBox.isEmpty()
+ textFormat: Text.RichText
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.mediumFontSize
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ width: root.width
}
}
}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml
index 796bcab6ebd..25e271c1c4e 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml
@@ -1,27 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import HelperWidgets
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml
deleted file mode 100644
index eb698d69932..00000000000
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-import QtQuick 2.15
-import HelperWidgets 2.0
-import StudioControls 1.0 as StudioControls
-import StudioTheme 1.0 as StudioTheme
-
-StudioControls.Menu {
- id: root
-
- property var targetMaterial: null
- signal unimport(var bundleMat);
-
- function popupMenu(targetMaterial = null)
- {
- this.targetMaterial = targetMaterial
- popup()
- }
-
- closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
-
- StudioControls.MenuItem {
- text: qsTr("Apply to selected (replace)")
- enabled: root.targetMaterial && materialBrowserModel.hasModelSelection
- onTriggered: materialBrowserBundleModel.applyToSelected(root.targetMaterial, false)
- }
-
- StudioControls.MenuItem {
- text: qsTr("Apply to selected (add)")
- enabled: root.targetMaterial && materialBrowserModel.hasModelSelection
- onTriggered: materialBrowserBundleModel.applyToSelected(root.targetMaterial, true)
- }
-
- StudioControls.MenuSeparator {}
-
- StudioControls.MenuItem {
- enabled: !materialBrowserBundleModel.importerRunning
- text: qsTr("Add an instance to project")
-
- onTriggered: {
- materialBrowserBundleModel.addToProject(root.targetMaterial)
- }
- }
-
- StudioControls.MenuItem {
- enabled: !materialBrowserBundleModel.importerRunning && root.targetMaterial.bundleMaterialImported
- text: qsTr("Remove from project")
-
- onTriggered: root.unimport(root.targetMaterial);
- }
-}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml
new file mode 100644
index 00000000000..e208ed1ec52
--- /dev/null
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuickDesignerTheme
+import HelperWidgets
+import StudioTheme as StudioTheme
+
+Image {
+ id: root
+
+ source: textureSource
+ sourceSize.width: root.width
+ sourceSize.height: root.height
+ visible: textureVisible
+ cache: false
+
+ signal showContextMenu()
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onPressed: (mouse) => {
+ if (mouse.button === Qt.LeftButton)
+ rootView.startDragTexture(modelData, mapToGlobal(mouse.x, mouse.y))
+ else if (mouse.button === Qt.RightButton)
+ root.showContextMenu()
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml
index 2355f33281c..536c8adc6a4 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml
@@ -13,6 +13,7 @@ QtObject {
property real mediumFont: 14
property real bigFont: 16
property real baseIconFont: 12
+ property real mediumIconFont: 18
property real bigIconFont: 26
property real scaleFactor: 1.0
@@ -24,6 +25,7 @@ QtObject {
property real bigFontSize: Math.round(values.bigFont * values.scaleFactor)
property real baseIconFontSize: Math.round(values.baseIconFont * values.scaleFactor)
property real myIconFontSize: values.baseIconFontSize; // TODO: rename all refs to myIconFontSize -> baseIconFontSize then remove myIconFontSize
+ property real mediumIconFontSize: Math.round(values.mediumIconFont * values.scaleFactor)
property real bigIconFontSize: Math.round(values.bigIconFont * values.scaleFactor)
property real squareComponentWidth: values.height
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index fdfde219199..279bcbf4c61 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -912,6 +912,20 @@ extend_qtc_plugin(QmlDesigner
quick2propertyeditorview.cpp quick2propertyeditorview.h
)
+extend_qtc_plugin(QmlDesigner
+ SOURCES_PREFIX components/contentlibrary
+ SOURCES
+ contentlibrarybundleimporter.cpp contentlibrarybundleimporter.h
+ contentlibraryview.cpp contentlibraryview.h
+ contentlibrarywidget.cpp contentlibrarywidget.h
+ contentlibrarytexturesmodel.cpp contentlibrarytexturesmodel.h
+ contentlibrarytexturescategory.cpp contentlibrarytexturescategory.h
+ contentlibrarytexture.cpp contentlibrarytexture.h
+ contentlibrarymaterialsmodel.cpp contentlibrarymaterialsmodel.h
+ contentlibrarymaterialscategory.cpp contentlibrarymaterialscategory.h
+ contentlibrarymaterial.cpp contentlibrarymaterial.h
+)
+
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/materialeditor
SOURCES
@@ -929,10 +943,7 @@ extend_qtc_plugin(QmlDesigner
materialbrowserview.cpp materialbrowserview.h
materialbrowserwidget.cpp materialbrowserwidget.h
materialbrowsermodel.cpp materialbrowsermodel.h
- bundleimporter.cpp bundleimporter.h
- materialbrowserbundlemodel.cpp materialbrowserbundlemodel.h
- bundlematerial.cpp bundlematerial.h
- bundlematerialcategory.cpp bundlematerialcategory.h
+ materialbrowsertexturesmodel.cpp materialbrowsertexturesmodel.h
)
extend_qtc_plugin(QmlDesigner
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
index 44f1c2e747b..c7493a64bb6 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
@@ -448,7 +448,7 @@ void AssetsLibraryWidget::addResources(const QStringList &files)
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
if (operation) {
AddFilesResult result = operation(fileNames,
- document->fileName().parentDir().toString());
+ document->fileName().parentDir().toString(), true);
if (result == AddFilesResult::Failed) {
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
tr("Could not add %1 to project.")
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 9216635e260..bb60e2a1c9d 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -276,7 +276,7 @@ QHash DesignerActionManager::handleExternalAssetsDrop(cons
for (const QString &category : categories) {
AddResourceOperation operation = categoryOperation.value(category);
QStringList files = categoryFiles.value(category);
- AddFilesResult result = operation(files, {});
+ AddFilesResult result = operation(files, {}, true);
if (result == AddFilesResult::Succeeded)
addedCategoryFiles.insert(category, files);
}
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
index 099174865fe..928d136a02e 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
@@ -24,20 +24,20 @@ namespace QmlDesigner {
class DesignerActionManagerView;
-using AddResourceOperation = std::function;
-using ModelNodePreviewImageOperation = std::function;
+using AddResourceOperation = std::function;
+using ModelNodePreviewImageOperation = std::function;
struct AddResourceHandler
{
public:
- AddResourceHandler( const QString &_category,
- const QString &_filter,
- AddResourceOperation _operation,
- int _priority = 0)
+ AddResourceHandler(const QString &_category,
+ const QString &_filter,
+ AddResourceOperation _operation,
+ int _priority = 0)
: category(_category)
- ,filter(_filter)
- ,operation(_operation)
- ,piority(_priority)
+ , filter(_filter)
+ , operation(_operation)
+ , piority(_priority)
{
}
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
index 34b257fe12c..78118e8f8bb 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
@@ -1034,9 +1034,9 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
}
-AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);
+ QString directory = showDialog ? AddImagesDialog::getDirectory(fileNames, defaultDir) : defaultDir;
if (directory.isEmpty())
return AddFilesResult::Cancelled;
@@ -1105,29 +1105,29 @@ static QString getAssetDefaultDirectory(const QString &assetDir, const QString &
return adjustedDefaultDirectory;
}
-AddFilesResult addFontToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addFontToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- return addFilesToProject(fileNames, getAssetDefaultDirectory("fonts", defaultDirectory));
+ return addFilesToProject(fileNames, getAssetDefaultDirectory("fonts", defaultDir), showDialog);
}
-AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- return addFilesToProject(fileNames, getAssetDefaultDirectory("sounds", defaultDirectory));
+ return addFilesToProject(fileNames, getAssetDefaultDirectory("sounds", defaultDir), showDialog);
}
-AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- return addFilesToProject(fileNames, getAssetDefaultDirectory("shaders", defaultDirectory));
+ return addFilesToProject(fileNames, getAssetDefaultDirectory("shaders", defaultDir), showDialog);
}
-AddFilesResult addImageToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addImageToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- return addFilesToProject(fileNames, getAssetDefaultDirectory("images", defaultDirectory));
+ return addFilesToProject(fileNames, getAssetDefaultDirectory("images", defaultDir), showDialog);
}
-AddFilesResult addVideoToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addVideoToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog)
{
- return addFilesToProject(fileNames, getAssetDefaultDirectory("videos", defaultDirectory));
+ return addFilesToProject(fileNames, getAssetDefaultDirectory("videos", defaultDir), showDialog);
}
void createFlowActionArea(const SelectionContext &selectionContext)
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
index 8156203a7ca..6ea503bc846 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
@@ -57,12 +57,12 @@ void addItemToStackedContainer(const SelectionContext &selectionContext);
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
-QMLDESIGNERCORE_EXPORT AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory);
-AddFilesResult addImageToProject(const QStringList &fileNames, const QString &directory);
-AddFilesResult addFontToProject(const QStringList &fileNames, const QString &directory);
-AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &directory);
-AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &directory);
-AddFilesResult addVideoToProject(const QStringList &fileNames, const QString &directory);
+QMLDESIGNERCORE_EXPORT AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDir, bool showDialog = true);
+AddFilesResult addImageToProject(const QStringList &fileNames, const QString &directory, bool showDialog = true);
+AddFilesResult addFontToProject(const QStringList &fileNames, const QString &directory, bool showDialog = true);
+AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &directory, bool showDialog = true);
+AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &directory, bool showDialog = true);
+AddFilesResult addVideoToProject(const QStringList &fileNames, const QString &directory, bool showDialog = true);
void createFlowActionArea(const SelectionContext &selectionContext);
void addTransition(const SelectionContext &selectionState);
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
index fc56a37f86f..5a06b2b1e83 100644
--- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
@@ -8,6 +8,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -56,6 +58,7 @@ public:
? capturingConnectionManager
: connectionManager,
externalDependencies)
+ , contentLibraryView{externalDependencies}
, componentView{externalDependencies}
, edit3DView{externalDependencies}
, formEditorView{externalDependencies}
@@ -76,6 +79,7 @@ public:
Internal::DebugView debugView;
DesignerActionManagerView designerActionManagerView;
NodeInstanceView nodeInstanceView;
+ ContentLibraryView contentLibraryView;
ComponentView componentView;
Edit3DView edit3DView;
FormEditorView formEditorView;
@@ -212,6 +216,7 @@ QList ViewManager::standardViews() const
&d->itemLibraryView,
&d->navigatorView,
&d->propertyEditorView,
+ &d->contentLibraryView,
&d->materialEditorView,
&d->materialBrowserView,
&d->statesEditorView,
@@ -392,6 +397,7 @@ QList ViewManager::widgetInfos() const
widgetInfoList.append(d->itemLibraryView.widgetInfo());
widgetInfoList.append(d->navigatorView.widgetInfo());
widgetInfoList.append(d->propertyEditorView.widgetInfo());
+ widgetInfoList.append(d->contentLibraryView.widgetInfo());
widgetInfoList.append(d->materialEditorView.widgetInfo());
widgetInfoList.append(d->materialBrowserView.widgetInfo());
if (useOldStatesEditor())
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp
similarity index 86%
rename from src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp
rename to src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp
index 24e3d3e1108..086ce32379a 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp
@@ -1,29 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
-#include "bundleimporter.h"
+#include "contentlibrarybundleimporter.h"
#include "documentmanager.h"
#include "import.h"
@@ -43,17 +21,17 @@ using namespace Utils;
namespace QmlDesigner::Internal {
-BundleImporter::BundleImporter(const QString &bundleDir,
- const QString &bundleId,
- const QStringList &sharedFiles,
- QObject *parent)
+ContentLibraryBundleImporter::ContentLibraryBundleImporter(const QString &bundleDir,
+ const QString &bundleId,
+ const QStringList &sharedFiles,
+ QObject *parent)
: QObject(parent)
, m_bundleDir(FilePath::fromString(bundleDir))
, m_bundleId(bundleId)
, m_sharedFiles(sharedFiles)
{
m_importTimer.setInterval(200);
- connect(&m_importTimer, &QTimer::timeout, this, &BundleImporter::handleImportTimer);
+ connect(&m_importTimer, &QTimer::timeout, this, &ContentLibraryBundleImporter::handleImportTimer);
m_moduleName = QStringLiteral("%1.%2").arg(
QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER),
m_bundleId).mid(1); // Chop leading slash
@@ -63,8 +41,8 @@ BundleImporter::BundleImporter(const QString &bundleDir,
// Note that there is also an asynchronous portion to the import, which will only
// be done if this method returns success. Once the asynchronous portion of the
// import is completed, importFinished signal will be emitted.
-QString BundleImporter::importComponent(const QString &qmlFile,
- const QStringList &files)
+QString ContentLibraryBundleImporter::importComponent(const QString &qmlFile,
+ const QStringList &files)
{
FilePath bundleImportPath = resolveBundleImportPath();
if (bundleImportPath.isEmpty())
@@ -171,7 +149,7 @@ QString BundleImporter::importComponent(const QString &qmlFile,
return {};
}
-void BundleImporter::handleImportTimer()
+void ContentLibraryBundleImporter::handleImportTimer()
{
auto handleFailure = [this]() {
m_importTimer.stop();
@@ -243,7 +221,7 @@ void BundleImporter::handleImportTimer()
}
}
-QVariantHash BundleImporter::loadAssetRefMap(const Utils::FilePath &bundlePath)
+QVariantHash ContentLibraryBundleImporter::loadAssetRefMap(const Utils::FilePath &bundlePath)
{
FilePath assetRefPath = bundlePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE));
const std::optional content = assetRefPath.fileContents();
@@ -260,8 +238,8 @@ QVariantHash BundleImporter::loadAssetRefMap(const Utils::FilePath &bundlePath)
return {};
}
-void BundleImporter::writeAssetRefMap(const Utils::FilePath &bundlePath,
- const QVariantHash &assetRefMap)
+void ContentLibraryBundleImporter::writeAssetRefMap(const Utils::FilePath &bundlePath,
+ const QVariantHash &assetRefMap)
{
FilePath assetRefPath = bundlePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE));
QJsonObject jsonObj = QJsonObject::fromVariantHash(assetRefMap);
@@ -271,7 +249,7 @@ void BundleImporter::writeAssetRefMap(const Utils::FilePath &bundlePath,
}
}
-QString BundleImporter::unimportComponent(const QString &qmlFile)
+QString ContentLibraryBundleImporter::unimportComponent(const QString &qmlFile)
{
FilePath bundleImportPath = resolveBundleImportPath();
if (bundleImportPath.isEmpty())
@@ -358,7 +336,7 @@ QString BundleImporter::unimportComponent(const QString &qmlFile)
return {};
}
-FilePath BundleImporter::resolveBundleImportPath()
+FilePath ContentLibraryBundleImporter::resolveBundleImportPath()
{
FilePath bundleImportPath = QmlDesignerPlugin::instance()->documentManager().currentProjectDirPath();
if (bundleImportPath.isEmpty())
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h
new file mode 100644
index 00000000000..4da431319db
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+#include "nodemetainfo.h"
+
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+QT_END_NAMESPACE
+
+namespace QmlDesigner::Internal {
+
+class ContentLibraryBundleImporter : public QObject
+{
+ Q_OBJECT
+
+public:
+ ContentLibraryBundleImporter(const QString &bundleDir,
+ const QString &bundleId,
+ const QStringList &sharedFiles,
+ QObject *parent = nullptr);
+ ~ContentLibraryBundleImporter() = default;
+
+ QString importComponent(const QString &qmlFile,
+ const QStringList &files);
+ QString unimportComponent(const QString &qmlFile);
+ Utils::FilePath resolveBundleImportPath();
+
+signals:
+ // The metaInfo parameter will be invalid if an error was encountered during
+ // asynchronous part of the import. In this case all remaining pending imports have been
+ // terminated, and will not receive separate importFinished notifications.
+ void importFinished(const QmlDesigner::NodeMetaInfo &metaInfo);
+ void unimportFinished(const QmlDesigner::NodeMetaInfo &metaInfo);
+
+private:
+ void handleImportTimer();
+ QVariantHash loadAssetRefMap(const Utils::FilePath &bundlePath);
+ void writeAssetRefMap(const Utils::FilePath &bundlePath, const QVariantHash &assetRefMap);
+
+ Utils::FilePath m_bundleDir;
+ QString m_bundleId;
+ QString m_moduleName;
+ QStringList m_sharedFiles;
+ QTimer m_importTimer;
+ int m_importTimerCount = 0;
+ bool m_importAddPending = false;
+ bool m_fullReset = false;
+ QHash m_pendingTypes; //
+};
+
+} // namespace QmlDesigner::Internal
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp
new file mode 100644
index 00000000000..8f034d7a08d
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.cpp
@@ -0,0 +1,67 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarymaterial.h"
+
+namespace QmlDesigner {
+
+ContentLibraryMaterial::ContentLibraryMaterial(QObject *parent,
+ const QString &name,
+ const QString &qml,
+ const TypeName &type,
+ const QUrl &icon,
+ const QStringList &files)
+ : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) {}
+
+bool ContentLibraryMaterial::filter(const QString &searchText)
+{
+ if (m_visible != m_name.contains(searchText, Qt::CaseInsensitive)) {
+ m_visible = !m_visible;
+ emit materialVisibleChanged();
+ }
+
+ return m_visible;
+}
+
+QUrl ContentLibraryMaterial::icon() const
+{
+ return m_icon;
+}
+
+QString ContentLibraryMaterial::qml() const
+{
+ return m_qml;
+}
+
+TypeName ContentLibraryMaterial::type() const
+{
+ return m_type;
+}
+
+QStringList ContentLibraryMaterial::files() const
+{
+ return m_files;
+}
+
+bool ContentLibraryMaterial::visible() const
+{
+ return m_visible;
+}
+
+bool ContentLibraryMaterial::setImported(bool imported)
+{
+ if (m_imported != imported) {
+ m_imported = imported;
+ emit materialImportedChanged();
+ return true;
+ }
+
+ return false;
+}
+
+bool ContentLibraryMaterial::imported() const
+{
+ return m_imported;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h
new file mode 100644
index 00000000000..5d156809583
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterial.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "qmldesignercorelib_global.h"
+
+#include
+#include
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryMaterial : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString bundleMaterialName MEMBER m_name CONSTANT)
+ Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT)
+ Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged)
+ Q_PROPERTY(bool bundleMaterialImported READ imported WRITE setImported NOTIFY materialImportedChanged)
+
+public:
+ ContentLibraryMaterial(QObject *parent,
+ const QString &name,
+ const QString &qml,
+ const TypeName &type,
+ const QUrl &icon,
+ const QStringList &files);
+
+ bool filter(const QString &searchText);
+
+ QUrl icon() const;
+ QString qml() const;
+ TypeName type() const;
+ QStringList files() const;
+ bool visible() const;
+
+ bool setImported(bool imported);
+ bool imported() const;
+
+signals:
+ void materialVisibleChanged();
+ void materialImportedChanged();
+
+private:
+ QString m_name;
+ QString m_qml;
+ TypeName m_type;
+ QUrl m_icon;
+ QStringList m_files;
+
+ bool m_visible = true;
+ bool m_imported = false;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.cpp
new file mode 100644
index 00000000000..17465f6b31b
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.cpp
@@ -0,0 +1,63 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarymaterialscategory.h"
+
+#include "contentlibrarymaterial.h"
+
+namespace QmlDesigner {
+
+ContentLibraryMaterialsCategory::ContentLibraryMaterialsCategory(QObject *parent, const QString &name)
+ : QObject(parent), m_name(name) {}
+
+void ContentLibraryMaterialsCategory::addBundleMaterial(ContentLibraryMaterial *bundleMat)
+{
+ m_categoryMaterials.append(bundleMat);
+}
+
+bool ContentLibraryMaterialsCategory::updateImportedState(const QStringList &importedMats)
+{
+ bool changed = false;
+
+ for (ContentLibraryMaterial *mat : std::as_const(m_categoryMaterials))
+ changed |= mat->setImported(importedMats.contains(mat->qml().chopped(4)));
+
+ return changed;
+}
+
+bool ContentLibraryMaterialsCategory::filter(const QString &searchText)
+{
+ bool visible = false;
+ for (ContentLibraryMaterial *mat : std::as_const(m_categoryMaterials))
+ visible |= mat->filter(searchText);
+
+ if (visible != m_visible) {
+ m_visible = visible;
+ emit categoryVisibleChanged();
+ return true;
+ }
+
+ return false;
+}
+
+QString ContentLibraryMaterialsCategory::name() const
+{
+ return m_name;
+}
+
+bool ContentLibraryMaterialsCategory::visible() const
+{
+ return m_visible;
+}
+
+bool ContentLibraryMaterialsCategory::expanded() const
+{
+ return m_expanded;
+}
+
+QList ContentLibraryMaterialsCategory::categoryMaterials() const
+{
+ return m_categoryMaterials;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.h
new file mode 100644
index 00000000000..8010270b25a
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialscategory.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryMaterial;
+
+class ContentLibraryMaterialsCategory : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString bundleCategoryName MEMBER m_name CONSTANT)
+ Q_PROPERTY(bool bundleCategoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged)
+ Q_PROPERTY(bool bundleCategoryExpanded MEMBER m_expanded NOTIFY categoryExpandChanged)
+ Q_PROPERTY(QList bundleCategoryMaterials MEMBER m_categoryMaterials
+ NOTIFY bundleMaterialsModelChanged)
+
+public:
+ ContentLibraryMaterialsCategory(QObject *parent, const QString &name);
+
+ void addBundleMaterial(ContentLibraryMaterial *bundleMat);
+ bool updateImportedState(const QStringList &importedMats);
+ bool filter(const QString &searchText);
+
+ QString name() const;
+ bool visible() const;
+ bool expanded() const;
+ QList categoryMaterials() const;
+
+signals:
+ void categoryVisibleChanged();
+ void categoryExpandChanged();
+ void bundleMaterialsModelChanged();
+
+private:
+ QString m_name;
+ bool m_visible = true;
+ bool m_expanded = true;
+
+ QList m_categoryMaterials;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
similarity index 64%
rename from src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp
rename to src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
index 7cb2a39c0d1..92be78f016b 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
@@ -1,33 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
-#include "materialbrowserbundlemodel.h"
+#include "contentlibrarymaterialsmodel.h"
-#include "bundleimporter.h"
-#include "bundlematerial.h"
-#include "bundlematerialcategory.h"
+#include "contentlibrarybundleimporter.h"
+#include "contentlibrarymaterial.h"
+#include "contentlibrarymaterialscategory.h"
#include "qmldesignerconstants.h"
#include "utils/qtcassert.h"
@@ -38,18 +16,18 @@
namespace QmlDesigner {
-MaterialBrowserBundleModel::MaterialBrowserBundleModel(QObject *parent)
+ContentLibraryMaterialsModel::ContentLibraryMaterialsModel(QObject *parent)
: QAbstractListModel(parent)
{
loadMaterialBundle();
}
-int MaterialBrowserBundleModel::rowCount(const QModelIndex &) const
+int ContentLibraryMaterialsModel::rowCount(const QModelIndex &) const
{
return m_bundleCategories.size();
}
-QVariant MaterialBrowserBundleModel::data(const QModelIndex &index, int role) const
+QVariant ContentLibraryMaterialsModel::data(const QModelIndex &index, int role) const
{
QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {});
QTC_ASSERT(roleNames().contains(role), return {});
@@ -57,13 +35,13 @@ QVariant MaterialBrowserBundleModel::data(const QModelIndex &index, int role) co
return m_bundleCategories.at(index.row())->property(roleNames().value(role));
}
-bool MaterialBrowserBundleModel::setData(const QModelIndex &index, const QVariant &value, int role)
+bool ContentLibraryMaterialsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || !roleNames().contains(role))
return false;
QByteArray roleName = roleNames().value(role);
- BundleMaterialCategory *bundleCategory = m_bundleCategories.at(index.row());
+ ContentLibraryMaterialsCategory *bundleCategory = m_bundleCategories.at(index.row());
QVariant currValue = bundleCategory->property(roleName);
if (currValue != value) {
@@ -76,12 +54,12 @@ bool MaterialBrowserBundleModel::setData(const QModelIndex &index, const QVarian
return false;
}
-bool MaterialBrowserBundleModel::isValidIndex(int idx) const
+bool ContentLibraryMaterialsModel::isValidIndex(int idx) const
{
return idx > -1 && idx < rowCount();
}
-QHash MaterialBrowserBundleModel::roleNames() const
+QHash ContentLibraryMaterialsModel::roleNames() const
{
static const QHash roles {
{Qt::UserRole + 1, "bundleCategoryName"},
@@ -92,7 +70,7 @@ QHash MaterialBrowserBundleModel::roleNames() const
return roles;
}
-void MaterialBrowserBundleModel::loadMaterialBundle()
+void ContentLibraryMaterialsModel::loadMaterialBundle()
{
if (m_matBundleLoaded || m_probeMatBundleDir)
return;
@@ -137,7 +115,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
const QJsonObject catsObj = m_matBundleObj.value("categories").toObject();
const QStringList categories = catsObj.keys();
for (const QString &cat : categories) {
- auto category = new BundleMaterialCategory(this, cat);
+ auto category = new ContentLibraryMaterialsCategory(this, cat);
const QJsonObject matsObj = catsObj.value(cat).toObject();
const QStringList mats = matsObj.keys();
@@ -156,7 +134,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
bundleId,
qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
- auto bundleMat = new BundleMaterial(category, mat, qml, type, icon, files);
+ auto bundleMat = new ContentLibraryMaterial(category, mat, qml, type, icon, files);
category->addBundleMaterial(bundleMat);
}
@@ -168,15 +146,17 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
for (const auto /*QJson{Const,}ValueRef*/ &file : sharedFilesArr)
sharedFiles.append(file.toString());
- m_importer = new Internal::BundleImporter(matBundleDir.path(), bundleId, sharedFiles);
- connect(m_importer, &Internal::BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
+ m_importer = new Internal::ContentLibraryBundleImporter(matBundleDir.path(), bundleId, sharedFiles);
+ connect(m_importer, &Internal::ContentLibraryBundleImporter::importFinished, this,
+ [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
m_importerRunning = false;
emit importerRunningChanged();
if (metaInfo.isValid())
emit bundleMaterialImported(metaInfo);
});
- connect(m_importer, &Internal::BundleImporter::unimportFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
+ connect(m_importer, &Internal::ContentLibraryBundleImporter::unimportFinished, this,
+ [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
Q_UNUSED(metaInfo)
m_importerRunning = false;
emit importerRunningChanged();
@@ -184,12 +164,26 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
});
}
-bool MaterialBrowserBundleModel::hasMaterialRoot() const
+bool ContentLibraryMaterialsModel::hasQuick3DImport() const
+{
+ return m_hasQuick3DImport;
+}
+
+void ContentLibraryMaterialsModel::setHasQuick3DImport(bool b)
+{
+ if (b == m_hasQuick3DImport)
+ return;
+
+ m_hasQuick3DImport = b;
+ emit hasQuick3DImportChanged();
+}
+
+bool ContentLibraryMaterialsModel::hasMaterialRoot() const
{
return m_hasMaterialRoot;
}
-void MaterialBrowserBundleModel::setHasMaterialRoot(bool b)
+void ContentLibraryMaterialsModel::setHasMaterialRoot(bool b)
{
if (m_hasMaterialRoot == b)
return;
@@ -198,17 +192,17 @@ void MaterialBrowserBundleModel::setHasMaterialRoot(bool b)
emit hasMaterialRootChanged();
}
-bool MaterialBrowserBundleModel::matBundleExists() const
+bool ContentLibraryMaterialsModel::matBundleExists() const
{
return m_matBundleLoaded && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3;
}
-Internal::BundleImporter *MaterialBrowserBundleModel::bundleImporter() const
+Internal::ContentLibraryBundleImporter *ContentLibraryMaterialsModel::bundleImporter() const
{
return m_importer;
}
-void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
+void ContentLibraryMaterialsModel::setSearchText(const QString &searchText)
{
QString lowerSearchText = searchText.toLower();
@@ -220,7 +214,7 @@ void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
bool anyCatVisible = false;
bool catVisibilityChanged = false;
- for (BundleMaterialCategory *cat : std::as_const(m_bundleCategories)) {
+ for (ContentLibraryMaterialsCategory *cat : std::as_const(m_bundleCategories)) {
catVisibilityChanged |= cat->filter(m_searchText);
anyCatVisible |= cat->visible();
}
@@ -234,17 +228,17 @@ void MaterialBrowserBundleModel::setSearchText(const QString &searchText)
resetModel();
}
-void MaterialBrowserBundleModel::updateImportedState(const QStringList &importedMats)
+void ContentLibraryMaterialsModel::updateImportedState(const QStringList &importedMats)
{
bool changed = false;
- for (BundleMaterialCategory *cat : std::as_const(m_bundleCategories))
+ for (ContentLibraryMaterialsCategory *cat : std::as_const(m_bundleCategories))
changed |= cat->updateImportedState(importedMats);
if (changed)
resetModel();
}
-void MaterialBrowserBundleModel::setQuick3DImportVersion(int major, int minor)
+void ContentLibraryMaterialsModel::setQuick3DImportVersion(int major, int minor)
{
bool bundleExisted = matBundleExists();
@@ -255,18 +249,18 @@ void MaterialBrowserBundleModel::setQuick3DImportVersion(int major, int minor)
emit matBundleExistsChanged();
}
-void MaterialBrowserBundleModel::resetModel()
+void ContentLibraryMaterialsModel::resetModel()
{
beginResetModel();
endResetModel();
}
-void MaterialBrowserBundleModel::applyToSelected(BundleMaterial *mat, bool add)
+void ContentLibraryMaterialsModel::applyToSelected(ContentLibraryMaterial *mat, bool add)
{
emit applyToSelectedTriggered(mat, add);
}
-void MaterialBrowserBundleModel::addToProject(BundleMaterial *mat)
+void ContentLibraryMaterialsModel::addToProject(ContentLibraryMaterial *mat)
{
QString err = m_importer->importComponent(mat->qml(), mat->files());
@@ -278,7 +272,7 @@ void MaterialBrowserBundleModel::addToProject(BundleMaterial *mat)
}
}
-void MaterialBrowserBundleModel::removeFromProject(BundleMaterial *mat)
+void ContentLibraryMaterialsModel::removeFromProject(ContentLibraryMaterial *mat)
{
emit bundleMaterialAboutToUnimport(mat->type());
@@ -292,4 +286,18 @@ void MaterialBrowserBundleModel::removeFromProject(BundleMaterial *mat)
}
}
+bool ContentLibraryMaterialsModel::hasModelSelection() const
+{
+ return m_hasModelSelection;
+}
+
+void ContentLibraryMaterialsModel::setHasModelSelection(bool b)
+{
+ if (b == m_hasModelSelection)
+ return;
+
+ m_hasModelSelection = b;
+ emit hasModelSelectionChanged();
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h
similarity index 50%
rename from src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h
rename to src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h
index beb445422e7..9fe76cd25df 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h
@@ -1,58 +1,35 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
-#include
-#include
+#include "nodemetainfo.h"
#include
#include
-#include
-#include
namespace QmlDesigner {
-class BundleMaterial;
-class BundleMaterialCategory;
+class ContentLibraryMaterial;
+class ContentLibraryMaterialsCategory;
namespace Internal {
-class BundleImporter;
+class ContentLibraryBundleImporter;
}
-class MaterialBrowserBundleModel : public QAbstractListModel
+class ContentLibraryMaterialsModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged)
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
+ Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
+ Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
Q_PROPERTY(bool importerRunning MEMBER m_importerRunning NOTIFY importerRunningChanged)
public:
- MaterialBrowserBundleModel(QObject *parent = nullptr);
+ ContentLibraryMaterialsModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@@ -64,25 +41,32 @@ public:
void setQuick3DImportVersion(int major, int minor);
+ bool hasQuick3DImport() const;
+ void setHasQuick3DImport(bool b);
+
bool hasMaterialRoot() const;
void setHasMaterialRoot(bool b);
bool matBundleExists() const;
- Internal::BundleImporter *bundleImporter() const;
+ bool hasModelSelection() const;
+ void setHasModelSelection(bool b);
void resetModel();
- Q_INVOKABLE void applyToSelected(QmlDesigner::BundleMaterial *mat, bool add = false);
- Q_INVOKABLE void addToProject(QmlDesigner::BundleMaterial *mat);
- Q_INVOKABLE void removeFromProject(QmlDesigner::BundleMaterial *mat);
+ Internal::ContentLibraryBundleImporter *bundleImporter() const;
+
+ Q_INVOKABLE void applyToSelected(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
+ Q_INVOKABLE void addToProject(QmlDesigner::ContentLibraryMaterial *mat);
+ Q_INVOKABLE void removeFromProject(QmlDesigner::ContentLibraryMaterial *mat);
signals:
void isEmptyChanged();
void hasQuick3DImportChanged();
+ void hasModelSelectionChanged();
void hasMaterialRootChanged();
void materialVisibleChanged();
- void applyToSelectedTriggered(QmlDesigner::BundleMaterial *mat, bool add = false);
+ void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false);
void bundleMaterialImported(const QmlDesigner::NodeMetaInfo &metaInfo);
void bundleMaterialAboutToUnimport(const QmlDesigner::TypeName &type);
void bundleMaterialUnimported(const QmlDesigner::NodeMetaInfo &metaInfo);
@@ -94,13 +78,15 @@ private:
bool isValidIndex(int idx) const;
QString m_searchText;
- QList m_bundleCategories;
+ QList m_bundleCategories;
QJsonObject m_matBundleObj;
- Internal::BundleImporter *m_importer = nullptr;
+ Internal::ContentLibraryBundleImporter *m_importer = nullptr;
bool m_isEmpty = true;
bool m_hasMaterialRoot = false;
+ bool m_hasQuick3DImport = false;
bool m_matBundleLoaded = false;
+ bool m_hasModelSelection = false;
bool m_probeMatBundleDir = false;
bool m_importerRunning = false;
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp
new file mode 100644
index 00000000000..288e04aaff6
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarytexture.h"
+
+namespace QmlDesigner {
+
+ContentLibraryTexture::ContentLibraryTexture(QObject *parent, const QString &path, const QUrl &icon)
+ : QObject(parent)
+ , m_path(path)
+ , m_icon(icon) {}
+
+bool ContentLibraryTexture::filter(const QString &searchText)
+{
+ if (m_visible != m_path.contains(searchText, Qt::CaseInsensitive)) {
+ m_visible = !m_visible;
+ emit textureVisibleChanged();
+ }
+
+ return m_visible;
+}
+
+QUrl ContentLibraryTexture::icon() const
+{
+ return m_icon;
+}
+
+QString ContentLibraryTexture::path() const
+{
+ return m_path;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h
new file mode 100644
index 00000000000..88d50158325
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryTexture : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString texturePath MEMBER m_path CONSTANT)
+ Q_PROPERTY(QUrl textureIcon MEMBER m_icon CONSTANT)
+ Q_PROPERTY(bool textureVisible MEMBER m_visible NOTIFY textureVisibleChanged)
+
+public:
+ ContentLibraryTexture(QObject *parent, const QString &path, const QUrl &icon);
+
+ bool filter(const QString &searchText);
+
+ QUrl icon() const;
+ QString path() const;
+
+signals:
+ void textureVisibleChanged();
+
+private:
+ QString m_path;
+ QUrl m_icon;
+
+ bool m_visible = true;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp
new file mode 100644
index 00000000000..56468364e67
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarytexturescategory.h"
+
+#include "contentlibrarytexture.h"
+
+#include
+
+namespace QmlDesigner {
+
+ContentLibraryTexturesCategory::ContentLibraryTexturesCategory(QObject *parent, const QString &name)
+ : QObject(parent), m_name(name) {}
+
+void ContentLibraryTexturesCategory::addTexture(const QFileInfo &tex)
+{
+ QUrl icon = QUrl::fromLocalFile(tex.path() + "/icon/" + tex.baseName() + ".png");
+ m_categoryTextures.append(new ContentLibraryTexture(this, tex.filePath(), icon));
+}
+
+bool ContentLibraryTexturesCategory::filter(const QString &searchText)
+{
+ bool visible = false;
+ for (ContentLibraryTexture *tex : std::as_const(m_categoryTextures))
+ visible |= tex->filter(searchText);
+
+ if (visible != m_visible) {
+ m_visible = visible;
+ emit categoryVisibleChanged();
+ return true;
+ }
+
+ return false;
+}
+
+QString ContentLibraryTexturesCategory::name() const
+{
+ return m_name;
+}
+
+bool ContentLibraryTexturesCategory::visible() const
+{
+ return m_visible;
+}
+
+bool ContentLibraryTexturesCategory::expanded() const
+{
+ return m_expanded;
+}
+
+QList ContentLibraryTexturesCategory::categoryTextures() const
+{
+ return m_categoryTextures;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h
new file mode 100644
index 00000000000..1e0055d28cd
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+QT_BEGIN_NAMESPACE
+class QFileInfo;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+
+class ContentLibraryTexture;
+
+class ContentLibraryTexturesCategory : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString bundleCategoryName MEMBER m_name CONSTANT)
+ Q_PROPERTY(bool bundleCategoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged)
+ Q_PROPERTY(bool bundleCategoryExpanded MEMBER m_expanded NOTIFY categoryExpandChanged)
+ Q_PROPERTY(QList bundleCategoryTextures MEMBER m_categoryTextures
+ NOTIFY bundleTexturesModelChanged)
+
+public:
+ ContentLibraryTexturesCategory(QObject *parent, const QString &name);
+
+ void addTexture(const QFileInfo &tex);
+ bool filter(const QString &searchText);
+
+ QString name() const;
+ bool visible() const;
+ bool expanded() const;
+ QList categoryTextures() const;
+
+signals:
+ void categoryVisibleChanged();
+ void categoryExpandChanged();
+ void bundleTexturesModelChanged();
+
+private:
+ QString m_name;
+ bool m_visible = true;
+ bool m_expanded = true;
+
+ QList m_categoryTextures;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp
new file mode 100644
index 00000000000..38c9522879b
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp
@@ -0,0 +1,185 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarytexturesmodel.h"
+
+#include "contentlibrarytexturescategory.h"
+#include "utils/qtcassert.h"
+
+#include
+#include
+#include
+#include
+
+namespace QmlDesigner {
+
+ContentLibraryTexturesModel::ContentLibraryTexturesModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+int ContentLibraryTexturesModel::rowCount(const QModelIndex &) const
+{
+ return m_bundleCategories.size();
+}
+
+QVariant ContentLibraryTexturesModel::data(const QModelIndex &index, int role) const
+{
+ QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {});
+ QTC_ASSERT(roleNames().contains(role), return {});
+
+ return m_bundleCategories.at(index.row())->property(roleNames().value(role));
+}
+
+bool ContentLibraryTexturesModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid() || !roleNames().contains(role))
+ return false;
+
+ QByteArray roleName = roleNames().value(role);
+ ContentLibraryTexturesCategory *bundleCategory = m_bundleCategories.at(index.row());
+ QVariant currValue = bundleCategory->property(roleName);
+
+ if (currValue != value) {
+ bundleCategory->setProperty(roleName, value);
+
+ emit dataChanged(index, index, {role});
+ return true;
+ }
+
+ return false;
+}
+
+bool ContentLibraryTexturesModel::isValidIndex(int idx) const
+{
+ return idx > -1 && idx < rowCount();
+}
+
+QHash ContentLibraryTexturesModel::roleNames() const
+{
+ static const QHash roles {
+ {Qt::UserRole + 1, "bundleCategoryName"},
+ {Qt::UserRole + 2, "bundleCategoryVisible"},
+ {Qt::UserRole + 3, "bundleCategoryExpanded"},
+ {Qt::UserRole + 4, "bundleCategoryTextures"}
+ };
+ return roles;
+}
+
+void ContentLibraryTexturesModel::loadTextureBundle(const QString &bundlePath)
+{
+ QDir bundleDir = QDir(bundlePath);
+ if (!bundleDir.exists()) {
+ qWarning() << __FUNCTION__ << "textures bundle folder doesn't exist." << bundlePath;
+ return;
+ }
+
+ if (m_texBundleLoaded)
+ return;
+
+ const QFileInfoList dirs = bundleDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QFileInfo &dir : dirs) {
+ auto category = new ContentLibraryTexturesCategory(this, dir.fileName());
+ const QFileInfoList texFiles = QDir(dir.filePath()).entryInfoList(QDir::Files);
+ for (const QFileInfo &tex : texFiles)
+ category->addTexture(tex);
+ m_bundleCategories.append(category);
+ }
+}
+
+bool ContentLibraryTexturesModel::hasQuick3DImport() const
+{
+ return m_hasQuick3DImport;
+}
+
+void ContentLibraryTexturesModel::setHasQuick3DImport(bool b)
+{
+ if (b == m_hasQuick3DImport)
+ return;
+
+ m_hasQuick3DImport = b;
+ emit hasQuick3DImportChanged();
+}
+
+bool ContentLibraryTexturesModel::hasMaterialRoot() const
+{
+ return m_hasMaterialRoot;
+}
+
+void ContentLibraryTexturesModel::setHasMaterialRoot(bool b)
+{
+ if (m_hasMaterialRoot == b)
+ return;
+
+ m_hasMaterialRoot = b;
+ emit hasMaterialRootChanged();
+}
+
+bool ContentLibraryTexturesModel::matBundleExists() const
+{
+ return m_texBundleLoaded && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3;
+}
+
+void ContentLibraryTexturesModel::setSearchText(const QString &searchText)
+{
+ QString lowerSearchText = searchText.toLower();
+
+ if (m_searchText == lowerSearchText)
+ return;
+
+ m_searchText = lowerSearchText;
+
+ bool anyCatVisible = false;
+ bool catVisibilityChanged = false;
+
+ for (ContentLibraryTexturesCategory *cat : std::as_const(m_bundleCategories)) {
+ catVisibilityChanged |= cat->filter(m_searchText);
+ anyCatVisible |= cat->visible();
+ }
+
+ if (anyCatVisible == m_isEmpty) {
+ m_isEmpty = !anyCatVisible;
+ emit isEmptyChanged();
+ }
+
+ if (catVisibilityChanged)
+ resetModel();
+}
+
+void ContentLibraryTexturesModel::setQuick3DImportVersion(int major, int minor)
+{
+ bool bundleExisted = matBundleExists();
+
+ m_quick3dMajorVersion = major;
+ m_quick3dMinorVersion = minor;
+
+ if (bundleExisted != matBundleExists())
+ emit matBundleExistsChanged();
+}
+
+void ContentLibraryTexturesModel::resetModel()
+{
+ beginResetModel();
+ endResetModel();
+}
+
+void ContentLibraryTexturesModel::addToProject(const QString &mat)
+{
+ // TODO: import asset
+}
+
+bool ContentLibraryTexturesModel::hasModelSelection() const
+{
+ return m_hasModelSelection;
+}
+
+void ContentLibraryTexturesModel::setHasModelSelection(bool b)
+{
+ if (b == m_hasModelSelection)
+ return;
+
+ m_hasModelSelection = b;
+ emit hasModelSelectionChanged();
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h
new file mode 100644
index 00000000000..8009dd3ff80
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryTexturesCategory;
+
+class ContentLibraryTexturesModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged)
+ Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
+ Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
+ Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
+ Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
+
+public:
+ ContentLibraryTexturesModel(QObject *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+ QHash roleNames() const override;
+
+ void setSearchText(const QString &searchText);
+
+ void setQuick3DImportVersion(int major, int minor);
+
+ bool hasQuick3DImport() const;
+ void setHasQuick3DImport(bool b);
+
+ bool hasMaterialRoot() const;
+ void setHasMaterialRoot(bool b);
+
+ bool matBundleExists() const;
+
+ bool hasModelSelection() const;
+ void setHasModelSelection(bool b);
+
+ void resetModel();
+ void loadTextureBundle(const QString &bundlePath);
+
+ Q_INVOKABLE void addToProject(const QString &mat);
+
+signals:
+ void isEmptyChanged();
+ void hasQuick3DImportChanged();
+ void hasModelSelectionChanged();
+ void hasMaterialRootChanged();
+ void materialVisibleChanged();
+ void matBundleExistsChanged();
+
+private:
+ bool isValidIndex(int idx) const;
+
+ QString m_searchText;
+ QList m_bundleCategories;
+
+ bool m_isEmpty = true;
+ bool m_hasMaterialRoot = false;
+ bool m_hasQuick3DImport = false;
+ bool m_texBundleLoaded = false;
+ bool m_hasModelSelection = false;
+
+ int m_quick3dMajorVersion = -1;
+ int m_quick3dMinorVersion = -1;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
new file mode 100644
index 00000000000..fe035cee345
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
@@ -0,0 +1,354 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibraryview.h"
+
+#include "contentlibrarybundleimporter.h"
+#include "contentlibrarywidget.h"
+#include "contentlibrarymaterial.h"
+#include "contentlibrarymaterialsmodel.h"
+#include "modelnodeoperations.h"
+#include "nodelistproperty.h"
+#include "qmlobjectnode.h"
+#include "variantproperty.h"
+
+#include
+#include
+
+#ifndef QMLDESIGNER_TEST
+#include
+#include
+#include
+#include
+#include
+#endif
+
+namespace QmlDesigner {
+
+ContentLibraryView::ContentLibraryView(ExternalDependenciesInterface &externalDependencies)
+ : AbstractView(externalDependencies)
+{}
+
+ContentLibraryView::~ContentLibraryView()
+{}
+
+bool ContentLibraryView::hasWidget() const
+{
+ return true;
+}
+
+WidgetInfo ContentLibraryView::widgetInfo()
+{
+ if (m_widget.isNull()) {
+ m_widget = new ContentLibraryWidget();
+
+ connect(m_widget, &ContentLibraryWidget::bundleMaterialDragStarted, this,
+ [&] (QmlDesigner::ContentLibraryMaterial *mat) {
+ m_draggedBundleMaterial = mat;
+ });
+ connect(m_widget, &ContentLibraryWidget::addTextureRequested, this,
+ [&] (const QString texPath, ContentLibraryWidget::AddTextureMode mode) {
+ AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false);
+
+ if (result == AddFilesResult::Failed) {
+ Core::AsynchronousMessageBox::warning(tr("Failed to Add Texture"),
+ tr("Could not add %1 to project.").arg(texPath));
+ return;
+ }
+
+ if (mode == ContentLibraryWidget::AddTextureMode::Texture) {
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return;
+
+ NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.Texture");
+ ModelNode newTexNode = createModelNode("QtQuick3D.Texture", metaInfo.majorVersion(),
+ metaInfo.minorVersion());
+ newTexNode.validId();
+ VariantProperty sourceProp = newTexNode.variantProperty("source");
+ sourceProp.setValue(QLatin1String("images/%1").arg(texPath.split('/').last()));
+ matLib.defaultNodeListProperty().reparentHere(newTexNode);
+ } else if (mode == ContentLibraryWidget::AddTextureMode::Environment) {
+ // TODO: assign as env
+ }
+ });
+
+ ContentLibraryMaterialsModel *materialsModel = m_widget->materialsModel().data();
+
+ connect(materialsModel, &ContentLibraryMaterialsModel::applyToSelectedTriggered, this,
+ [&] (ContentLibraryMaterial *bundleMat, bool add) {
+ if (m_selectedModels.isEmpty())
+ return;
+
+ m_bundleMaterialTargets = m_selectedModels;
+ m_bundleMaterialAddToSelected = add;
+
+ ModelNode defaultMat = getBundleMaterialDefaultInstance(bundleMat->type());
+ if (defaultMat.isValid())
+ applyBundleMaterialToDropTarget(defaultMat);
+ else
+ m_widget->materialsModel()->addToProject(bundleMat);
+ });
+
+ connect(materialsModel, &ContentLibraryMaterialsModel::bundleMaterialImported, this,
+ [&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
+ applyBundleMaterialToDropTarget({}, metaInfo);
+ updateBundleMaterialsImportedState();
+ });
+
+ connect(materialsModel, &ContentLibraryMaterialsModel::bundleMaterialAboutToUnimport, this,
+ [&] (const QmlDesigner::TypeName &type) {
+ // delete instances of the bundle material that is about to be unimported
+ executeInTransaction("MaterialBrowserView::widgetInfo", [&] {
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return;
+
+ Utils::reverseForeach(matLib.directSubModelNodes(), [&](const ModelNode &mat) {
+ if (mat.isValid() && mat.type() == type)
+ QmlObjectNode(mat).destroy();
+ });
+ });
+ });
+
+ connect(materialsModel, &ContentLibraryMaterialsModel::bundleMaterialUnimported, this,
+ &ContentLibraryView::updateBundleMaterialsImportedState);
+ }
+
+ return createWidgetInfo(m_widget.data(),
+ "ContentLibrary",
+ WidgetInfo::LeftPane,
+ 0,
+ tr("Content Library"));
+}
+
+void ContentLibraryView::modelAttached(Model *model)
+{
+ AbstractView::modelAttached(model);
+
+ m_hasQuick3DImport = model->hasImport("QtQuick3D");
+
+ m_widget->materialsModel()->setHasMaterialRoot(rootModelNode().metaInfo().isQtQuick3DMaterial());
+ m_widget->materialsModel()->setHasQuick3DImport(m_hasQuick3DImport);
+
+ updateBundleMaterialsQuick3DVersion();
+ updateBundleMaterialsImportedState();
+}
+
+void ContentLibraryView::modelAboutToBeDetached(Model *model)
+{
+
+ AbstractView::modelAboutToBeDetached(model);
+}
+
+void ContentLibraryView::importsChanged(const QList &addedImports, const QList &removedImports)
+{
+ Q_UNUSED(addedImports)
+ Q_UNUSED(removedImports)
+
+ updateBundleMaterialsQuick3DVersion();
+
+ bool hasQuick3DImport = model()->hasImport("QtQuick3D");
+
+ if (hasQuick3DImport == m_hasQuick3DImport)
+ return;
+
+ m_hasQuick3DImport = hasQuick3DImport;
+ m_widget->materialsModel()->setHasQuick3DImport(m_hasQuick3DImport);
+}
+
+void ContentLibraryView::selectedNodesChanged(const QList &selectedNodeList,
+ const QList &lastSelectedNodeList)
+{
+ Q_UNUSED(lastSelectedNodeList)
+
+ m_selectedModels = Utils::filtered(selectedNodeList, [](const ModelNode &node) {
+ return node.metaInfo().isQtQuick3DModel();
+ });
+
+ m_widget->materialsModel()->setHasModelSelection(!m_selectedModels.isEmpty());
+}
+
+void ContentLibraryView::customNotification(const AbstractView *view, const QString &identifier,
+ const QList &nodeList, const QList &data)
+{
+ Q_UNUSED(data)
+
+ if (view == this)
+ return;
+
+ if (identifier == "drop_bundle_material") {
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return;
+
+ m_bundleMaterialTargets = nodeList;
+
+ ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
+ if (defaultMat.isValid()) {
+ if (m_bundleMaterialTargets.isEmpty()) // if no drop target, create a duplicate material
+ createMaterial(defaultMat.metaInfo());
+ else
+ applyBundleMaterialToDropTarget(defaultMat);
+ } else {
+ m_widget->materialsModel()->addToProject(m_draggedBundleMaterial);
+ }
+
+ m_draggedBundleMaterial = nullptr;
+ }
+}
+
+void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundleMat,
+ const NodeMetaInfo &metaInfo)
+{
+ if (!bundleMat.isValid() && !metaInfo.isValid())
+ return;
+
+ executeInTransaction("MaterialBrowserView::applyBundleMaterialToDropTarget", [&] {
+ ModelNode newMatNode = metaInfo.isValid() ? createMaterial(metaInfo) : bundleMat;
+
+ // TODO: unify this logic as it exist elsewhere also
+ auto expToList = [](const QString &exp) {
+ QString copy = exp;
+ copy = copy.remove("[").remove("]");
+
+ QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
+ for (QString &str : tmp)
+ str = str.trimmed();
+
+ return tmp;
+ };
+
+ auto listToExp = [](QStringList &stringList) {
+ if (stringList.size() > 1)
+ return QString("[" + stringList.join(",") + "]");
+
+ if (stringList.size() == 1)
+ return stringList.first();
+
+ return QString();
+ };
+
+ for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) {
+ if (target.isValid() && target.metaInfo().isQtQuick3DModel()) {
+ QmlObjectNode qmlObjNode(target);
+ if (m_bundleMaterialAddToSelected) {
+ QStringList matList = expToList(qmlObjNode.expression("materials"));
+ matList.append(newMatNode.id());
+ QString updatedExp = listToExp(matList);
+ qmlObjNode.setBindingProperty("materials", updatedExp);
+ } else {
+ qmlObjNode.setBindingProperty("materials", newMatNode.id());
+ }
+ }
+
+ m_bundleMaterialTargets = {};
+ m_bundleMaterialAddToSelected = false;
+ }
+ });
+}
+
+ModelNode ContentLibraryView::getBundleMaterialDefaultInstance(const TypeName &type)
+{
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return {};
+
+ const QList matLibNodes = matLib.directSubModelNodes();
+ for (const ModelNode &mat : matLibNodes) {
+ if (mat.isValid() && mat.type() == type) {
+ bool isDefault = true;
+ const QList props = mat.properties();
+ for (const AbstractProperty &prop : props) {
+ if (prop.name() != "objectName") {
+ isDefault = false;
+ break;
+ }
+ }
+
+ if (isDefault)
+ return mat;
+ }
+ }
+
+ return {};
+}
+
+ModelNode ContentLibraryView::createMaterial(const NodeMetaInfo &metaInfo)
+{
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid() || !metaInfo.isValid())
+ return {};
+
+ ModelNode newMatNode = createModelNode(metaInfo.typeName(), metaInfo.majorVersion(),
+ metaInfo.minorVersion());
+ matLib.defaultNodeListProperty().reparentHere(newMatNode);
+
+ static QRegularExpression rgx("([A-Z])([a-z]*)");
+ QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed();
+ if (newName.endsWith(" Material"))
+ newName.chop(9); // remove trailing " Material"
+ QString newId = model()->generateIdFromName(newName, "material");
+ newMatNode.setIdWithRefactoring(newId);
+
+ VariantProperty objNameProp = newMatNode.variantProperty("objectName");
+ objNameProp.setValue(newName);
+
+ return newMatNode;
+}
+
+void ContentLibraryView::updateBundleMaterialsImportedState()
+{
+ using namespace Utils;
+
+ if (!m_widget->materialsModel()->bundleImporter())
+ return;
+
+ QStringList importedBundleMats;
+
+ FilePath materialBundlePath = m_widget->materialsModel()->bundleImporter()->resolveBundleImportPath();
+
+ if (materialBundlePath.exists()) {
+ importedBundleMats = transform(materialBundlePath.dirEntries({{"*.qml"}, QDir::Files}),
+ [](const FilePath &f) { return f.fileName().chopped(4); });
+ }
+
+ m_widget->materialsModel()->updateImportedState(importedBundleMats);
+}
+
+void ContentLibraryView::updateBundleMaterialsQuick3DVersion()
+{
+ bool hasImport = false;
+ int major = -1;
+ int minor = -1;
+ const QString url {"QtQuick3D"};
+ const auto imports = model()->imports();
+ for (const auto &import : imports) {
+ if (import.url() == url) {
+ hasImport = true;
+ const int importMajor = import.majorVersion();
+ if (major < importMajor) {
+ minor = -1;
+ major = importMajor;
+ }
+ if (major == importMajor)
+ minor = qMax(minor, import.minorVersion());
+ }
+ }
+#ifndef QMLDESIGNER_TEST
+ if (hasImport && major == -1) {
+ // Import without specifying version, so we take the kit version
+ auto target = ProjectExplorer::SessionManager::startupTarget();
+ if (target) {
+ QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
+ if (qtVersion) {
+ major = qtVersion->qtVersion().majorVersion();
+ minor = qtVersion->qtVersion().minorVersion();
+ }
+ }
+ }
+#endif
+ m_widget->materialsModel()->setQuick3DImportVersion(major, minor);
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h
new file mode 100644
index 00000000000..8ece6a76d05
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "abstractview.h"
+#include "nodemetainfo.h"
+
+#include
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryMaterial;
+class ContentLibraryWidget;
+class Model;
+
+class ContentLibraryView : public AbstractView
+{
+ Q_OBJECT
+
+public:
+ ContentLibraryView(ExternalDependenciesInterface &externalDependencies);
+ ~ContentLibraryView() override;
+
+ bool hasWidget() const override;
+ WidgetInfo widgetInfo() override;
+
+ // AbstractView
+ void modelAttached(Model *model) override;
+ void modelAboutToBeDetached(Model *model) override;
+ void importsChanged(const QList &addedImports, const QList &removedImports) override;
+ void selectedNodesChanged(const QList &selectedNodeList,
+ const QList &lastSelectedNodeList) override;
+ void customNotification(const AbstractView *view, const QString &identifier,
+ const QList &nodeList, const QList &data) override;
+
+private:
+ void updateBundleMaterialsImportedState();
+ void updateBundleMaterialsQuick3DVersion();
+ void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
+ ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
+ ModelNode createMaterial(const NodeMetaInfo &metaInfo);
+
+ QPointer m_widget;
+ QList m_bundleMaterialTargets;
+ QList m_selectedModels; // selected 3D model nodes
+ ContentLibraryMaterial *m_draggedBundleMaterial = nullptr;
+ bool m_bundleMaterialAddToSelected = false;
+ bool m_hasQuick3DImport = false;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
new file mode 100644
index 00000000000..02d116811eb
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
@@ -0,0 +1,238 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "contentlibrarywidget.h"
+
+#include "contentlibrarymaterial.h"
+#include "contentlibrarymaterialsmodel.h"
+#include "contentlibrarytexture.h"
+#include "contentlibrarytexturesmodel.h"
+
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace QmlDesigner {
+
+static QString propertyEditorResourcesPath()
+{
+#ifdef SHARE_QML_PATH
+ if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
+ return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
+#endif
+ return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
+}
+
+bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::FocusOut) {
+ if (obj == m_quickWidget.data())
+ QMetaObject::invokeMethod(m_quickWidget->rootObject(), "closeContextMenu");
+ } else if (event->type() == QMouseEvent::MouseMove) {
+ DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
+ QTC_ASSERT(document, return false);
+ Model *model = document->currentModel();
+ QTC_ASSERT(model, return false);
+
+ if (m_materialToDrag) {
+ QMouseEvent *me = static_cast(event);
+ if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
+ QByteArray data;
+ QMimeData *mimeData = new QMimeData;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << m_materialToDrag->type();
+ mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data);
+ mimeData->removeFormat("text/plain");
+
+ if (!m_draggedMaterial) {
+ m_draggedMaterial = m_materialToDrag;
+ emit draggedMaterialChanged();
+ }
+
+ emit bundleMaterialDragStarted(m_materialToDrag);
+ model->startDrag(mimeData, m_materialToDrag->icon().toLocalFile());
+ m_materialToDrag = nullptr;
+ }
+ } else if (m_textureToDrag) {
+ QMouseEvent *me = static_cast(event);
+ if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
+ QByteArray data;
+ QMimeData *mimeData = new QMimeData;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << m_textureToDrag->path();
+ mimeData->setData(Constants::MIME_TYPE_BUNDLE_TEXTURE, data);
+ mimeData->removeFormat("text/plain");
+
+ model->startDrag(mimeData, m_textureToDrag->icon().toLocalFile());
+ m_textureToDrag = nullptr;
+ }
+ }
+ } else if (event->type() == QMouseEvent::MouseButtonRelease) {
+ m_materialToDrag = nullptr;
+ m_textureToDrag = nullptr;
+
+ if (m_draggedMaterial) {
+ m_draggedMaterial = nullptr;
+ emit draggedMaterialChanged();
+ }
+ }
+
+ return QObject::eventFilter(obj, event);
+}
+
+ContentLibraryWidget::ContentLibraryWidget()
+ : m_quickWidget(new QQuickWidget(this))
+ , m_materialsModel(new ContentLibraryMaterialsModel(this))
+ , m_texturesModel(new ContentLibraryTexturesModel(this))
+ , m_environmentsModel(new ContentLibraryTexturesModel(this))
+{
+ setWindowTitle(tr("Content Library", "Title of content library widget"));
+ setMinimumWidth(120);
+
+ m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
+ m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground));
+
+ QString textureBundlePath = findTextureBundlePath();
+ m_texturesModel->loadTextureBundle(textureBundlePath + "/Textures");
+ m_environmentsModel->loadTextureBundle(textureBundlePath + "/Environments");
+
+ m_quickWidget->rootContext()->setContextProperties({
+ {"rootView", QVariant::fromValue(this)},
+ {"materialsModel", QVariant::fromValue(m_materialsModel.data())},
+ {"texturesModel", QVariant::fromValue(m_texturesModel.data())},
+ {"environmentsModel", QVariant::fromValue(m_environmentsModel.data())},
+ });
+
+ Theme::setupTheme(m_quickWidget->engine());
+ m_quickWidget->installEventFilter(this);
+
+ auto layout = new QVBoxLayout(this);
+ layout->setContentsMargins({});
+ layout->setSpacing(0);
+ layout->addWidget(m_quickWidget.data());
+
+ updateSearch();
+
+ setStyleSheet(Theme::replaceCssColors(
+ QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
+
+ m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F11), this);
+ connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ContentLibraryWidget::reloadQmlSource);
+
+// QmlDesignerPlugin::trackWidgetFocusTime(this, Constants::EVENT_MATERIALBROWSER_TIME); // TODO
+
+ reloadQmlSource();
+}
+
+QList ContentLibraryWidget::createToolBarWidgets()
+{
+ return {};
+}
+
+void ContentLibraryWidget::handleSearchFilterChanged(const QString &filterText)
+{
+ if (filterText != m_filterText) {
+ m_filterText = filterText;
+ updateSearch();
+ }
+}
+
+QString ContentLibraryWidget::qmlSourcesPath()
+{
+#ifdef SHARE_QML_PATH
+ if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
+ return QLatin1String(SHARE_QML_PATH) + "/contentLibraryQmlSource";
+#endif
+ return Core::ICore::resourcePath("qmldesigner/contentLibraryQmlSource").toString();
+}
+
+void ContentLibraryWidget::clearSearchFilter()
+{
+ QMetaObject::invokeMethod(m_quickWidget->rootObject(), "clearSearchFilter");
+}
+
+void ContentLibraryWidget::reloadQmlSource()
+{
+ const QString materialBrowserQmlPath = qmlSourcesPath() + "/ContentLibrary.qml";
+
+ QTC_ASSERT(QFileInfo::exists(materialBrowserQmlPath), return);
+
+ m_quickWidget->engine()->clearComponentCache();
+ m_quickWidget->setSource(QUrl::fromLocalFile(materialBrowserQmlPath));
+}
+
+void ContentLibraryWidget::updateSearch()
+{
+ m_materialsModel->setSearchText(m_filterText);
+ m_texturesModel->setSearchText(m_filterText);
+ m_environmentsModel->setSearchText(m_filterText);
+ m_quickWidget->update();
+}
+
+QString ContentLibraryWidget::findTextureBundlePath()
+{
+ QDir texBundleDir(qEnvironmentVariable("TEXTURE_BUNDLE_PATH"));
+
+ // search for matBundleDir from exec dir and up
+ if (texBundleDir.dirName() == ".") {
+ texBundleDir.setPath(QCoreApplication::applicationDirPath());
+ while (!texBundleDir.cd("texture_bundle") && texBundleDir.cdUp())
+ ; // do nothing
+
+ if (texBundleDir.dirName() != "texture_bundle") // bundlePathDir not found
+ return {};
+ }
+
+ return texBundleDir.path();
+}
+
+void ContentLibraryWidget::startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat,
+ const QPointF &mousePos)
+{
+ m_materialToDrag = mat;
+ m_dragStartPoint = mousePos.toPoint();
+}
+
+void ContentLibraryWidget::startDragTexture(QmlDesigner::ContentLibraryTexture *tex,
+ const QPointF &mousePos)
+{
+ m_textureToDrag = tex;
+ m_dragStartPoint = mousePos.toPoint();
+}
+
+void ContentLibraryWidget::addImage(ContentLibraryTexture *tex)
+{
+ emit addTextureRequested(tex->path(), AddTextureMode::Image);
+}
+
+void ContentLibraryWidget::addTexture(ContentLibraryTexture *tex)
+{
+ emit addTextureRequested(tex->path(), AddTextureMode::Texture);
+}
+
+void ContentLibraryWidget::addEnv(ContentLibraryTexture *tex)
+{
+ emit addTextureRequested(tex->path(), AddTextureMode::Environment);
+}
+
+QPointer ContentLibraryWidget::materialsModel() const
+{
+ return m_materialsModel;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
new file mode 100644
index 00000000000..3eb470b7ae3
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
@@ -0,0 +1,76 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QShortcut;
+class QToolButton;
+class QQuickWidget;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+
+class ContentLibraryTexture;
+class ContentLibraryMaterial;
+class ContentLibraryTexturesModel;
+class ContentLibraryMaterialsModel;
+
+class ContentLibraryWidget : public QFrame
+{
+ Q_OBJECT
+
+public:
+ ContentLibraryWidget();
+
+ QList createToolBarWidgets();
+
+ static QString qmlSourcesPath();
+ void clearSearchFilter();
+
+ Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
+
+ void setMaterialsModel(QPointer newMaterialsModel);
+
+ QPointer materialsModel() const;
+
+ Q_INVOKABLE void startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat, const QPointF &mousePos);
+ Q_INVOKABLE void startDragTexture(QmlDesigner::ContentLibraryTexture *tex, const QPointF &mousePos);
+ Q_INVOKABLE void addImage(QmlDesigner::ContentLibraryTexture *tex);
+ Q_INVOKABLE void addTexture(QmlDesigner::ContentLibraryTexture *tex);
+ Q_INVOKABLE void addEnv(QmlDesigner::ContentLibraryTexture *tex);
+
+ enum class AddTextureMode { Image, Texture, Environment };
+
+signals:
+ void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat);
+ void draggedMaterialChanged();
+ void addTextureRequested(const QString texPath, QmlDesigner::ContentLibraryWidget::AddTextureMode mode);
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event) override;
+
+private:
+ void reloadQmlSource();
+ void updateSearch();
+ QString findTextureBundlePath();
+
+ QScopedPointer m_quickWidget;
+ QPointer m_materialsModel;
+ QPointer m_texturesModel;
+ QPointer m_environmentsModel;
+
+ QShortcut *m_qmlSourceUpdateShortcut = nullptr;
+
+ QString m_filterText;
+
+ ContentLibraryMaterial *m_materialToDrag = nullptr;
+ ContentLibraryMaterial *m_draggedMaterial = nullptr;
+ ContentLibraryTexture *m_textureToDrag = nullptr;
+ QPoint m_dragStartPoint;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
index 80fd6aa2b16..c734b0e362c 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
@@ -286,7 +286,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
});
}
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {
- emitCustomNotification("drop_bundle_material", {modelNode}); // To MaterialBrowserView
+ emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
}
m_nodeAtPosReqType = NodeAtPosReqType::None;
}
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
index 7d90020d961..813b021b85d 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
@@ -146,7 +146,8 @@ void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
m_importableExtensions3DMap = extMap;
AddResourceOperation import3DModelOperation = [this](const QStringList &fileNames,
- const QString &defaultDir) -> AddFilesResult {
+ const QString &defaultDir,
+ bool showDialog) -> AddFilesResult {
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
m_importableExtensions3DMap,
m_importOptions3DMap, {}, {},
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h
deleted file mode 100644
index 64344915ce1..00000000000
--- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include
-
-#include "nodemetainfo.h"
-
-#include
-#include
-
-QT_BEGIN_NAMESPACE
-QT_END_NAMESPACE
-
-namespace QmlDesigner::Internal {
-
-class BundleImporter : public QObject
-{
- Q_OBJECT
-
-public:
- BundleImporter(const QString &bundleDir,
- const QString &bundleId,
- const QStringList &sharedFiles,
- QObject *parent = nullptr);
- ~BundleImporter() = default;
-
- QString importComponent(const QString &qmlFile,
- const QStringList &files);
- QString unimportComponent(const QString &qmlFile);
- Utils::FilePath resolveBundleImportPath();
-
-signals:
- // The metaInfo parameter will be invalid if an error was encountered during
- // asynchronous part of the import. In this case all remaining pending imports have been
- // terminated, and will not receive separate importFinished notifications.
- void importFinished(const QmlDesigner::NodeMetaInfo &metaInfo);
- void unimportFinished(const QmlDesigner::NodeMetaInfo &metaInfo);
-
-private:
- void handleImportTimer();
- QVariantHash loadAssetRefMap(const Utils::FilePath &bundlePath);
- void writeAssetRefMap(const Utils::FilePath &bundlePath, const QVariantHash &assetRefMap);
-
- Utils::FilePath m_bundleDir;
- QString m_bundleId;
- QString m_moduleName;
- QStringList m_sharedFiles;
- QTimer m_importTimer;
- int m_importTimerCount = 0;
- bool m_importAddPending = false;
- bool m_fullReset = false;
- QHash m_pendingTypes; //
-};
-
-} // namespace QmlDesigner::Internal
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp
deleted file mode 100644
index 6cee76475ac..00000000000
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "bundlematerial.h"
-
-namespace QmlDesigner {
-
-BundleMaterial::BundleMaterial(QObject *parent,
- const QString &name,
- const QString &qml,
- const TypeName &type,
- const QUrl &icon,
- const QStringList &files)
- : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) {}
-
-bool BundleMaterial::filter(const QString &searchText)
-{
- if (m_visible != m_name.contains(searchText, Qt::CaseInsensitive)) {
- m_visible = !m_visible;
- emit materialVisibleChanged();
- }
-
- return m_visible;
-}
-
-QUrl BundleMaterial::icon() const
-{
- return m_icon;
-}
-
-QString BundleMaterial::qml() const
-{
- return m_qml;
-}
-
-TypeName BundleMaterial::type() const
-{
- return m_type;
-}
-
-QStringList BundleMaterial::files() const
-{
- return m_files;
-}
-
-bool BundleMaterial::visible() const
-{
- return m_visible;
-}
-
-bool BundleMaterial::setImported(bool imported)
-{
- if (m_imported != imported) {
- m_imported = imported;
- emit materialImportedChanged();
- return true;
- }
-
- return false;
-}
-
-bool BundleMaterial::imported() const
-{
- return m_imported;
-}
-
-} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h
deleted file mode 100644
index 64d79aa65ee..00000000000
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "qmldesignercorelib_global.h"
-
-#include
-#include
-#include
-
-namespace QmlDesigner {
-
-class BundleMaterial : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QString bundleMaterialName MEMBER m_name CONSTANT)
- Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT)
- Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged)
- Q_PROPERTY(bool bundleMaterialImported READ imported WRITE setImported NOTIFY materialImportedChanged)
-
-public:
- BundleMaterial(QObject *parent,
- const QString &name,
- const QString &qml,
- const TypeName &type,
- const QUrl &icon,
- const QStringList &files);
-
- bool filter(const QString &searchText);
-
- QUrl icon() const;
- QString qml() const;
- TypeName type() const;
- QStringList files() const;
- bool visible() const;
-
- bool setImported(bool imported);
- bool imported() const;
-
-signals:
- void materialVisibleChanged();
- void materialImportedChanged();
-
-private:
- QString m_name;
- QString m_qml;
- TypeName m_type;
- QUrl m_icon;
- QStringList m_files;
-
- bool m_visible = true;
- bool m_imported = false;
-};
-
-} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp
deleted file mode 100644
index 60910abb046..00000000000
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "bundlematerialcategory.h"
-
-#include "bundlematerial.h"
-
-namespace QmlDesigner {
-
-BundleMaterialCategory::BundleMaterialCategory(QObject *parent, const QString &name)
- : QObject(parent), m_name(name) {}
-
-void BundleMaterialCategory::addBundleMaterial(BundleMaterial *bundleMat)
-{
- m_categoryMaterials.append(bundleMat);
-}
-
-bool BundleMaterialCategory::updateImportedState(const QStringList &importedMats)
-{
- bool changed = false;
-
- for (BundleMaterial *mat : std::as_const(m_categoryMaterials))
- changed |= mat->setImported(importedMats.contains(mat->qml().chopped(4)));
-
- return changed;
-}
-
-bool BundleMaterialCategory::filter(const QString &searchText)
-{
- bool visible = false;
- for (BundleMaterial *mat : std::as_const(m_categoryMaterials))
- visible |= mat->filter(searchText);
-
- if (visible != m_visible) {
- m_visible = visible;
- emit categoryVisibleChanged();
- return true;
- }
-
- return false;
-}
-
-QString BundleMaterialCategory::name() const
-{
- return m_name;
-}
-
-bool BundleMaterialCategory::visible() const
-{
- return m_visible;
-}
-
-bool BundleMaterialCategory::expanded() const
-{
- return m_expanded;
-}
-
-QList BundleMaterialCategory::categoryMaterials() const
-{
- return m_categoryMaterials;
-}
-
-} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h
deleted file mode 100644
index 14f7ddf654e..00000000000
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2022 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include
-
-namespace QmlDesigner {
-
-class BundleMaterial;
-
-class BundleMaterialCategory : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QString bundleCategoryName MEMBER m_name CONSTANT)
- Q_PROPERTY(bool bundleCategoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged)
- Q_PROPERTY(bool bundleCategoryExpanded MEMBER m_expanded NOTIFY categoryExpandChanged)
- Q_PROPERTY(QList bundleCategoryMaterials MEMBER m_categoryMaterials
- NOTIFY bundleMaterialsModelChanged)
-
-public:
- BundleMaterialCategory(QObject *parent, const QString &name);
-
- void addBundleMaterial(BundleMaterial *bundleMat);
- bool updateImportedState(const QStringList &importedMats);
- bool filter(const QString &searchText);
-
- QString name() const;
- bool visible() const;
- bool expanded() const;
- QList categoryMaterials() const;
-
-signals:
- void categoryVisibleChanged();
- void categoryExpandChanged();
- void bundleMaterialsModelChanged();
-
-private:
- QString m_name;
- bool m_visible = true;
- bool m_expanded = true;
-
- QList m_categoryMaterials;
-};
-
-} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp
new file mode 100644
index 00000000000..b39bdbb1f94
--- /dev/null
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp
@@ -0,0 +1,219 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "materialbrowsertexturesmodel.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "utils/qtcassert.h"
+
+namespace QmlDesigner {
+
+MaterialBrowserTexturesModel::MaterialBrowserTexturesModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+MaterialBrowserTexturesModel::~MaterialBrowserTexturesModel()
+{
+}
+
+int MaterialBrowserTexturesModel::rowCount(const QModelIndex &) const
+{
+ return m_textureList.count();
+}
+
+QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role) const
+{
+ QTC_ASSERT(index.isValid() && index.row() < m_textureList.count(), return {});
+ QTC_ASSERT(roleNames().contains(role), return {});
+
+ QByteArray roleName = roleNames().value(role);
+ if (roleName == "textureSource") {
+ QString source = m_textureList.at(index.row()).variantProperty("source").value().toString();
+ return QUrl::fromLocalFile(DocumentManager::currentResourcePath().path() + '/' + source);
+ }
+
+ if (roleName == "textureVisible")
+ return isTextureVisible(index.row());
+
+ if (roleName == "hasDynamicProperties")
+ return !m_textureList.at(index.row()).dynamicProperties().isEmpty();
+
+ return {};
+}
+
+bool MaterialBrowserTexturesModel::isTextureVisible(int idx) const
+{
+ if (!isValidIndex(idx))
+ return false;
+
+ return m_searchText.isEmpty() || m_textureList.at(idx).variantProperty("objectName")
+ .value().toString().contains(m_searchText, Qt::CaseInsensitive);
+}
+
+bool MaterialBrowserTexturesModel::isValidIndex(int idx) const
+{
+ return idx > -1 && idx < rowCount();
+}
+
+
+QHash MaterialBrowserTexturesModel::roleNames() const
+{
+ static const QHash roles {
+ {Qt::UserRole + 1, "textureSource"},
+ {Qt::UserRole + 2, "textureVisible"},
+ {Qt::UserRole + 3, "hasDynamicProperties"}
+ };
+ return roles;
+}
+
+QList MaterialBrowserTexturesModel::textures() const
+{
+ return m_textureList;
+}
+
+void MaterialBrowserTexturesModel::setSearchText(const QString &searchText)
+{
+ QString lowerSearchText = searchText.toLower();
+
+ if (m_searchText == lowerSearchText)
+ return;
+
+ m_searchText = lowerSearchText;
+
+ bool isEmpty = false;
+
+ // if selected texture goes invisible, select nearest one
+ if (!isTextureVisible(m_selectedIndex)) {
+ int inc = 1;
+ int incCap = m_textureList.count();
+ while (!isEmpty && inc < incCap) {
+ if (isTextureVisible(m_selectedIndex - inc)) {
+ selectTexture(m_selectedIndex - inc);
+ break;
+ } else if (isTextureVisible(m_selectedIndex + inc)) {
+ selectTexture(m_selectedIndex + inc);
+ break;
+ }
+ ++inc;
+ isEmpty = !isValidIndex(m_selectedIndex + inc)
+ && !isValidIndex(m_selectedIndex - inc);
+ }
+ if (!isTextureVisible(m_selectedIndex)) // handles the case of a single item
+ isEmpty = true;
+ }
+
+ if (isEmpty != m_isEmpty) {
+ m_isEmpty = isEmpty;
+ emit isEmptyChanged();
+ }
+
+ resetModel();
+}
+
+void MaterialBrowserTexturesModel::setTextures(const QList &textures)
+{
+ m_textureList = textures;
+ m_textureIndexHash.clear();
+ for (int i = 0; i < textures.size(); ++i)
+ m_textureIndexHash.insert(textures.at(i).internalId(), i);
+
+ bool isEmpty = textures.size() == 0;
+ if (isEmpty != m_isEmpty) {
+ m_isEmpty = isEmpty;
+ emit isEmptyChanged();
+ }
+
+ updateSelectedTexture();
+ resetModel();
+}
+
+void MaterialBrowserTexturesModel::removeTexture(const ModelNode &texture)
+{
+ if (!m_textureIndexHash.contains(texture.internalId()))
+ return;
+
+ m_textureList.removeOne(texture);
+ int idx = m_textureIndexHash.value(texture.internalId());
+ m_textureIndexHash.remove(texture.internalId());
+
+ // update index hash
+ for (int i = idx; i < rowCount(); ++i)
+ m_textureIndexHash.insert(m_textureList.at(i).internalId(), i);
+
+ resetModel();
+
+ if (m_textureList.isEmpty()) {
+ m_isEmpty = true;
+ emit isEmptyChanged();
+ }
+}
+
+void MaterialBrowserTexturesModel::deleteSelectedTexture()
+{
+ deleteTexture(m_selectedIndex);
+}
+
+void MaterialBrowserTexturesModel::updateSelectedTexture()
+{
+ selectTexture(m_selectedIndex, true);
+}
+
+int MaterialBrowserTexturesModel::textureIndex(const ModelNode &texture) const
+{
+ if (m_textureIndexHash.contains(texture.internalId()))
+ return m_textureIndexHash.value(texture.internalId());
+
+ return -1;
+}
+
+ModelNode MaterialBrowserTexturesModel::textureAt(int idx) const
+{
+ if (isValidIndex(idx))
+ return m_textureList.at(idx);
+
+ return {};
+}
+
+void MaterialBrowserTexturesModel::resetModel()
+{
+ beginResetModel();
+ endResetModel();
+}
+
+void MaterialBrowserTexturesModel::selectTexture(int idx, bool force)
+{
+ if (m_textureList.size() == 0) {
+ m_selectedIndex = -1;
+ emit selectedIndexChanged(m_selectedIndex);
+ return;
+ }
+
+ idx = std::max(0, std::min(idx, rowCount() - 1));
+
+ if (idx != m_selectedIndex || force) {
+ m_selectedIndex = idx;
+ emit selectedIndexChanged(idx);
+ }
+}
+
+void MaterialBrowserTexturesModel::duplicateTexture(int idx)
+{
+ emit duplicateTextureTriggered(m_textureList.at(idx));
+}
+
+void MaterialBrowserTexturesModel::deleteTexture(int idx)
+{
+ if (isValidIndex(idx)) {
+ ModelNode node = m_textureList[idx];
+ if (node.isValid())
+ QmlObjectNode(node).destroy();
+ }
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h
new file mode 100644
index 00000000000..4b5d1bd55bf
--- /dev/null
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+#include
+#include
+
+namespace QmlDesigner {
+
+class MaterialBrowserTexturesModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
+ Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
+
+public:
+ MaterialBrowserTexturesModel(QObject *parent = nullptr);
+ ~MaterialBrowserTexturesModel() override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QHash roleNames() const override;
+
+ void setSearchText(const QString &searchText);
+
+ QList textures() const;
+ void setTextures(const QList &textures);
+ void removeTexture(const ModelNode &texture);
+ void deleteSelectedTexture();
+ void updateSelectedTexture();
+ int textureIndex(const ModelNode &material) const;
+ ModelNode textureAt(int idx) const;
+
+ void resetModel();
+
+ Q_INVOKABLE void selectTexture(int idx, bool force = false);
+ Q_INVOKABLE void duplicateTexture(int idx);
+ Q_INVOKABLE void deleteTexture(int idx);
+
+signals:
+ void isEmptyChanged();
+ void materialSectionsChanged();
+ void selectedIndexChanged(int idx);
+ void duplicateTextureTriggered(const QmlDesigner::ModelNode &material);
+
+private:
+ bool isTextureVisible(int idx) const;
+ bool isValidIndex(int idx) const;
+
+ QString m_searchText;
+ QList m_textureList;
+ ModelNode m_copiedMaterial;
+ QHash m_textureIndexHash; // internalId -> index
+
+ int m_selectedIndex = 0;
+ bool m_isEmpty = true;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
index 2a7b6833b3e..86d6c69b59f 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
@@ -4,11 +4,9 @@
#include "materialbrowserview.h"
#include "bindingproperty.h"
-#include "bundlematerial.h"
-#include "bundleimporter.h"
-#include "materialbrowsermodel.h"
#include "materialbrowserwidget.h"
-#include "materialbrowserbundlemodel.h"
+#include "materialbrowsermodel.h"
+#include "materialbrowsertexturesmodel.h"
#include "nodeabstractproperty.h"
#include "nodemetainfo.h"
#include "qmlobjectnode.h"
@@ -22,14 +20,6 @@
#include
#include
-#ifndef QMLDESIGNER_TEST
-#include
-#include
-#include
-#include
-#include
-#endif
-
#include
#include
#include
@@ -149,48 +139,6 @@ WidgetInfo MaterialBrowserView::widgetInfo()
}
});
});
-
- connect(m_widget, &MaterialBrowserWidget::bundleMaterialDragStarted, this,
- [&] (QmlDesigner::BundleMaterial *bundleMat) {
- m_draggedBundleMaterial = bundleMat;
- });
-
- MaterialBrowserBundleModel *matBrowserBundleModel = m_widget->materialBrowserBundleModel().data();
-
- connect(matBrowserBundleModel, &MaterialBrowserBundleModel::applyToSelectedTriggered, this,
- [&] (BundleMaterial *bundleMat, bool add) {
- if (m_selectedModels.isEmpty())
- return;
-
- m_bundleMaterialTargets = m_selectedModels;
- m_bundleMaterialAddToSelected = add;
-
- ModelNode defaultMat = getBundleMaterialDefaultInstance(bundleMat->type());
- if (defaultMat.isValid())
- applyBundleMaterialToDropTarget(defaultMat);
- else
- m_widget->materialBrowserBundleModel()->addToProject(bundleMat);
- });
-
- connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialImported, this,
- [&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
- applyBundleMaterialToDropTarget({}, metaInfo);
- updateBundleMaterialsImportedState();
- });
-
- connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialAboutToUnimport, this,
- [&] (const QmlDesigner::TypeName &type) {
- // delete instances of the bundle material that is about to be unimported
- executeInTransaction("MaterialBrowserView::widgetInfo", [&] {
- Utils::reverseForeach(m_widget->materialBrowserModel()->materials(), [&](const ModelNode &mat) {
- if (mat.isValid() && mat.type() == type)
- QmlObjectNode(mat).destroy();
- });
- });
- });
-
- connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialUnimported, this,
- &MaterialBrowserView::updateBundleMaterialsImportedState);
}
return createWidgetInfo(m_widget.data(),
@@ -200,77 +148,6 @@ WidgetInfo MaterialBrowserView::widgetInfo()
tr("Material Browser"));
}
-void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundleMat,
- const NodeMetaInfo &metaInfo)
-{
- if (!bundleMat.isValid() && !metaInfo.isValid())
- return;
-
- ModelNode matLib = materialLibraryNode();
- if (!matLib.isValid())
- return;
-
- executeInTransaction("MaterialBrowserView::applyBundleMaterialToDropTarget", [&] {
- ModelNode newMatNode;
- if (metaInfo.isValid()) {
- newMatNode = createModelNode(metaInfo.typeName(), metaInfo.majorVersion(),
- metaInfo.minorVersion());
- matLib.defaultNodeListProperty().reparentHere(newMatNode);
-
- static QRegularExpression rgx("([A-Z])([a-z]*)");
- QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed();
- if (newName.endsWith(" Material"))
- newName.chop(9); // remove trailing " Material"
- QString newId = model()->generateIdFromName(newName, "material");
- newMatNode.setIdWithRefactoring(newId);
-
- VariantProperty objNameProp = newMatNode.variantProperty("objectName");
- objNameProp.setValue(newName);
- } else {
- newMatNode = bundleMat;
- }
-
- // TODO: unify this logic as it exist elsewhere also
- auto expToList = [](const QString &exp) {
- QString copy = exp;
- copy = copy.remove("[").remove("]");
-
- QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
- for (QString &str : tmp)
- str = str.trimmed();
-
- return tmp;
- };
-
- auto listToExp = [](QStringList &stringList) {
- if (stringList.size() > 1)
- return QString("[" + stringList.join(",") + "]");
-
- if (stringList.size() == 1)
- return stringList.first();
-
- return QString();
- };
-
- for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) {
- if (target.isValid() && target.metaInfo().isQtQuick3DModel()) {
- QmlObjectNode qmlObjNode(target);
- if (m_bundleMaterialAddToSelected) {
- QStringList matList = expToList(qmlObjNode.expression("materials"));
- matList.append(newMatNode.id());
- QString updatedExp = listToExp(matList);
- qmlObjNode.setBindingProperty("materials", updatedExp);
- } else {
- qmlObjNode.setBindingProperty("materials", newMatNode.id());
- }
- }
-
- m_bundleMaterialTargets = {};
- m_bundleMaterialAddToSelected = false;
- }
- });
-}
-
void MaterialBrowserView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
@@ -280,9 +157,6 @@ void MaterialBrowserView::modelAttached(Model *model)
rootModelNode().metaInfo().isQtQuick3DMaterial());
m_hasQuick3DImport = model->hasImport("QtQuick3D");
- updateBundleMaterialsQuick3DVersion();
- updateBundleMaterialsImportedState();
-
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
// before refreshing the model
QTimer::singleShot(1000, model, [this]() {
@@ -297,18 +171,22 @@ void MaterialBrowserView::refreshModel(bool updateImages)
return;
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
- QList materials;
+ QList materials;
+ QList textures;
if (m_hasQuick3DImport && matLib.isValid()) {
const QList matLibNodes = matLib.directSubModelNodes();
for (const ModelNode &node : matLibNodes) {
if (isMaterial(node))
materials.append(node);
+ else if (isTexture(node))
+ textures.append(node);
}
}
m_widget->clearSearchFilter();
m_widget->materialBrowserModel()->setMaterials(materials, m_hasQuick3DImport);
+ m_widget->materialBrowserTexturesModel()->setTextures(textures);
if (updateImages) {
for (const ModelNode &node : std::as_const(materials))
@@ -323,6 +201,14 @@ bool MaterialBrowserView::isMaterial(const ModelNode &node) const
return node.metaInfo().isQtQuick3DMaterial();
}
+bool MaterialBrowserView::isTexture(const ModelNode &node) const
+{
+ if (!node.isValid())
+ return false;
+
+ return node.metaInfo().isQtQuick3DTexture();
+}
+
void MaterialBrowserView::modelAboutToBeDetached(Model *model)
{
m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport);
@@ -388,7 +274,9 @@ void MaterialBrowserView::nodeReparented(const ModelNode &node,
const NodeAbstractProperty &oldPropertyParent,
[[maybe_unused]] PropertyChangeFlags propertyChange)
{
- if (!isMaterial(node))
+ Q_UNUSED(propertyChange)
+
+ if (!isMaterial(node) && !isTexture(node))
return;
ModelNode newParentNode = newPropertyParent.parentModelNode();
@@ -445,82 +333,6 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
}
-void MaterialBrowserView::updateBundleMaterialsImportedState()
-{
- using namespace Utils;
-
- if (!m_widget->materialBrowserBundleModel()->bundleImporter())
- return;
-
- QStringList importedBundleMats;
-
- FilePath materialBundlePath = m_widget->materialBrowserBundleModel()->bundleImporter()->resolveBundleImportPath();
-
- if (materialBundlePath.exists()) {
- importedBundleMats = transform(materialBundlePath.dirEntries({{"*.qml"}, QDir::Files}),
- [](const FilePath &f) { return f.fileName().chopped(4); });
- }
-
- m_widget->materialBrowserBundleModel()->updateImportedState(importedBundleMats);
-}
-
-void MaterialBrowserView::updateBundleMaterialsQuick3DVersion()
-{
- bool hasImport = false;
- int major = -1;
- int minor = -1;
- const QString url {"QtQuick3D"};
- const auto imports = model()->imports();
- for (const auto &import : imports) {
- if (import.url() == url) {
- hasImport = true;
- const int importMajor = import.majorVersion();
- if (major < importMajor) {
- minor = -1;
- major = importMajor;
- }
- if (major == importMajor)
- minor = qMax(minor, import.minorVersion());
- }
- }
-#ifndef QMLDESIGNER_TEST
- if (hasImport && major == -1) {
- // Import without specifying version, so we take the kit version
- auto target = ProjectExplorer::SessionManager::startupTarget();
- if (target) {
- QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
- if (qtVersion) {
- major = qtVersion->qtVersion().majorVersion();
- minor = qtVersion->qtVersion().minorVersion();
- }
- }
- }
-#endif
- m_widget->materialBrowserBundleModel()->setQuick3DImportVersion(major, minor);
-}
-
-ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type)
-{
- const QList materials = m_widget->materialBrowserModel()->materials();
- for (const ModelNode &mat : materials) {
- if (mat.type() == type) {
- bool isDefault = true;
- const QList props = mat.properties();
- for (const AbstractProperty &prop : props) {
- if (prop.name() != "objectName") {
- isDefault = false;
- break;
- }
- }
-
- if (isDefault)
- return mat;
- }
- }
-
- return {};
-}
-
void MaterialBrowserView::requestPreviews()
{
if (model() && model()->nodeInstanceView()) {
@@ -535,8 +347,6 @@ void MaterialBrowserView::importsChanged([[maybe_unused]] const QList &a
{
bool hasQuick3DImport = model()->hasImport("QtQuick3D");
- updateBundleMaterialsQuick3DVersion();
-
if (hasQuick3DImport == m_hasQuick3DImport)
return;
@@ -566,16 +376,6 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
});
} else if (identifier == "delete_selected_material") {
m_widget->materialBrowserModel()->deleteSelectedMaterial();
- } else if (identifier == "drop_bundle_material") {
- m_bundleMaterialTargets = nodeList;
-
- ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
- if (defaultMat.isValid())
- applyBundleMaterialToDropTarget(defaultMat);
- else
- m_widget->materialBrowserBundleModel()->addToProject(m_draggedBundleMaterial);
-
- m_draggedBundleMaterial = nullptr;
}
}
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
index a8bcf5f2f1f..f59cb2dbbcd 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
@@ -4,7 +4,6 @@
#pragma once
#include "abstractview.h"
-#include "nodemetainfo.h"
#include
#include
@@ -12,7 +11,6 @@
namespace QmlDesigner {
-class BundleMaterial;
class MaterialBrowserWidget;
class MaterialBrowserView : public AbstractView
@@ -48,19 +46,13 @@ public:
private:
void refreshModel(bool updateImages);
bool isMaterial(const ModelNode &node) const;
+ bool isTexture(const ModelNode &node) const;
void loadPropertyGroups();
- void updateBundleMaterialsImportedState();
- void updateBundleMaterialsQuick3DVersion();
- void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
- ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
void requestPreviews();
QPointer m_widget;
- QList m_bundleMaterialTargets;
QList m_selectedModels; // selected 3D model nodes
- BundleMaterial *m_draggedBundleMaterial = nullptr;
- bool m_bundleMaterialAddToSelected = false;
bool m_hasQuick3DImport = false;
bool m_autoSelectModelMaterial = false; // TODO: wire this to some action
bool m_puppetResetPending = false;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
index 4a513d380f3..f51dd57b804 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
@@ -3,9 +3,8 @@
#include "materialbrowserwidget.h"
-#include "bundlematerial.h"
-#include "materialbrowserbundlemodel.h"
#include "materialbrowsermodel.h"
+#include "materialbrowsertexturesmodel.h"
#include "materialbrowserview.h"
#include
@@ -30,10 +29,10 @@
#include
#include
#include
+#include
#include
#include
#include
-#include
#include
#include
#include
@@ -108,34 +107,9 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
QString::number(m_materialToDrag.internalId()), nullptr, {128, 128}));
m_materialToDrag = {};
}
- } else if (m_bundleMaterialToDrag != nullptr) {
- QMouseEvent *me = static_cast(event);
- if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
- QByteArray data;
- QMimeData *mimeData = new QMimeData;
- QDataStream stream(&data, QIODevice::WriteOnly);
- stream << m_bundleMaterialToDrag->type();
- mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data);
- mimeData->removeFormat("text/plain");
-
- if (!m_draggedBundleMaterial) {
- m_draggedBundleMaterial = m_bundleMaterialToDrag;
- emit draggedBundleMaterialChanged();
- }
-
- emit bundleMaterialDragStarted(m_bundleMaterialToDrag);
- model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile());
- m_bundleMaterialToDrag = nullptr;
- }
}
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
m_materialToDrag = {};
- m_bundleMaterialToDrag = nullptr;
-
- if (m_draggedBundleMaterial) {
- m_draggedBundleMaterial = nullptr;
- emit draggedBundleMaterialChanged();
- }
}
return QObject::eventFilter(obj, event);
@@ -144,7 +118,7 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
MaterialBrowserWidget::MaterialBrowserWidget(MaterialBrowserView *view)
: m_materialBrowserView(view)
, m_materialBrowserModel(new MaterialBrowserModel(this))
- , m_materialBrowserBundleModel(new MaterialBrowserBundleModel(this))
+ , m_materialBrowserTexturesModel(new MaterialBrowserTexturesModel(this))
, m_quickWidget(new QQuickWidget(this))
, m_previewImageProvider(new PreviewImageProvider())
{
@@ -163,7 +137,7 @@ MaterialBrowserWidget::MaterialBrowserWidget(MaterialBrowserView *view)
m_quickWidget->rootContext()->setContextProperties({
{"rootView", QVariant::fromValue(this)},
{"materialBrowserModel", QVariant::fromValue(m_materialBrowserModel.data())},
- {"materialBrowserBundleModel", QVariant::fromValue(m_materialBrowserBundleModel.data())},
+ {"materialBrowserTexturesModel", QVariant::fromValue(m_materialBrowserTexturesModel.data())},
});
m_quickWidget->engine()->addImageProvider("materialBrowser", m_previewImageProvider);
@@ -223,10 +197,9 @@ void MaterialBrowserWidget::startDragMaterial(int index, const QPointF &mousePos
m_dragStartPoint = mousePos.toPoint();
}
-void MaterialBrowserWidget::startDragBundleMaterial(QmlDesigner::BundleMaterial *bundleMat, const QPointF &mousePos)
+void MaterialBrowserWidget::acceptBundleMaterialDrop()
{
- m_bundleMaterialToDrag = bundleMat;
- m_dragStartPoint = mousePos.toPoint();
+ m_materialBrowserView->emitCustomNotification("drop_bundle_material", {}, {}); // To ContentLibraryView
}
QString MaterialBrowserWidget::qmlSourcesPath()
@@ -256,7 +229,6 @@ void MaterialBrowserWidget::reloadQmlSource()
void MaterialBrowserWidget::updateSearch()
{
m_materialBrowserModel->setSearchText(m_filterText);
- m_materialBrowserBundleModel->setSearchText(m_filterText);
m_quickWidget->update();
}
@@ -270,10 +242,9 @@ QPointer MaterialBrowserWidget::materialBrowserModel() con
return m_materialBrowserModel;
}
-QPointer MaterialBrowserWidget::materialBrowserBundleModel() const
+QPointer MaterialBrowserWidget::materialBrowserTexturesModel() const
{
- return m_materialBrowserBundleModel;
+ return m_materialBrowserTexturesModel;
}
-
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
index 42739d83c42..af5909b546b 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
@@ -11,32 +11,27 @@
#include
#include
-#include
-#include
#include
-#include
-#include
-#include
#include
QT_BEGIN_NAMESPACE
-class QStackedWidget;
+class QQuickWidget;
+class QPointF;
class QShortcut;
+class QToolButton;
QT_END_NAMESPACE
namespace QmlDesigner {
-class BundleMaterial;
class MaterialBrowserView;
class MaterialBrowserModel;
-class MaterialBrowserBundleModel;
+class MaterialBrowserTexturesModel;
class PreviewImageProvider;
class MaterialBrowserWidget : public QFrame
{
Q_OBJECT
- Q_PROPERTY(BundleMaterial *draggedBundleMaterial MEMBER m_draggedBundleMaterial NOTIFY draggedBundleMaterialChanged)
public:
MaterialBrowserWidget(MaterialBrowserView *view);
@@ -49,19 +44,15 @@ public:
void clearSearchFilter();
QPointer materialBrowserModel() const;
- QPointer materialBrowserBundleModel() const;
+ QPointer materialBrowserTexturesModel() const;
void updateMaterialPreview(const ModelNode &node, const QPixmap &pixmap);
Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
Q_INVOKABLE void startDragMaterial(int index, const QPointF &mousePos);
- Q_INVOKABLE void startDragBundleMaterial(QmlDesigner::BundleMaterial *bundleMat, const QPointF &mousePos);
+ Q_INVOKABLE void acceptBundleMaterialDrop();
QQuickWidget *quickWidget() const;
-signals:
- void bundleMaterialDragStarted(QmlDesigner::BundleMaterial *bundleMat);
- void draggedBundleMaterialChanged();
-
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
@@ -71,7 +62,7 @@ private:
QPointer m_materialBrowserView;
QPointer m_materialBrowserModel;
- QPointer m_materialBrowserBundleModel;
+ QPointer m_materialBrowserTexturesModel;
QScopedPointer m_quickWidget;
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
@@ -81,8 +72,6 @@ private:
QString m_filterText;
ModelNode m_materialToDrag;
- BundleMaterial *m_bundleMaterialToDrag = nullptr;
- BundleMaterial *m_draggedBundleMaterial = nullptr;
QPoint m_dragStartPoint;
};
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
index 12d496b2522..a407cf129b3 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
@@ -544,7 +544,7 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
if (targetNode.isValid())
- m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To MaterialBrowserView
+ m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To ContentLibraryView
} else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) {
const QStringList assetsPaths = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',');
NodeAbstractProperty targetProperty;
diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h
index 9b5dac8aa9f..6a3a4e0de48 100644
--- a/src/plugins/qmldesigner/qmldesignerconstants.h
+++ b/src/plugins/qmldesigner/qmldesignerconstants.h
@@ -76,6 +76,7 @@ const char MIME_TYPE_ITEM_LIBRARY_INFO[] = "application/vnd.qtdesignstudio.iteml
const char MIME_TYPE_ASSETS[] = "application/vnd.qtdesignstudio.assets";
const char MIME_TYPE_MATERIAL[] = "application/vnd.qtdesignstudio.material";
const char MIME_TYPE_BUNDLE_MATERIAL[] = "application/vnd.qtdesignstudio.bundlematerial";
+const char MIME_TYPE_BUNDLE_TEXTURE[] = "application/vnd.qtdesignstudio.bundletexture";
const char MIME_TYPE_ASSET_IMAGE[] = "application/vnd.qtdesignstudio.asset.image";
const char MIME_TYPE_ASSET_FONT[] = "application/vnd.qtdesignstudio.asset.font";
const char MIME_TYPE_ASSET_SHADER[] = "application/vnd.qtdesignstudio.asset.shader";