Add ClideTreeView.

This commit is contained in:
2025-03-30 16:14:58 -04:00
parent 1546eb1028
commit b62dce631f
11 changed files with 433 additions and 12 deletions

View File

@@ -5,6 +5,11 @@ import QtQuick.Layouts
import clide.module 1.0
SplitView {
id: root
// Path to the file selected in the tree view.
property string selectedFilePath;
Layout.fillHeight: true
Layout.fillWidth: true
anchors.fill: parent
@@ -42,12 +47,10 @@ SplitView {
wrapMode: TextArea.Wrap
}
// TODO: Shows the files on the file system.
// ClideTreeView {
// id: fileSystemView
// color: Colors.surface1
// onFileClicked: path => root.currentFilePath = path
// }
ClideTreeView {
id: clideTreeView
onFileClicked: path => root.currentFilePath = path
}
}
}
ClideEditor {

148
qml/ClideTreeView.qml Normal file
View File

@@ -0,0 +1,148 @@
import QtQuick
import QtQuick.Controls
import clide.module 1.0
Rectangle {
id: root
signal fileClicked(string filePath)
TreeView {
id: fileSystemTreeView
// rootIndex: FileSystem.rootIndex
property int lastIndex: -1
// model: FileSystem
anchors.fill: parent
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: RustColors.editor_text
}
background: Rectangle {
color: (treeDelegate.index === fileSystemTreeView.lastIndex)
? RustColors.editor_highlight
: (hoverHandler.hovered ? RustColors.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(RustColors.explorer_folder, 3)
//
// const isExpandedFolder = treeDelegate.expanded && treeDelegate.hasChildren;
// if (isExpandedFolder)
// return RustColors.explorer_forder_open
// else
// return RustColors.explorer_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;
}
}
}
Menu {
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: RustColors.scrollbar
opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0
Behavior on opacity {
OpacityAnimator {
duration: 500
}
}
}
}
}
}