qtdeclarative/examples/quickcontrols/filesystemexplorer/qml/FileSystemView.qml

157 lines
5.4 KiB
QML

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Effects
import QtQuick.Controls.Basic
import FileSystemModule
pragma ComponentBehavior: Bound
// This is the file system view which gets populated by the C++ model.
Rectangle {
id: root
signal fileClicked(string filePath)
property alias rootIndex: fileSystemTreeView.rootIndex
TreeView {
id: fileSystemTreeView
property int lastIndex: -1
anchors.fill: parent
model: FileSystemModel
rootIndex: FileSystemModel.rootIndex
boundsBehavior: Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds
clip: true
Component.onCompleted: fileSystemTreeView.toggleExpanded(0)
// The delegate represents a single entry in the filesystem.
delegate: TreeViewDelegate {
id: treeDelegate
indentation: 8
implicitWidth: fileSystemTreeView.width > 0 ? fileSystemTreeView.width : 250
implicitHeight: 25
// Since we have the 'ComponentBehavior Bound' pragma, we need to
// require these properties from our model. This is a convenient way
// to bind the properties provided by the model's role names.
required property int index
required property url filePath
required property string fileName
indicator: Image {
id: directoryIcon
x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation)
anchors.verticalCenter: parent.verticalCenter
source: treeDelegate.hasChildren ? (treeDelegate.expanded
? "../icons/folder_open.svg" : "../icons/folder_closed.svg")
: "../icons/generic_file.svg"
sourceSize.width: 20
sourceSize.height: 20
fillMode: Image.PreserveAspectFit
smooth: true
antialiasing: true
asynchronous: true
}
contentItem: Text {
text: treeDelegate.fileName
color: Colors.text
}
background: Rectangle {
color: (treeDelegate.index === fileSystemTreeView.lastIndex)
? Colors.selection
: (hoverHandler.hovered ? Colors.active : "transparent")
}
// We color the directory icons with this MultiEffect, where we overlay
// the colorization color ontop of the SVG icons.
MultiEffect {
id: iconOverlay
anchors.fill: directoryIcon
source: directoryIcon
colorization: 1.0
brightness: 1.0
colorizationColor: {
const isFile = treeDelegate.index === fileSystemTreeView.lastIndex
&& !treeDelegate.hasChildren;
if (isFile)
return Qt.lighter(Colors.folder, 3)
const isExpandedFolder = treeDelegate.expanded && treeDelegate.hasChildren;
if (isExpandedFolder)
return Colors.color2
else
return Colors.folder
}
}
HoverHandler {
id: hoverHandler
}
TapHandler {
acceptedButtons: Qt.LeftButton | Qt.RightButton
onSingleTapped: (eventPoint, button) => {
switch (button) {
case Qt.LeftButton:
fileSystemTreeView.toggleExpanded(treeDelegate.row)
fileSystemTreeView.lastIndex = treeDelegate.index
// If this model item doesn't have children, it means it's
// representing a file.
if (!treeDelegate.hasChildren)
root.fileClicked(treeDelegate.filePath)
break;
case Qt.RightButton:
if (treeDelegate.hasChildren)
contextMenu.popup();
break;
}
}
}
MyMenu {
id: contextMenu
Action {
text: qsTr("Set as root index")
onTriggered: {
fileSystemTreeView.rootIndex = fileSystemTreeView.index(treeDelegate.row, 0)
}
}
Action {
text: qsTr("Reset root index")
onTriggered: fileSystemTreeView.rootIndex = undefined
}
}
}
// Provide our own custom ScrollIndicator for the TreeView.
ScrollIndicator.vertical: ScrollIndicator {
active: true
implicitWidth: 15
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 6
color: Colors.color1
opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0
Behavior on opacity {
OpacityAnimator {
duration: 500
}
}
}
}
}
}