clide/qml/ClideTreeView.qml

147 lines
4.7 KiB
QML
Raw Normal View History

2025-03-30 16:14:58 -04:00
import QtQuick
import QtQuick.Controls
2025-03-30 21:38:57 -04:00
import QtQuick.Layouts
2025-03-30 16:14:58 -04:00
import clide.module 1.0
Rectangle {
id: root
2025-03-30 21:38:57 -04:00
2025-03-30 16:14:58 -04:00
signal fileClicked(string filePath)
2025-03-30 21:38:57 -04:00
color: RustColors.explorer_background
2025-03-30 16:14:58 -04:00
TreeView {
id: fileSystemTreeView
// rootIndex: FileSystem.rootIndex
property int lastIndex: -1
2025-03-30 21:38:57 -04:00
model: FileSystem
2025-03-30 16:14:58 -04:00
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds
clip: true
2025-03-30 21:38:57 -04:00
Component.onCompleted: {
FileSystem.setDirectory(FileSystem.filePath)
fileSystemTreeView.expandRecursively(0, 4)
}
2025-03-30 16:14:58 -04:00
// The delegate represents a single entry in the filesystem.
delegate: TreeViewDelegate {
id: treeDelegate
indentation: 8
implicitWidth: fileSystemTreeView.width > 0 ? fileSystemTreeView.width : 250
implicitHeight: 25
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
2025-03-30 21:38:57 -04:00
source: {
// If the item has children, it's a directory.
if (treeDelegate.hasChildren) {
return treeDelegate.expanded ?
"../icons/folder-open-solid.svg" : "../icons/folder-solid.svg";
}
return "../icons/file-solid.svg"
}
sourceSize.width: 15
sourceSize.height: 15
2025-03-30 16:14:58 -04:00
fillMode: Image.PreserveAspectFit
smooth: true
antialiasing: true
asynchronous: true
}
contentItem: Text {
text: treeDelegate.fileName
2025-03-30 21:38:57 -04:00
color: RustColors.explorer_text
2025-03-30 16:14:58 -04:00
}
background: Rectangle {
2025-03-30 21:38:57 -04:00
// TODO: Fix flickering from color transition on states here.
2025-03-30 16:14:58 -04:00
color: (treeDelegate.index === fileSystemTreeView.lastIndex)
2025-03-30 21:38:57 -04:00
? RustColors.explorer_text_selected
: (hoverHandler.hovered ? RustColors.explorer_hovered : "transparent")
radius: 2.5
opacity: hoverHandler.hovered ? 0.75 : 1.0
Behavior on color {
ColorAnimation {
duration: 300
}
}
2025-03-30 16:14:58 -04:00
}
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;
}
}
}
Menu {
id: contextMenu
Action {
text: qsTr("Set as root index")
onTriggered: {
2025-03-30 21:38:57 -04:00
console.log("Setting directory: " + treeDelegate.filePath)
FileSystem.setDirectory(treeDelegate.filePath)
2025-03-30 16:14:58 -04:00
}
}
Action {
text: qsTr("Reset root index")
2025-03-30 21:38:57 -04:00
onTriggered: {
FileSystem.setDirectory("")
}
2025-03-30 16:14:58 -04:00
}
}
}
// Provide our own custom ScrollIndicator for the TreeView.
ScrollIndicator.vertical: ScrollIndicator {
active: true
implicitWidth: 15
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 6
color: RustColors.scrollbar
opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0
Behavior on opacity {
OpacityAnimator {
duration: 500
}
}
}
}
}
}