diff --git a/qml/ClideProjectView.qml b/qml/ClideProjectView.qml
index 1c56c53..3cd08b4 100644
--- a/qml/ClideProjectView.qml
+++ b/qml/ClideProjectView.qml
@@ -43,11 +43,26 @@ SplitView {
SplitView.preferredWidth: 200
SplitView.maximumWidth: 250
- StackLayout {
- anchors.fill: parent
+ ColumnLayout {
+ spacing: 2
+ Rectangle {
+ width: navigationView.width
+ height: breadCrumb.height + 5
+
+ color: RustColors.explorer_text
+ Text {
+ id: breadCrumb
+ text: clideTreeView.rootDirectory
+ elide: Text.ElideLeft
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+
ClideTreeView {
id: clideTreeView
onFileClicked: path => root.projectDir = path
+ width: navigationView.width
+ height: navigationView.height
// Path to the directory opened in the file explorer.
rootDirectory: root.projectDir
diff --git a/qml/ClideTreeView.qml b/qml/ClideTreeView.qml
index 17d7e24..9a58e0b 100644
--- a/qml/ClideTreeView.qml
+++ b/qml/ClideTreeView.qml
@@ -3,153 +3,170 @@
// SPDX-License-Identifier: GNU General Public License v3.0 or later
import QtQuick
+import QtQuick.Effects
import QtQuick.Controls
import clide.module 1.0
-Rectangle {
- id: root
- color: RustColors.explorer_background
+TreeView {
+ id: fileSystemTreeView
+ model: FileSystem
+
+ property int lastIndex: -1
required property string rootDirectory
signal fileClicked(string filePath)
- TreeView {
- id: fileSystemTreeView
- anchors.margins: 15
- property int lastIndex: -1
+ rootIndex: FileSystem.rootIndex
+ leftMargin: 5
+ boundsBehavior: Flickable.StopAtBounds
+ boundsMovement: Flickable.StopAtBounds
+ clip: true
- model: FileSystem
- anchors.fill: parent
- boundsBehavior: Flickable.StopAtBounds
- boundsMovement: Flickable.StopAtBounds
- clip: true
- rootIndex: FileSystem.rootIndex
+ Component.onCompleted: {
+ FileSystem.rootIndex = FileSystem.setDirectory(fileSystemTreeView.rootDirectory)
+ }
- Component.onCompleted: {
- FileSystem.setDirectory(root.rootDirectory)
- fileSystemTreeView.expandRecursively(0, -1)
+ // The delegate represents a single entry in the filesystem.
+ delegate: TreeViewDelegate {
+ id: treeDelegate
+ indentation: 6
+ 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
+
+ function setSourceImage() {
+ let folderOpen = "data:image/svg+xml;utf8,";
+ let folderClosed = "data:image/svg+xml;utf8,";
+ let file = "data:image/svg+xml;utf8,";
+ // If the item has children, it's a directory.
+ if (treeDelegate.hasChildren) {
+ return treeDelegate.expanded ?
+ folderOpen : folderClosed;
+ } else {
+ return file
+ }
+ }
+
+ x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation)
+ anchors.verticalCenter: parent.verticalCenter
+ source: setSourceImage()
+ sourceSize.width: 15
+ sourceSize.height: 15
+ fillMode: Image.PreserveAspectFit
+
+ smooth: true
+ antialiasing: true
+ asynchronous: true
}
- // The delegate represents a single entry in the filesystem.
- delegate: TreeViewDelegate {
- id: treeDelegate
- indentation: 8
- implicitWidth: fileSystemTreeView.width > 0 ? fileSystemTreeView.width : 250
- implicitHeight: 25
+ contentItem: Text {
+ text: treeDelegate.fileName
+ color: RustColors.explorer_text
+ }
- required property int index
- required property url filePath
- required property string fileName
+ background: Rectangle {
+ // TODO: Fix flickering from color transition on states here.
+ color: (treeDelegate.index === fileSystemTreeView.lastIndex)
+ ? RustColors.explorer_text_selected
+ : (hoverHandler.hovered ? RustColors.explorer_hovered : "transparent")
+ radius: 2.5
+ opacity: hoverHandler.hovered ? 0.75 : 1.0
- indicator: Image {
- id: directoryIcon
-
- function setSourceImage() {
- let folderOpen = "data:image/svg+xml;utf8,";
- let folderClosed = "data:image/svg+xml;utf8,";
- let file = "data:image/svg+xml;utf8,";
- // If the item has children, it's a directory.
- if (treeDelegate.hasChildren) {
- return treeDelegate.expanded ?
- folderOpen : folderClosed;
- } else {
- return file
- }
- }
-
- x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation)
- anchors.verticalCenter: parent.verticalCenter
- source: setSourceImage()
- sourceSize.width: 15
- sourceSize.height: 15
- fillMode: Image.PreserveAspectFit
-
- smooth: true
- antialiasing: true
- asynchronous: true
- }
-
- contentItem: Text {
- text: treeDelegate.fileName
- color: RustColors.explorer_text
- }
-
- background: Rectangle {
- // TODO: Fix flickering from color transition on states here.
- color: (treeDelegate.index === fileSystemTreeView.lastIndex)
- ? 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
- }
- }
- }
-
- 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: {
- console.log("Setting directory: " + treeDelegate.filePath)
- FileSystem.rootIndex = FileSystem.setDirectory(treeDelegate.filePath)
- }
- }
- Action {
- text: qsTr("Reset root index")
- onTriggered: {
- FileSystem.rootIndex = FileSystem.setDirectory(root.rootDirectory)
- }
+ Behavior on color {
+ ColorAnimation {
+ duration: 300
}
}
}
- // Provide our own custom ScrollIndicator for the TreeView.
- ScrollIndicator.vertical: ScrollIndicator {
- active: true
- implicitWidth: 15
+ MultiEffect {
+ id: iconOverlay
- contentItem: Rectangle {
- implicitWidth: 6
- implicitHeight: 6
+ anchors.fill: directoryIcon
+ source: directoryIcon
+ colorization: 1.0
+ brightness: 1.0
+ colorizationColor: {
+ const isFile = !treeDelegate.hasChildren;
+ if (isFile)
+ return Qt.lighter(RustColors.explorer_folder, 2)
- color: RustColors.scrollbar
- opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0
+ const isExpandedFolder = treeDelegate.expanded && treeDelegate.hasChildren;
+ if (isExpandedFolder)
+ return Qt.darker(RustColors.explorer_folder, 2)
+ else
+ return RustColors.explorer_folder
+ }
+ }
- Behavior on opacity {
- OpacityAnimator {
- duration: 500
- }
+ HoverHandler {
+ id: hoverHandler
+ acceptedDevices: PointerDevice.Mouse
+ }
+
+ 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: {
+ console.log("Setting directory: " + treeDelegate.filePath)
+ FileSystem.rootIndex = FileSystem.setDirectory(treeDelegate.filePath)
+ }
+ }
+ Action {
+ text: qsTr("Reset root index")
+ onTriggered: {
+ console.log("Reset root index")
+ FileSystem.rootIndex = FileSystem.setDirectory(fileSystemTreeView.rootDirectory)
+ }
+ }
+ }
+ }
+
+ // 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
}
}
}
diff --git a/src/gui/colors.rs b/src/gui/colors.rs
index 0d2b17f..fea8ea1 100644
--- a/src/gui/colors.rs
+++ b/src/gui/colors.rs
@@ -88,10 +88,10 @@ impl Default for RustColorsImpl {
gutter: QColor::try_from("#1e1f22").unwrap(),
explorer_hovered: QColor::try_from("#4c5053").unwrap(),
explorer_text: QColor::try_from("#3b3b3b").unwrap(),
- explorer_text_selected: QColor::try_from("#8b8b8b").unwrap(),
- explorer_background: QColor::try_from("#676c70").unwrap(),
+ explorer_text_selected: QColor::try_from("#262626").unwrap(),
+ explorer_background: QColor::try_from("#1E1F22").unwrap(),
explorer_folder: QColor::try_from("#54585b").unwrap(),
- explorer_folder_open: QColor::try_from("#FFF").unwrap(),
+ explorer_folder_open: QColor::try_from("#2b2b2b").unwrap(),
}
}
}