Load icons using mime type

This commit is contained in:
Jeremy Soller 2023-11-13 10:33:26 -07:00
parent 1151c64323
commit f76f83565c
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
6 changed files with 72 additions and 15 deletions

26
Cargo.lock generated
View file

@ -847,6 +847,7 @@ dependencies = [
"lazy_static",
"libcosmic",
"log",
"mime_guess",
"rfd",
"rust-embed",
"serde",
@ -2716,6 +2717,22 @@ dependencies = [
"objc",
]
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -4636,6 +4653,15 @@ dependencies = [
"tinystr",
]
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"

View file

@ -10,6 +10,7 @@ env_logger = "0.10.0"
fontdb = "0.15.0"
lazy_static = "1.4.0"
log = "0.4.20"
mime_guess = "2"
rfd = "0.12.0"
serde = { version = "1", features = ["serde_derive"] }
syntect = "5.1.0"

View file

@ -26,6 +26,9 @@ mod config;
mod localize;
pub use self::mime_icon::{mime_icon, FALLBACK_MIME_ICON};
mod mime_icon;
use self::menu::menu_bar;
mod menu;
@ -212,7 +215,7 @@ impl App {
.insert()
.position(position)
.indent(indent)
.icon(icon::from_name(node.icon_name()).size(16).icon())
.icon(node.icon(16))
.text(node.name().to_string())
.data(node);
@ -247,7 +250,7 @@ impl App {
let id = self
.nav_model
.insert()
.icon(icon::from_name(node.icon_name()).size(16).icon())
.icon(node.icon(16))
.text(node.name().to_string())
.data(node)
.id();
@ -265,7 +268,7 @@ impl App {
self.tab_model
.insert()
.text(tab.title())
.icon(icon::from_name("text-x-generic").size(16).icon())
.icon(tab.icon(16))
.data::<Tab>(tab)
.closable()
.activate();
@ -494,8 +497,7 @@ impl Application for App {
match node_opt {
Some(node) => {
// Update icon
self.nav_model
.icon_set(id, icon::from_name(node.icon_name()).size(16).icon());
self.nav_model.icon_set(id, node.icon(16));
match node {
ProjectNode::Folder { path, open, .. } => {

17
src/mime_icon.rs Normal file
View file

@ -0,0 +1,17 @@
use cosmic::widget::icon;
use std::path::Path;
pub const FALLBACK_MIME_ICON: &str = "text-x-generic";
pub fn mime_icon<P: AsRef<Path>>(path: P, size: u16) -> icon::Icon {
let path = path.as_ref();
for mime in mime_guess::from_path(path).iter() {
//TODO: correct some common issues (like application/x-sh not being found)
let icon_name = mime.essence_str().replace("/", "-");
let named = icon::from_name(icon_name).size(size);
if named.clone().path().is_some() {
return named.icon();
}
}
icon::from_name(FALLBACK_MIME_ICON).size(size).icon()
}

View file

@ -1,11 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::widget::{icon, Icon};
use std::{
cmp::Ordering,
fs, io,
path::{Path, PathBuf},
};
use crate::mime_icon;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ProjectNode {
Folder {
@ -47,17 +50,17 @@ impl ProjectNode {
})
}
pub fn icon_name(&self) -> &str {
pub fn icon(&self, size: u16) -> Icon {
match self {
//TODO: different icon for project root?
Self::Folder { open, .. } => {
if *open {
"go-down-symbolic"
} else {
"go-next-symbolic"
}
}
Self::File { .. } => "text-x-generic",
Self::Folder { open, .. } => icon::from_name(if *open {
"go-down-symbolic"
} else {
"go-next-symbolic"
})
.size(size)
.icon(),
Self::File { path, .. } => mime_icon(path, size),
}
}

View file

@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::widget::{icon, Icon};
use cosmic_text::{Attrs, Buffer, Edit, Shaping, SyntaxEditor, ViEditor, Wrap};
use std::{fs, path::PathBuf, sync::Mutex};
use crate::{fl, Config, FONT_SYSTEM, SYNTAX_SYSTEM};
use crate::{fl, mime_icon, Config, FALLBACK_MIME_ICON, FONT_SYSTEM, SYNTAX_SYSTEM};
pub struct Tab {
pub path_opt: Option<PathBuf>,
@ -95,6 +96,13 @@ impl Tab {
}
}
pub fn icon(&self, size: u16) -> Icon {
match &self.path_opt {
Some(path) => mime_icon(path, size),
None => icon::from_name(FALLBACK_MIME_ICON).size(size).icon(),
}
}
pub fn title(&self) -> String {
//TODO: show full title when there is a conflict
if let Some(path) = &self.path_opt {