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:58:38 -04:00
|
|
|
color: RustColors.explorer_background
|
2025-03-30 21:38:57 -04:00
|
|
|
|
2025-03-30 16:14:58 -04:00
|
|
|
signal fileClicked(string filePath)
|
|
|
|
|
|
|
|
|
|
TreeView {
|
|
|
|
|
id: fileSystemTreeView
|
2025-03-30 21:58:38 -04:00
|
|
|
anchors.margins: 15
|
2025-03-30 16:14:58 -04:00
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|