diff --git a/res/icons/folder-open-symbolic.svg b/res/icons/folder-open-symbolic.svg
new file mode 100644
index 0000000..73b142c
--- /dev/null
+++ b/res/icons/folder-open-symbolic.svg
@@ -0,0 +1,11 @@
+
diff --git a/res/icons/go-down-symbolic.svg b/res/icons/go-down-symbolic.svg
new file mode 100644
index 0000000..5e89982
--- /dev/null
+++ b/res/icons/go-down-symbolic.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/icons/go-next-symbolic.svg b/res/icons/go-next-symbolic.svg
new file mode 100644
index 0000000..8c1b878
--- /dev/null
+++ b/res/icons/go-next-symbolic.svg
@@ -0,0 +1,10 @@
+
diff --git a/res/icons/list-add-symbolic.svg b/res/icons/list-add-symbolic.svg
new file mode 100644
index 0000000..59b2fb0
--- /dev/null
+++ b/res/icons/list-add-symbolic.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/icons/object-select-symbolic.svg b/res/icons/object-select-symbolic.svg
new file mode 100644
index 0000000..a23d9b4
--- /dev/null
+++ b/res/icons/object-select-symbolic.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/icons/window-close-symbolic.svg b/res/icons/window-close-symbolic.svg
new file mode 100644
index 0000000..2533639
--- /dev/null
+++ b/res/icons/window-close-symbolic.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/icon_cache.rs b/src/icon_cache.rs
new file mode 100644
index 0000000..2a5a637
--- /dev/null
+++ b/src/icon_cache.rs
@@ -0,0 +1,49 @@
+use cosmic::widget::icon;
+use std::collections::HashMap;
+
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub struct IconCacheKey {
+ name: &'static str,
+ size: u16,
+}
+
+pub struct IconCache {
+ cache: HashMap,
+}
+
+impl IconCache {
+ pub fn new() -> Self {
+ let mut cache = HashMap::new();
+
+ macro_rules! bundle {
+ ($name:expr, $size:expr) => {
+ let data: &'static [u8] = include_bytes!(concat!("../res/icons/", $name, ".svg"));
+ cache.insert(
+ IconCacheKey {
+ name: $name,
+ size: $size,
+ },
+ icon::from_svg_bytes(data).symbolic(true),
+ );
+ };
+ }
+
+ bundle!("folder-open-symbolic", 16);
+ bundle!("go-down-symbolic", 16);
+ bundle!("go-next-symbolic", 16);
+ bundle!("list-add-symbolic", 16);
+ bundle!("object-select-symbolic", 16);
+ bundle!("window-close-symbolic", 16);
+
+ Self { cache }
+ }
+
+ pub fn get(&mut self, name: &'static str, size: u16) -> icon::Icon {
+ let handle = self
+ .cache
+ .entry(IconCacheKey { name, size })
+ .or_insert_with(|| icon::from_name(name).size(size).handle())
+ .clone();
+ icon::icon(handle).size(size)
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 0052702..4294dd7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -28,6 +28,9 @@ use tokio::time;
use config::{Action, AppTheme, Config, CONFIG_VERSION};
mod config;
+use icon_cache::IconCache;
+mod icon_cache;
+
mod localize;
pub use self::mime_icon::{mime_icon, FALLBACK_MIME_ICON};
@@ -48,6 +51,7 @@ mod text_box;
//TODO: re-use iced FONT_SYSTEM
lazy_static::lazy_static! {
static ref FONT_SYSTEM: Mutex = Mutex::new(FontSystem::new());
+ static ref ICON_CACHE: Mutex = Mutex::new(IconCache::new());
static ref SWASH_CACHE: Mutex = Mutex::new(SwashCache::new());
static ref SYNTAX_SYSTEM: SyntaxSystem = {
let lazy_theme_set = two_face::theme::LazyThemeSet::from(two_face::theme::extra());
@@ -59,6 +63,11 @@ lazy_static::lazy_static! {
};
}
+pub fn icon_cache_get(name: &'static str, size: u16) -> icon::Icon {
+ let mut icon_cache = ICON_CACHE.lock().unwrap();
+ icon_cache.get(name, size)
+}
+
fn main() -> Result<(), Box> {
#[cfg(unix)]
match fork::daemon(true, true) {
@@ -539,7 +548,7 @@ impl Application for App {
app.core.nav_bar_toggle();
app.nav_model
.insert()
- .icon(icon::from_name("folder-open-symbolic").size(16).icon())
+ .icon(icon_cache_get("folder-open-symbolic", 16))
.text(fl!("open-project"));
}
@@ -1149,10 +1158,11 @@ impl Application for App {
row![
view_switcher::horizontal(&self.tab_model)
.button_height(32)
+ .close_icon(icon_cache_get("window-close-symbolic", 16))
.on_activate(Message::TabActivate)
.on_close(Message::TabClose)
.width(Length::Shrink),
- button(icon::from_name("list-add-symbolic").size(16).icon())
+ button(icon_cache_get("list-add-symbolic", 16))
.on_press(Message::NewFile)
.padding(8)
.style(style::Button::Icon)
diff --git a/src/menu.rs b/src/menu.rs
index 6f335ff..525a037 100644
--- a/src/menu.rs
+++ b/src/menu.rs
@@ -15,7 +15,7 @@ use cosmic::{
Element,
};
-use crate::{fl, Action, Config, ContextPage, Message};
+use crate::{fl, icon_cache_get, Action, Config, ContextPage, Message};
macro_rules! menu_button {
($($x:expr),+ $(,)?) => (
@@ -113,10 +113,7 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
//TODO: support key lookup?
let menu_checkbox = |label, value, message| {
let check: Element<_> = if value {
- widget::icon::from_name("object-select-symbolic")
- .size(16)
- .icon()
- .into()
+ icon_cache_get("object-select-symbolic", 16).into()
} else {
widget::Space::with_width(Length::Fixed(16.0)).into()
};
diff --git a/src/project.rs b/src/project.rs
index 6d24c69..839653e 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-only
-use cosmic::widget::{icon, Icon};
+use cosmic::widget::Icon;
use std::{
cmp::Ordering,
fs, io,
path::{Path, PathBuf},
};
-use crate::mime_icon;
+use crate::{icon_cache_get, mime_icon};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ProjectNode {
@@ -53,13 +53,13 @@ impl ProjectNode {
pub fn icon(&self, size: u16) -> Icon {
match self {
//TODO: different icon for project root?
- Self::Folder { open, .. } => icon::from_name(if *open {
- "go-down-symbolic"
- } else {
- "go-next-symbolic"
- })
- .size(size)
- .icon(),
+ Self::Folder { open, .. } => {
+ if *open {
+ icon_cache_get("go-down-symbolic", size)
+ } else {
+ icon_cache_get("go-next-symbolic", size)
+ }
+ }
Self::File { path, .. } => mime_icon(path, size),
}
}