Bring in mime icon implementation from cosmic-edit

This commit is contained in:
Jeremy Soller 2024-01-03 15:33:28 -07:00
parent 9978f246b9
commit 68be49302b
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
5 changed files with 887 additions and 127 deletions

932
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,10 @@ default-features = false
features = ["tokio", "winit"]
#path = "../libcosmic"
#TODO: clean up and send changes upstream
[dependencies.systemicons]
git = "https://github.com/jackpot51/systemicons"
[features]
default = ["wgpu"]
wgpu = ["libcosmic/wgpu"]

View file

@ -17,6 +17,8 @@ mod config;
mod localize;
mod mime_icon;
use tab::Tab;
mod tab;

58
src/mime_icon.rs Normal file
View file

@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::widget::icon;
use std::{collections::HashMap, path::Path, sync::Mutex};
pub const FALLBACK_MIME_ICON: &str = "text-x-generic";
#[derive(Debug, Eq, Hash, PartialEq)]
struct MimeIconKey {
path: String,
size: u16,
}
struct MimeIconCache {
cache: HashMap<MimeIconKey, Option<icon::Handle>>,
}
impl MimeIconCache {
pub fn new() -> Self {
Self {
cache: HashMap::new(),
}
}
pub fn get(&mut self, key: MimeIconKey) -> Option<icon::Handle> {
self.cache
.entry(key)
.or_insert_with_key(|key| match systemicons::get_icon(&key.path, key.size) {
Ok(icon_kind) => match icon_kind {
systemicons::Icon::Png(bytes) => Some(icon::from_raster_bytes(bytes)),
systemicons::Icon::Svg(bytes) => Some(icon::from_svg_bytes(bytes)),
},
Err(err) => {
log::warn!("failed to get icon for {:?}: {:?}", key, err);
None
}
})
.clone()
}
}
lazy_static::lazy_static! {
static ref MIME_ICON_CACHE: Mutex<MimeIconCache> = Mutex::new(MimeIconCache::new());
}
pub fn mime_icon<P: AsRef<Path>>(path: P, size: u16) -> icon::Icon {
//TODO: smarter path handling
let path = path
.as_ref()
.to_str()
.expect("failed to convert path to UTF-8")
.to_owned();
let mut mime_icon_cache = MIME_ICON_CACHE.lock().unwrap();
match mime_icon_cache.get(MimeIconKey { path, size }) {
Some(handle) => icon::icon(handle).size(size),
None => icon::from_name(FALLBACK_MIME_ICON).size(size).icon(),
}
}

View file

@ -12,6 +12,8 @@ use std::{
time::{Duration, Instant},
};
use crate::mime_icon::mime_icon;
const DOUBLE_CLICK_DURATION: Duration = Duration::from_millis(500);
#[derive(Clone, Copy, Debug)]
@ -24,7 +26,7 @@ pub struct Item {
pub name: String,
pub path: PathBuf,
pub is_dir: bool,
pub icon: widget::icon::Named,
pub icon: widget::icon::Icon,
pub select_time: Option<Instant>,
}
@ -73,14 +75,14 @@ impl Tab {
};
let path = entry.path();
let is_dir = path.is_dir();
let icon = widget::icon::from_name(if is_dir {
"folder"
//TODO: configurable size
let icon_size = 32;
let icon = if is_dir {
widget::icon::from_name("folder").size(icon_size).icon()
} else {
//TODO: get icon from mime
"text-x-generic"
});
mime_icon(&path, icon_size)
};
self.items.push(Item {
name,
@ -158,7 +160,7 @@ impl Tab {
column = column.push(
widget::button(
widget::row::with_children(vec![
item.icon.clone().size(32).icon().into(),
item.icon.clone().into(),
widget::text(item.name.clone()).into(),
])
.align_items(Alignment::Center)