From aa42ec607231e46568d7eaa0ffbfe18075ae3450 Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sat, 7 Feb 2026 18:01:31 -0500 Subject: [PATCH] Get file explorer icon based on file type. Fixes #15 --- Cargo.lock | 10 +++++++ Cargo.toml | 1 + qml/ClideTreeView.qml | 30 ++++++++------------ resources.qrc | 7 ++++- {images => resources/images}/kilroy-256.png | Bin src/gui/filesystem.rs | 15 ++++++++++ 6 files changed, 44 insertions(+), 19 deletions(-) rename {images => resources/images}/kilroy-256.png (100%) diff --git a/Cargo.lock b/Cargo.lock index c2b50d7..55a5491 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,6 +295,7 @@ dependencies = [ "cxx-qt", "cxx-qt-build", "cxx-qt-lib", + "devicons", "dirs", "edtui", "log", @@ -667,6 +668,15 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "devicons" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830e47e2f330cf4fdd5a958dcef921b9523ffc21ab6713aa5e77ba2cce03904b" +dependencies = [ + "lazy_static", +] + [[package]] name = "digest" version = "0.10.7" diff --git a/Cargo.toml b/Cargo.toml index fe5a0fc..237e11d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ tui-logger = "0.18.1" edtui = "0.11.1" strum = "0.27.2" uuid = { version = "1.19.0", features = ["v4"] } +devicons = "0.6.12" [build-dependencies] # The link_qt_object_files feature is required for statically linking Qt 6. diff --git a/qml/ClideTreeView.qml b/qml/ClideTreeView.qml index 6a7e6de..4f70afe 100644 --- a/qml/ClideTreeView.qml +++ b/qml/ClideTreeView.qml @@ -21,7 +21,7 @@ TreeView { boundsBehavior: Flickable.StopAtBounds boundsMovement: Flickable.StopAtBounds clip: true - leftMargin: 5 + leftMargin: 25 model: FileSystem rootIndex: FileSystem.setDirectory(fileSystemTreeView.rootDirectory) @@ -66,36 +66,30 @@ TreeView { color: RustColors.explorer_text text: treeDelegate.fileName } - indicator: Image { + indicator: Label { 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; - } - return file; - } - anchors.verticalCenter: parent.verticalCenter antialiasing: true - asynchronous: true - fillMode: Image.PreserveAspectFit + font.family: localFont.font.family + font.pixelSize: 18 smooth: true - source: setSourceImage() - sourceSize.height: 15 - sourceSize.width: 15 + text: fileSystemTreeView.model.icon(filePath) x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation) + (indicator.visible ? indicator.width : 0) } + FontLoader { + id: localFont + + source: "qrc:/fonts/saucecodepro-xlight.ttf" + } Label { id: indicator anchors.verticalCenter: parent.verticalCenter + font.family: localFont.font.family font.pixelSize: 10 + font.weight: localFont.font.weight text: expanded ? "⮟" : "⮞" visible: isTreeNode && hasChildren x: padding + (depth * indentation) diff --git a/resources.qrc b/resources.qrc index abfa83c..ac4c2f2 100644 --- a/resources.qrc +++ b/resources.qrc @@ -1,5 +1,10 @@ - images/kilroy-256.png + resources/images/kilroy-256.png + + + resources/SauceCodeProNerdFont-Black.ttf + resources/SauceCodeProNerdFont-Light.ttf + resources/SauceCodeProNerdFont-ExtraLight.ttf \ No newline at end of file diff --git a/images/kilroy-256.png b/resources/images/kilroy-256.png similarity index 100% rename from images/kilroy-256.png rename to resources/images/kilroy-256.png diff --git a/src/gui/filesystem.rs b/src/gui/filesystem.rs index 9d897b7..ea33c62 100644 --- a/src/gui/filesystem.rs +++ b/src/gui/filesystem.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GNU General Public License v3.0 or later use cxx_qt_lib::{QModelIndex, QString}; +use devicons::FileIcon; use dirs; use log::warn; use std::fs; @@ -52,6 +53,9 @@ pub mod qobject { #[qinvokable] #[cxx_name = "setDirectory"] fn set_directory(self: Pin<&mut FileSystem>, path: &QString) -> QModelIndex; + + #[qinvokable] + fn icon(self: Pin<&mut FileSystem>, path: &QString) -> QString; } } @@ -139,4 +143,15 @@ impl qobject::FileSystem { self.set_root_path(&QString::from(homedir)) } } + + fn icon(self: std::pin::Pin<&mut Self>, path: &QString) -> QString { + let str = path.to_string(); + if Path::new(&str).is_dir() { + // Ensures directories are given a folder icon and not mistakenly resolved to a language. + // For example, a directory named `cpp` would otherwise return a C++ icon. + return QString::from(FileIcon::from("dir/").to_string()) + } + let icon = FileIcon::from(str); + QString::from(icon.to_string()) + } }