Files
qt-creator/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml
Tim Jenßen feabda3aa7 Merge remote-tracking branch 'origin/10.0' into qds/dev
bigger conflicts resolved at:
  src/plugins/qmldesigner/CMakeLists.txt
  src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp

Change-Id: I08e2a109d8e37cbd77225129854e9e633725bfc7
2023-03-26 16:26:18 +02:00

270 lines
9.0 KiB
QML

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import HelperWidgets as HelperWidgets
import StudioControls as StudioControls
import StudioTheme as StudioTheme
import AssetsLibraryBackend
Item {
id: root
property var assetsModel: AssetsLibraryBackend.assetsModel
property var rootView: AssetsLibraryBackend.rootView
// Array of supported externally dropped files that are imported as-is
property var dropSimpleExtFiles: []
// Array of supported externally dropped files that trigger custom import process
property var dropComplexExtFiles: []
readonly property int qtVersion: rootView.qtVersion()
property bool __searchBoxEmpty: true
AssetsContextMenu {
id: contextMenu
assetsView: assetsView
}
function clearSearchFilter() {
searchBox.clear()
}
function updateDropExtFiles(drag) {
root.dropSimpleExtFiles = []
root.dropComplexExtFiles = []
var simpleSuffixes = rootView.supportedAssetSuffixes(false)
var complexSuffixes = rootView.supportedAssetSuffixes(true)
for (const u of drag.urls) {
var url = u.toString()
if (assetsModel.urlPathExistsInModel(url))
continue;
var ext = '*.' + url.slice(url.lastIndexOf('.') + 1).toLowerCase()
if (simpleSuffixes.includes(ext))
root.dropSimpleExtFiles.push(url)
else if (complexSuffixes.includes(ext))
root.dropComplexExtFiles.push(url)
}
drag.accepted = root.dropSimpleExtFiles.length > 0 || root.dropComplexExtFiles.length > 0
}
DropArea { // handles external drop on empty area of the view (goes to root folder)
id: dropArea
y: assetsView.y + assetsView.contentHeight - assetsView.rowSpacing
width: parent.width
height: parent.height - y
onEntered: (drag) => {
root.updateDropExtFiles(drag)
}
onDropped: (drag) => {
drag.accept()
rootView.handleExtFilesDrop(root.dropSimpleExtFiles,
root.dropComplexExtFiles,
assetsModel.rootPath())
}
Canvas { // marker for the drop area
id: dropCanvas
y: 5
width: parent.width
height: parent.height - y
visible: dropArea.containsDrag && root.dropSimpleExtFiles.length > 0
onWidthChanged: dropCanvas.requestPaint()
onHeightChanged: dropCanvas.requestPaint()
onPaint: {
var ctx = getContext("2d")
ctx.reset()
ctx.strokeStyle = StudioTheme.Values.themeInteraction
ctx.lineWidth = 2
ctx.setLineDash([4, 4])
ctx.rect(5, 5, dropCanvas.width - 10, dropCanvas.height - 10)
ctx.stroke()
}
}
}
MouseArea { // right clicking the empty area of the view
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (assetsModel.haveFiles) {
function onFolderCreated(path) {
assetsView.addCreatedFolder(path)
}
var rootIndex = assetsModel.rootIndex()
var dirPath = assetsModel.filePath(rootIndex)
var dirName = assetsModel.fileName(rootIndex)
contextMenu.openContextMenuForRoot(rootIndex, dirPath, dirName, onFolderCreated)
}
}
}
// called from C++ to close context menu on focus out
function handleViewFocusOut() {
contextMenu.close()
assetsView.selectedAssets = {}
assetsView.selectedAssetsChanged()
}
Timer {
id: updateSearchFilterTimer
interval: 200
repeat: false
onTriggered: {
assetsView.resetVerticalScrollPosition()
rootView.handleSearchFilterChanged(searchBox.text)
assetsView.expandAll()
if (root.__searchBoxEmpty && searchBox.text)
root.__searchBoxEmpty = false
else if (!root.__searchBoxEmpty && !searchBox.text)
root.__searchBoxEmpty = true
}
}
Column {
id: column
anchors.fill: parent
spacing: 5
Rectangle {
id: toolbar
width: parent.width
height: StudioTheme.Values.doubleToolbarHeight
color: StudioTheme.Values.themeToolbarBackground
Column {
id: toolbarColumn
anchors.fill: parent
anchors.topMargin: 6
anchors.bottomMargin: 6
anchors.leftMargin: 10
anchors.rightMargin: 10
spacing: 12
StudioControls.SearchBox {
id: searchBox
width: parent.width
style: StudioTheme.Values.searchControlStyle
onSearchChanged: (searchText) => {
updateSearchFilterTimer.restart()
}
}
Row {
id: buttonRow
width: parent.width
height: StudioTheme.Values.toolbarHeight
spacing: 6
HelperWidgets.AbstractButton {
id: addModuleButton
style: StudioTheme.Values.viewBarButtonStyle
buttonIcon: StudioTheme.Constants.add_medium
tooltip: qsTr("Add a new asset to the project.")
onClicked: rootView.handleAddAsset()
}
}
}
}
Text {
text: qsTr("No match found.")
leftPadding: 10
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.baseFont
visible: !assetsModel.haveFiles && !root.__searchBoxEmpty
}
Item { // placeholder when the assets library is empty
width: parent.width
height: parent.height - toolbar.height - column.spacing
visible: !assetsModel.haveFiles && root.__searchBoxEmpty
clip: true
MouseArea { // right clicking the empty area of the view
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
contextMenu.openContextMenuForEmpty(assetsModel.rootPath())
}
}
DropArea { // handles external drop (goes into default folder based on suffix)
anchors.fill: parent
onEntered: (drag) => {
root.updateDropExtFiles(drag)
}
onDropped: (drag) => {
drag.accept()
rootView.emitExtFilesDrop(root.dropSimpleExtFiles, root.dropComplexExtFiles)
}
Column {
id: noAssetsColumn
spacing: 20
width: root.width - 40
anchors.centerIn: parent
Text {
text: qsTr("Looks like you don't have any assets yet.")
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.bigFont
width: noAssetsColumn.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
Image {
source: "image://qmldesigner_assets/browse"
anchors.horizontalCenter: parent.horizontalCenter
scale: maBrowse.containsMouse ? 1.2 : 1
Behavior on scale {
NumberAnimation {
duration: 300
easing.type: Easing.OutQuad
}
}
MouseArea {
id: maBrowse
anchors.fill: parent
hoverEnabled: true
onClicked: rootView.handleAddAsset();
}
}
Text {
text: qsTr("Drag-and-drop your assets here or click the '+' button to browse assets from the file system.")
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.bigFont
width: noAssetsColumn.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
}
}
}
AssetsView {
id: assetsView
assetsRoot: root
contextMenu: contextMenu
width: parent.width
height: parent.height - assetsView.y
}
}
}