diff --git a/Cargo.lock b/Cargo.lock
index 1ef0a49f..27af214d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1222,7 +1222,7 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"atomicwrites",
"cosmic-config-derive",
@@ -1241,7 +1241,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"quote",
"syn 1.0.109",
@@ -1348,7 +1348,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"almost",
"cosmic-config",
@@ -2776,7 +2776,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"dnd",
"iced_accessibility",
@@ -2794,7 +2794,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"accesskit",
"accesskit_winit",
@@ -2803,7 +2803,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"bitflags 2.6.0",
"bytes",
@@ -2827,7 +2827,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"futures",
"iced_core",
@@ -2853,7 +2853,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
@@ -2875,7 +2875,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@@ -2887,7 +2887,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"bytes",
"dnd",
@@ -2902,7 +2902,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"bytemuck",
"cosmic-text",
@@ -2918,7 +2918,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"as-raw-xcb-connection",
"bitflags 2.6.0",
@@ -2949,7 +2949,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"dnd",
"iced_renderer",
@@ -2967,7 +2967,7 @@ dependencies = [
[[package]]
name = "iced_winit"
version = "0.14.0-dev"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"dnd",
"iced_futures",
@@ -3551,7 +3551,7 @@ checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "libcosmic"
version = "0.1.0"
-source = "git+https://github.com/pop-os/libcosmic.git#aaadf7199ebed8a5a04ebed559f62455d622689e"
+source = "git+https://github.com/pop-os/libcosmic.git#62b0c8a401c175ab956229b2901f2fdb8b96aeab"
dependencies = [
"apply",
"ashpd 0.9.2",
@@ -3575,6 +3575,7 @@ dependencies = [
"iced_winit",
"lazy_static",
"libc",
+ "license",
"mime 0.3.17",
"palette",
"rfd",
@@ -3649,6 +3650,17 @@ dependencies = [
"redox_syscall 0.5.7",
]
+[[package]]
+name = "license"
+version = "3.5.1+3.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8825807237bd9fa571b99ffea06a26901b0e44692208f87e3b040a499f1504a7"
+dependencies = [
+ "reword",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
@@ -5253,6 +5265,15 @@ dependencies = [
"usvg",
]
+[[package]]
+name = "reword"
+version = "7.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe272098dce9ed76b479995953f748d1851261390b08f8a0ff619c885a1f0765"
+dependencies = [
+ "unicode-segmentation",
+]
+
[[package]]
name = "rfd"
version = "0.14.1"
diff --git a/Cargo.toml b/Cargo.toml
index 52b6721e..6240446d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -63,7 +63,7 @@ uzers = "0.12.0"
git = "https://github.com/pop-os/libcosmic.git"
default-features = false
#TODO: a11y feature crashes
-features = ["multi-window", "tokio", "winit"]
+features = ["multi-window", "tokio", "winit", "about"]
[features]
default = ["bzip2", "desktop", "gvfs", "liblzma", "notify", "wgpu"]
diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl
index a05cd2d2..b28d1492 100644
--- a/i18n/en/cosmic_files.ftl
+++ b/i18n/en/cosmic_files.ftl
@@ -277,3 +277,7 @@ sort-newest-first = Newest first
sort-oldest-first = Oldest first
sort-smallest-to-largest = Smallest to largest
sort-largest-to-smallest = Largest to smallest
+
+## About
+repository = Repository
+support = Support
diff --git a/res/icons/bundled/archive-extract-symbolic.svg b/res/icons/bundled/archive-extract-symbolic.svg
new file mode 100644
index 00000000..4fe1863e
--- /dev/null
+++ b/res/icons/bundled/archive-extract-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/arrow-into-box-symbolic.svg b/res/icons/bundled/arrow-into-box-symbolic.svg
new file mode 100644
index 00000000..fca4bc39
--- /dev/null
+++ b/res/icons/bundled/arrow-into-box-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/brush-monitor-symbolic.svg b/res/icons/bundled/brush-monitor-symbolic.svg
new file mode 100644
index 00000000..8b0436a0
--- /dev/null
+++ b/res/icons/bundled/brush-monitor-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/clipboard-symbolic.svg b/res/icons/bundled/clipboard-symbolic.svg
new file mode 100644
index 00000000..9ba800e2
--- /dev/null
+++ b/res/icons/bundled/clipboard-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/copy-symbolic.svg b/res/icons/bundled/copy-symbolic.svg
new file mode 100644
index 00000000..7aad5a3e
--- /dev/null
+++ b/res/icons/bundled/copy-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/cross-small-square-filled-symbolic.svg b/res/icons/bundled/cross-small-square-filled-symbolic.svg
new file mode 100644
index 00000000..4f83c5d1
--- /dev/null
+++ b/res/icons/bundled/cross-small-square-filled-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/cut-symbolic.svg b/res/icons/bundled/cut-symbolic.svg
new file mode 100644
index 00000000..5e00a6d3
--- /dev/null
+++ b/res/icons/bundled/cut-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/display-symbolic.svg b/res/icons/bundled/display-symbolic.svg
new file mode 100644
index 00000000..e3152317
--- /dev/null
+++ b/res/icons/bundled/display-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/dock-left-symbolic.svg b/res/icons/bundled/dock-left-symbolic.svg
new file mode 100644
index 00000000..3c515204
--- /dev/null
+++ b/res/icons/bundled/dock-left-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/document-open-symbolic.svg b/res/icons/bundled/document-open-symbolic.svg
new file mode 100644
index 00000000..9ca10452
--- /dev/null
+++ b/res/icons/bundled/document-open-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/edit-copy-symbolic.svg b/res/icons/bundled/edit-copy-symbolic.svg
new file mode 100644
index 00000000..230b742c
--- /dev/null
+++ b/res/icons/bundled/edit-copy-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/edit-select-all-symbolic.svg b/res/icons/bundled/edit-select-all-symbolic.svg
new file mode 100644
index 00000000..d1e48c28
--- /dev/null
+++ b/res/icons/bundled/edit-select-all-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/edit-symbolic.svg b/res/icons/bundled/edit-symbolic.svg
new file mode 100644
index 00000000..51090b91
--- /dev/null
+++ b/res/icons/bundled/edit-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/empty-trash-bin-symbolic.svg b/res/icons/bundled/empty-trash-bin-symbolic.svg
new file mode 100644
index 00000000..f27ba1b0
--- /dev/null
+++ b/res/icons/bundled/empty-trash-bin-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/external-link-symbolic.svg b/res/icons/bundled/external-link-symbolic.svg
new file mode 100644
index 00000000..e88a887a
--- /dev/null
+++ b/res/icons/bundled/external-link-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/folder-new-symbolic.svg b/res/icons/bundled/folder-new-symbolic.svg
new file mode 100644
index 00000000..2d467ae9
--- /dev/null
+++ b/res/icons/bundled/folder-new-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/folder-symbolic.svg b/res/icons/bundled/folder-symbolic.svg
new file mode 100644
index 00000000..c7f1815c
--- /dev/null
+++ b/res/icons/bundled/folder-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/grid-symbolic.svg b/res/icons/bundled/grid-symbolic.svg
new file mode 100644
index 00000000..441f2752
--- /dev/null
+++ b/res/icons/bundled/grid-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/history-undo-symbolic.svg b/res/icons/bundled/history-undo-symbolic.svg
new file mode 100644
index 00000000..c1afe3ad
--- /dev/null
+++ b/res/icons/bundled/history-undo-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/image-round-symbolic.svg b/res/icons/bundled/image-round-symbolic.svg
new file mode 100644
index 00000000..0f687ca1
--- /dev/null
+++ b/res/icons/bundled/image-round-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/info-outline-symbolic.svg b/res/icons/bundled/info-outline-symbolic.svg
new file mode 100644
index 00000000..254e7e83
--- /dev/null
+++ b/res/icons/bundled/info-outline-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/list-large-symbolic.svg b/res/icons/bundled/list-large-symbolic.svg
new file mode 100644
index 00000000..cbcd0bbd
--- /dev/null
+++ b/res/icons/bundled/list-large-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/loupe-symbolic.svg b/res/icons/bundled/loupe-symbolic.svg
new file mode 100644
index 00000000..da6ef8c5
--- /dev/null
+++ b/res/icons/bundled/loupe-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/package-x-generic-symbolic.svg b/res/icons/bundled/package-x-generic-symbolic.svg
new file mode 100644
index 00000000..16076016
--- /dev/null
+++ b/res/icons/bundled/package-x-generic-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/paper-symbolic.svg b/res/icons/bundled/paper-symbolic.svg
new file mode 100644
index 00000000..d24c7186
--- /dev/null
+++ b/res/icons/bundled/paper-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/settings-symbolic.svg b/res/icons/bundled/settings-symbolic.svg
new file mode 100644
index 00000000..408d7e5d
--- /dev/null
+++ b/res/icons/bundled/settings-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/shell-overview-symbolic.svg b/res/icons/bundled/shell-overview-symbolic.svg
new file mode 100644
index 00000000..ef1bf2a6
--- /dev/null
+++ b/res/icons/bundled/shell-overview-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/symbolic-link-symbolic.svg b/res/icons/bundled/symbolic-link-symbolic.svg
new file mode 100644
index 00000000..0d582a9e
--- /dev/null
+++ b/res/icons/bundled/symbolic-link-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/tab-new-filled-symbolic.svg b/res/icons/bundled/tab-new-filled-symbolic.svg
new file mode 100644
index 00000000..2b2f1d80
--- /dev/null
+++ b/res/icons/bundled/tab-new-filled-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/terminal-symbolic.svg b/res/icons/bundled/terminal-symbolic.svg
new file mode 100644
index 00000000..f2bba5b9
--- /dev/null
+++ b/res/icons/bundled/terminal-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/user-trash-symbolic.svg b/res/icons/bundled/user-trash-symbolic.svg
new file mode 100644
index 00000000..f99b5009
--- /dev/null
+++ b/res/icons/bundled/user-trash-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/value-decrease-symbolic.svg b/res/icons/bundled/value-decrease-symbolic.svg
new file mode 100644
index 00000000..41f0b6a4
--- /dev/null
+++ b/res/icons/bundled/value-decrease-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/value-increase-symbolic.svg b/res/icons/bundled/value-increase-symbolic.svg
new file mode 100644
index 00000000..1470fac6
--- /dev/null
+++ b/res/icons/bundled/value-increase-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/res/icons/bundled/view-conceal-symbolic.svg b/res/icons/bundled/view-conceal-symbolic.svg
new file mode 100644
index 00000000..3f1cb044
--- /dev/null
+++ b/res/icons/bundled/view-conceal-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/app.rs b/src/app.rs
index 7388ec17..86558d28 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -13,7 +13,7 @@ use cosmic::iced::{
Limits,
};
use cosmic::{
- app::{self, message, Core, Task},
+ app::{self, context_drawer, message, Core, Task},
cosmic_config, cosmic_theme, executor,
iced::{
clipboard::dnd::DndAction,
@@ -29,6 +29,7 @@ use cosmic::{
style, theme,
widget::{
self,
+ about::About,
dnd_destination::DragId,
menu::{action::MenuAction, key_bind::KeyBind},
segmented_button::{self, Entity},
@@ -69,6 +70,8 @@ use crate::{
tab::{self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION},
};
+pub mod icons;
+
#[derive(Clone, Debug)]
pub enum Mode {
App,
@@ -339,6 +342,7 @@ pub enum Message {
),
TabView(Option, tab::View),
ToggleContextPage(ContextPage),
+ ToggleContextDrawer,
ToggleFoldersFirst,
Undo(usize),
UndoTrash(widget::ToastId, Arc<[PathBuf]>),
@@ -503,6 +507,7 @@ impl PartialEq for WatcherWrapper {
/// The [`App`] stores application-specific state.
pub struct App {
core: Core,
+ about: About,
nav_bar_context_id: segmented_button::Entity,
nav_model: segmented_button::SingleSelectModel,
tab_model: segmented_button::Model,
@@ -1429,8 +1434,24 @@ impl Application for App {
let window_id_opt = core.main_window_id();
+ let about = About::default()
+ .name(fl!("cosmic-files"))
+ .author("System 76")
+ .icon(Self::APP_ID)
+ .version("0.1.0")
+ .license("GPL-3.0-only")
+ .links([
+ (fl!("repository"), "https://github.com/pop-os/cosmic-files"),
+ (
+ fl!("support"),
+ "https://github.com/pop-os/cosmic-files/issues",
+ ),
+ ])
+ .developers([("Jeremy Soller", "jeremy@system76.com")]);
+
let mut app = App {
core,
+ about,
nav_bar_context_id: segmented_button::Entity::null(),
nav_model: segmented_button::ModelBuilder::default().build(),
tab_model: segmented_button::ModelBuilder::default().build(),
@@ -1539,37 +1560,44 @@ impl Application for App {
{
items.push(cosmic::widget::menu::Item::Button(
fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
NavMenuAction::Open(entity),
));
items.push(cosmic::widget::menu::Item::Button(
fl!("open-with"),
+ Some(icons::get_handle("external-link-symbolic", 14)),
NavMenuAction::OpenWith(entity),
));
} else {
items.push(cosmic::widget::menu::Item::Button(
fl!("open-in-new-tab"),
+ Some(icons::get_handle("tab-new-filled-symbolic", 14)),
NavMenuAction::OpenInNewTab(entity),
));
items.push(cosmic::widget::menu::Item::Button(
fl!("open-in-new-window"),
+ Some(icons::get_handle("edit-copy-symbolic", 14)),
NavMenuAction::OpenInNewWindow(entity),
));
}
items.push(cosmic::widget::menu::Item::Divider);
items.push(cosmic::widget::menu::Item::Button(
fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
NavMenuAction::Preview(entity),
));
items.push(cosmic::widget::menu::Item::Divider);
if favorite_index_opt.is_some() {
items.push(cosmic::widget::menu::Item::Button(
fl!("remove-from-sidebar"),
+ Some(icons::get_handle("cross-small-square-filled-symbolic", 14)),
NavMenuAction::RemoveFromSidebar(entity),
));
}
if matches!(location_opt, Some(Location::Trash)) {
items.push(cosmic::widget::menu::Item::Button(
fl!("empty-trash"),
+ Some(icons::get_handle("user-trash-symbolic", 14)),
NavMenuAction::EmptyTrash,
));
}
@@ -2724,7 +2752,6 @@ impl Application for App {
tab::Command::AddNetworkDrive => {
self.context_page = ContextPage::NetworkDrive;
self.set_show_context(true);
- self.set_context_title(self.context_page.title());
}
tab::Command::AddToSidebar(path) => {
let mut favorites = self.config.favorites.clone();
@@ -2792,7 +2819,6 @@ impl Application for App {
tab::Command::Preview(kind) => {
self.context_page = ContextPage::Preview(Some(entity), kind);
self.set_show_context(true);
- self.set_context_title(self.context_page.title());
}
tab::Command::WindowDrag => {
if let Some(window_id) = &self.window_id_opt {
@@ -2847,7 +2873,9 @@ impl Application for App {
self.set_show_context(true);
}
self.context_page = context_page;
- self.set_context_title(self.context_page.title());
+ }
+ Message::ToggleContextDrawer => {
+ self.set_show_context(!self.core.window.show_context);
}
Message::Undo(_id) => {
// TODO: undo
@@ -3183,7 +3211,6 @@ impl Application for App {
PreviewKind::Custom(PreviewItem(item)),
);
self.set_show_context(true);
- self.set_context_title(self.context_page.title());
}
Err(err) => {
log::warn!("failed to get item from path {:?}: {}", path, err);
@@ -3302,17 +3329,34 @@ impl Application for App {
Task::none()
}
- fn context_drawer(&self) -> Option> {
+ fn context_drawer(&self) -> Option> {
if !self.core.window.show_context {
return None;
}
Some(match &self.context_page {
- ContextPage::About => self.about(),
- ContextPage::EditHistory => self.edit_history(),
- ContextPage::NetworkDrive => self.network_drive(),
- ContextPage::Preview(entity_opt, kind) => self.preview(entity_opt, kind, true),
- ContextPage::Settings => self.settings(),
+ ContextPage::About => context_drawer::about(
+ &self.about,
+ Message::LaunchUrl,
+ Message::ToggleContextDrawer,
+ ),
+ ContextPage::EditHistory => {
+ context_drawer::context_drawer(self.edit_history(), Message::ToggleContextDrawer)
+ .title(self.context_page.title())
+ }
+ ContextPage::NetworkDrive => {
+ context_drawer::context_drawer(self.network_drive(), Message::ToggleContextDrawer)
+ .title(self.context_page.title())
+ }
+ ContextPage::Preview(entity_opt, kind) => context_drawer::context_drawer(
+ self.preview(entity_opt, kind, true),
+ Message::ToggleContextDrawer,
+ )
+ .title(self.context_page.title()),
+ ContextPage::Settings => {
+ context_drawer::context_drawer(self.settings(), Message::ToggleContextDrawer)
+ .title(self.context_page.title())
+ }
})
}
diff --git a/src/app/icons.rs b/src/app/icons.rs
new file mode 100644
index 00000000..368befaf
--- /dev/null
+++ b/src/app/icons.rs
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-3.0-only
+
+use cosmic::widget::icon;
+use std::collections::HashMap;
+use std::sync::{Mutex, OnceLock};
+
+pub(crate) static ICON_CACHE: OnceLock> = OnceLock::new();
+
+#[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/bundled/", $name, ".svg"));
+ cache.insert(
+ IconCacheKey {
+ name: $name,
+ size: $size,
+ },
+ icon::from_svg_bytes(data).symbolic(true),
+ );
+ };
+ }
+
+ bundle!("tab-new-filled-symbolic", 14);
+ bundle!("value-increase-symbolic", 14);
+ bundle!("value-decrease-symbolic", 14);
+ bundle!("loupe-symbolic", 14);
+ bundle!("folder-symbolic", 14);
+ bundle!("folder-new-symbolic", 14);
+ bundle!("edit-copy-symbolic", 14);
+ bundle!("paper-symbolic", 14);
+ bundle!("document-open-symbolic", 14);
+ bundle!("arrow-into-box-symbolic", 14);
+ bundle!("edit-symbolic", 14);
+ bundle!("user-trash-symbolic", 14);
+ bundle!("cross-small-square-filled-symbolic", 14);
+ bundle!("external-link-symbolic", 14);
+ bundle!("cut-symbolic", 14);
+ bundle!("copy-symbolic", 14);
+ bundle!("clipboard-symbolic", 14);
+ bundle!("edit-select-all-symbolic", 14);
+ bundle!("history-undo-symbolic", 14);
+ bundle!("grid-symbolic", 14);
+ bundle!("list-large-symbolic", 14);
+ bundle!("view-conceal-symbolic", 14);
+ bundle!("settings-symbolic", 14);
+ bundle!("info-outline-symbolic", 14);
+ bundle!("dock-left-symbolic", 14);
+ bundle!("arrow-into-box-symbolic", 14);
+ bundle!("image-round-symbolic", 14);
+ bundle!("terminal-symbolic", 14);
+ bundle!("symbolic-link-symbolic", 14);
+ bundle!("package-x-generic-symbolic", 14);
+ bundle!("archive-extract-symbolic", 14);
+ bundle!("brush-monitor-symbolic", 14);
+ bundle!("display-symbolic", 14);
+ bundle!("shell-overview-symbolic", 14);
+ bundle!("empty-trash-bin-symbolic", 14);
+
+ Self { cache }
+ }
+
+ pub fn get_icon(&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)
+ }
+
+ pub fn get_handle(&mut self, name: &'static str, size: u16) -> icon::Handle {
+ let handle = self
+ .cache
+ .entry(IconCacheKey { name, size })
+ .or_insert_with(|| icon::from_name(name).size(size).handle())
+ .clone();
+ handle
+ }
+}
+
+pub fn get_icon(name: &'static str, size: u16) -> icon::Icon {
+ let mut icon_cache = ICON_CACHE.get().unwrap().lock().unwrap();
+ icon_cache.get_icon(name, size)
+}
+
+pub fn get_handle(name: &'static str, size: u16) -> icon::Handle {
+ let mut icon_cache = ICON_CACHE.get().unwrap().lock().unwrap();
+ icon_cache.get_handle(name, size)
+}
diff --git a/src/dialog.rs b/src/dialog.rs
index 794b63a0..5490f743 100644
--- a/src/dialog.rs
+++ b/src/dialog.rs
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::{
- app::{self, cosmic::Cosmic, message, Core, Task},
+ app::{self, context_drawer, cosmic::Cosmic, message, Core, Task},
cosmic_config, cosmic_theme, executor,
iced::{
event,
@@ -794,13 +794,16 @@ impl Application for App {
(app, commands)
}
- fn context_drawer(&self) -> Option> {
+ fn context_drawer(&self) -> Option> {
if !self.core.window.show_context {
return None;
}
match &self.context_page {
- ContextPage::Preview(_, kind) => Some(self.preview(kind).map(Message::from)),
+ ContextPage::Preview(_, kind) => Some(context_drawer::context_drawer(
+ self.preview(kind).map(Message::from),
+ Message::DialogCancel,
+ )),
_ => None,
}
}
@@ -1401,7 +1404,6 @@ impl Application for App {
tab::Command::Preview(kind) => {
self.context_page = ContextPage::Preview(None, kind);
self.set_show_context(true);
- self.set_context_title(self.context_page.title());
}
tab::Command::WindowDrag => {
commands.push(window::drag(self.flags.window_id));
diff --git a/src/lib.rs b/src/lib.rs
index c6ca3456..650c87d6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,9 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::{app::Settings, iced::Limits};
-use std::{env, fs, path::PathBuf, process};
+use std::{env, fs, path::PathBuf, process, sync::Mutex};
-use app::{App, Flags};
+use app::{
+ icons::{IconCache, ICON_CACHE},
+ App, Flags,
+};
pub mod app;
pub mod clipboard;
use config::Config;
@@ -87,6 +90,8 @@ pub fn main() -> Result<(), Box> {
localize::localize();
+ ICON_CACHE.get_or_init(|| Mutex::new(IconCache::new()));
+
let (config_handler, config) = Config::load();
let mut daemonize = true;
diff --git a/src/menu.rs b/src/menu.rs
index d3616ae2..c3703548 100644
--- a/src/menu.rs
+++ b/src/menu.rs
@@ -15,7 +15,7 @@ use mime_guess::Mime;
use std::collections::HashMap;
use crate::{
- app::{Action, Message},
+ app::{icons, Action, Message},
config::Config,
fl,
tab::{self, HeadingOptions, Location, LocationMenuAction, Tab},
@@ -38,13 +38,14 @@ macro_rules! menu_button {
fn menu_button_optional(
label: String,
+ icon: Option,
action: Action,
enabled: bool,
) -> menu::Item {
if enabled {
- menu::Item::Button(label, action)
+ menu::Item::Button(label, icon, action)
} else {
- menu::Item::ButtonDisabled(label, action)
+ menu::Item::ButtonDisabled(label, icon, action)
}
}
@@ -61,14 +62,25 @@ pub fn context_menu<'a>(
String::new()
};
- let menu_item = |label, action| {
+ let menu_item = |label, icon, action| {
let key = find_key(&action);
- menu_button!(text::body(label), horizontal_space(), text::body(key))
+ if let Some(icon) = icon {
+ menu_button!(
+ widget::icon(icon),
+ widget::Space::with_width(8.0),
+ text::body(label),
+ horizontal_space(),
+ text::body(key)
+ )
.on_press(tab::Message::ContextAction(action))
+ } else {
+ menu_button!(text::body(label), horizontal_space(), text::body(key))
+ .on_press(tab::Message::ContextAction(action))
+ }
};
let (sort_name, sort_direction, _) = tab.sort_options();
- let sort_item = |label, variant| {
+ let sort_item = |label, icon, variant| {
menu_item(
format!(
"{} {}",
@@ -79,6 +91,7 @@ pub fn context_menu<'a>(
_ => "",
}
),
+ icon,
Action::ToggleSort(variant),
)
.into()
@@ -134,50 +147,159 @@ pub fn context_menu<'a>(
Location::Desktop(..) | Location::Path(..) | Location::Search(..) | Location::Recents,
) => {
if selected_trash_only {
- children.push(menu_item(fl!("open"), Action::Open).into());
+ children.push(
+ menu_item(
+ fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
+ Action::Open,
+ )
+ .into(),
+ );
if tab::trash_entries() > 0 {
- children.push(menu_item(fl!("empty-trash"), Action::EmptyTrash).into());
+ children.push(
+ menu_item(
+ fl!("empty-trash"),
+ Some(icons::get_handle("user-trash-symbolic", 14)),
+ Action::EmptyTrash,
+ )
+ .into(),
+ );
}
} else if let Some(entry) = selected_desktop_entry {
- children.push(menu_item(fl!("open"), Action::Open).into());
+ children.push(
+ menu_item(
+ fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
+ Action::Open,
+ )
+ .into(),
+ );
#[cfg(feature = "desktop")]
{
for (i, action) in entry.desktop_actions.into_iter().enumerate() {
- children.push(menu_item(action.name, Action::ExecEntryAction(i)).into())
+ children
+ .push(menu_item(action.name, None, Action::ExecEntryAction(i)).into())
}
}
children.push(divider::horizontal::light().into());
- children.push(menu_item(fl!("rename"), Action::Rename).into());
- children.push(menu_item(fl!("cut"), Action::Cut).into());
- children.push(menu_item(fl!("copy"), Action::Copy).into());
+ children.push(
+ menu_item(
+ fl!("rename"),
+ Some(icons::get_handle("edit-symbolic", 14)),
+ Action::Rename,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("cut"),
+ Some(icons::get_handle("cut-symbolic", 14)),
+ Action::Cut,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("copy"),
+ Some(icons::get_handle("copy-symbolic", 14)),
+ Action::Copy,
+ )
+ .into(),
+ );
// Should this simply bypass trash and remove the shortcut?
- children.push(menu_item(fl!("move-to-trash"), Action::MoveToTrash).into());
+ children.push(
+ menu_item(
+ fl!("move-to-trash"),
+ Some(icons::get_handle("user-trash-symbolic", 14)),
+ Action::MoveToTrash,
+ )
+ .into(),
+ );
} else if selected > 0 {
if selected_dir == 1 && selected == 1 || selected_dir == 0 {
- children.push(menu_item(fl!("open"), Action::Open).into());
+ children.push(
+ menu_item(
+ fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
+ Action::Open,
+ )
+ .into(),
+ );
}
if selected == 1 {
- children.push(menu_item(fl!("open-with"), Action::OpenWith).into());
+ children.push(
+ menu_item(
+ fl!("open-with"),
+ Some(icons::get_handle("external-link-symbolic", 14)),
+ Action::OpenWith,
+ )
+ .into(),
+ );
if selected_dir == 1 {
- children
- .push(menu_item(fl!("open-in-terminal"), Action::OpenTerminal).into());
+ children.push(
+ menu_item(
+ fl!("open-in-terminal"),
+ Some(icons::get_handle("terminal-symbolic", 14)),
+ Action::OpenTerminal,
+ )
+ .into(),
+ );
}
}
if matches!(tab.location, Location::Search(..)) {
children.push(
- menu_item(fl!("open-item-location"), Action::OpenItemLocation).into(),
+ menu_item(
+ fl!("open-item-location"),
+ Some(icons::get_handle("symbolic-link-symbolic", 14)),
+ Action::OpenItemLocation,
+ )
+ .into(),
);
}
// All selected items are directories
if selected == selected_dir && matches!(tab.mode, tab::Mode::App) {
- children.push(menu_item(fl!("open-in-new-tab"), Action::OpenInNewTab).into());
- children
- .push(menu_item(fl!("open-in-new-window"), Action::OpenInNewWindow).into());
+ children.push(
+ menu_item(
+ fl!("open-in-new-tab"),
+ Some(icons::get_handle("tab-new-filled-symbolic", 14)),
+ Action::OpenInNewTab,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("open-in-new-window"),
+ Some(icons::get_handle("edit-copy-symbolic", 14)),
+ Action::OpenInNewWindow,
+ )
+ .into(),
+ );
}
children.push(divider::horizontal::light().into());
- children.push(menu_item(fl!("rename"), Action::Rename).into());
- children.push(menu_item(fl!("cut"), Action::Cut).into());
- children.push(menu_item(fl!("copy"), Action::Copy).into());
+ children.push(
+ menu_item(
+ fl!("rename"),
+ Some(icons::get_handle("edit-symbolic", 14)),
+ Action::Rename,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("cut"),
+ Some(icons::get_handle("cut-symbolic", 14)),
+ Action::Cut,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("copy"),
+ Some(icons::get_handle("copy-symbolic", 14)),
+ Action::Copy,
+ )
+ .into(),
+ );
children.push(divider::horizontal::light().into());
let supported_archive_types = [
@@ -199,55 +321,148 @@ pub fn context_menu<'a>(
.collect::>();
selected_types.retain(|t| !supported_archive_types.contains(t));
if selected_types.is_empty() {
- children.push(menu_item(fl!("extract-here"), Action::ExtractHere).into());
+ children.push(
+ menu_item(
+ fl!("extract-here"),
+ Some(icons::get_handle("archive-extract-symbolic", 14)),
+ Action::ExtractHere,
+ )
+ .into(),
+ );
}
- children.push(menu_item(fl!("compress"), Action::Compress).into());
+ children.push(
+ menu_item(
+ fl!("compress"),
+ Some(icons::get_handle("package-x-generic-symbolic", 14)),
+ Action::Compress,
+ )
+ .into(),
+ );
children.push(divider::horizontal::light().into());
//TODO: Print?
- children.push(menu_item(fl!("show-details"), Action::Preview).into());
+ children.push(
+ menu_item(
+ fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ Action::Preview,
+ )
+ .into(),
+ );
if matches!(tab.mode, tab::Mode::App) {
children.push(divider::horizontal::light().into());
- children.push(menu_item(fl!("add-to-sidebar"), Action::AddToSidebar).into());
+ children.push(
+ menu_item(
+ fl!("add-to-sidebar"),
+ Some(icons::get_handle("dock-left-symbolic", 14)),
+ Action::AddToSidebar,
+ )
+ .into(),
+ );
}
children.push(divider::horizontal::light().into());
- children.push(menu_item(fl!("move-to-trash"), Action::MoveToTrash).into());
+ children.push(
+ menu_item(
+ fl!("move-to-trash"),
+ Some(icons::get_handle("user-trash-symbolic", 14)),
+ Action::MoveToTrash,
+ )
+ .into(),
+ );
} else {
//TODO: need better designs for menu with no selection
//TODO: have things like properties but they apply to the folder?
- children.push(menu_item(fl!("new-folder"), Action::NewFolder).into());
- children.push(menu_item(fl!("new-file"), Action::NewFile).into());
- children.push(menu_item(fl!("open-in-terminal"), Action::OpenTerminal).into());
+ children.push(
+ menu_item(
+ fl!("new-folder"),
+ Some(icons::get_handle("folder-new-symbolic", 14)),
+ Action::NewFolder,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("new-file"),
+ Some(icons::get_handle("paper-symbolic", 14)),
+ Action::NewFile,
+ )
+ .into(),
+ );
+ children.push(
+ menu_item(
+ fl!("open-in-terminal"),
+ Some(icons::get_handle("terminal-symbolic", 14)),
+ Action::OpenTerminal,
+ )
+ .into(),
+ );
children.push(divider::horizontal::light().into());
if tab.mode.multiple() {
- children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
+ children.push(
+ menu_item(
+ fl!("select-all"),
+ Some(icons::get_handle("edit-select-all-symbolic", 14)),
+ Action::SelectAll,
+ )
+ .into(),
+ );
}
- children.push(menu_item(fl!("paste"), Action::Paste).into());
+ children.push(
+ menu_item(
+ fl!("paste"),
+ Some(icons::get_handle("clipboard-symbolic", 14)),
+ Action::Paste,
+ )
+ .into(),
+ );
//TODO: only show if cosmic-settings is found?
if matches!(tab.mode, tab::Mode::Desktop) {
children.push(divider::horizontal::light().into());
children.push(
- menu_item(fl!("change-wallpaper"), Action::CosmicSettingsWallpaper).into(),
+ menu_item(
+ fl!("change-wallpaper"),
+ Some(icons::get_handle("image-symbolic", 14)),
+ Action::CosmicSettingsWallpaper,
+ )
+ .into(),
);
children.push(
- menu_item(fl!("desktop-appearance"), Action::CosmicSettingsAppearance)
- .into(),
+ menu_item(
+ fl!("desktop-appearance"),
+ Some(icons::get_handle("brush-monitor-symbolic", 14)),
+ Action::CosmicSettingsAppearance,
+ )
+ .into(),
);
children.push(
- menu_item(fl!("display-settings"), Action::CosmicSettingsDisplays).into(),
+ menu_item(
+ fl!("display-settings"),
+ Some(icons::get_handle("display-symbolic", 14)),
+ Action::CosmicSettingsDisplays,
+ )
+ .into(),
);
}
children.push(divider::horizontal::light().into());
// TODO: Nested menu
- children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name));
- children.push(sort_item(fl!("sort-by-modified"), HeadingOptions::Modified));
- children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size));
+ children.push(sort_item(fl!("sort-by-name"), None, HeadingOptions::Name));
+ children.push(sort_item(
+ fl!("sort-by-modified"),
+ None,
+ HeadingOptions::Modified,
+ ));
+ children.push(sort_item(fl!("sort-by-size"), None, HeadingOptions::Size));
if matches!(tab.location, Location::Desktop(..)) {
children.push(divider::horizontal::light().into());
children.push(
- menu_item(fl!("desktop-view-options"), Action::DesktopViewOptions).into(),
+ menu_item(
+ fl!("desktop-view-options"),
+ Some(icons::get_handle("shell-overview-symbolic", 14)),
+ Action::DesktopViewOptions,
+ )
+ .into(),
);
}
}
@@ -258,64 +473,143 @@ pub fn context_menu<'a>(
) => {
if selected > 0 {
if selected_dir == 1 && selected == 1 || selected_dir == 0 {
- children.push(menu_item(fl!("open"), Action::Open).into());
+ children.push(
+ menu_item(
+ fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
+ Action::Open,
+ )
+ .into(),
+ );
}
if matches!(tab.location, Location::Search(..)) {
children.push(
- menu_item(fl!("open-item-location"), Action::OpenItemLocation).into(),
+ menu_item(
+ fl!("open-item-location"),
+ Some(icons::get_handle("symbolic-link-symbolic", 14)),
+ Action::OpenItemLocation,
+ )
+ .into(),
);
}
children.push(divider::horizontal::light().into());
- children.push(menu_item(fl!("show-details"), Action::Preview).into());
+ children.push(
+ menu_item(
+ fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ Action::Preview,
+ )
+ .into(),
+ );
} else {
if dialog_kind.save() {
- children.push(menu_item(fl!("new-folder"), Action::NewFolder).into());
+ children.push(
+ menu_item(
+ fl!("new-folder"),
+ Some(icons::get_handle("folder-new-symbolic", 14)),
+ Action::NewFolder,
+ )
+ .into(),
+ );
}
if tab.mode.multiple() {
- children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
+ children.push(
+ menu_item(
+ fl!("select-all"),
+ Some(icons::get_handle("edit-select-all-symbolic", 14)),
+ Action::SelectAll,
+ )
+ .into(),
+ );
}
if !children.is_empty() {
children.push(divider::horizontal::light().into());
}
- children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name));
- children.push(sort_item(fl!("sort-by-modified"), HeadingOptions::Modified));
- children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size));
+ children.push(sort_item(fl!("sort-by-name"), None, HeadingOptions::Name));
+ children.push(sort_item(
+ fl!("sort-by-modified"),
+ None,
+ HeadingOptions::Modified,
+ ));
+ children.push(sort_item(fl!("sort-by-size"), None, HeadingOptions::Size));
}
}
(_, Location::Network(..)) => {
if selected > 0 {
if selected_dir == 1 && selected == 1 || selected_dir == 0 {
- children.push(menu_item(fl!("open"), Action::Open).into());
+ children.push(
+ menu_item(
+ fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
+ Action::Open,
+ )
+ .into(),
+ );
}
} else {
if tab.mode.multiple() {
- children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
+ children.push(
+ menu_item(
+ fl!("select-all"),
+ Some(icons::get_handle("edit-select-all-symbolic", 14)),
+ Action::SelectAll,
+ )
+ .into(),
+ );
}
if !children.is_empty() {
children.push(divider::horizontal::light().into());
}
- children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name));
- children.push(sort_item(fl!("sort-by-modified"), HeadingOptions::Modified));
- children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size));
+ children.push(sort_item(fl!("sort-by-name"), None, HeadingOptions::Name));
+ children.push(sort_item(
+ fl!("sort-by-modified"),
+ None,
+ HeadingOptions::Modified,
+ ));
+ children.push(sort_item(fl!("sort-by-size"), None, HeadingOptions::Size));
}
}
(_, Location::Trash) => {
if tab.mode.multiple() {
- children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
+ children.push(
+ menu_item(
+ fl!("select-all"),
+ Some(icons::get_handle("edit-select-all-symbolic", 14)),
+ Action::SelectAll,
+ )
+ .into(),
+ );
}
if !children.is_empty() {
children.push(divider::horizontal::light().into());
}
if selected > 0 {
- children.push(menu_item(fl!("show-details"), Action::Preview).into());
+ children.push(
+ menu_item(
+ fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ Action::Preview,
+ )
+ .into(),
+ );
children.push(divider::horizontal::light().into());
- children
- .push(menu_item(fl!("restore-from-trash"), Action::RestoreFromTrash).into());
+ children.push(
+ menu_item(
+ fl!("restore-from-trash"),
+ Some(icons::get_handle("empty-trash-bin-symbolic", 14)),
+ Action::RestoreFromTrash,
+ )
+ .into(),
+ );
} else {
// TODO: Nested menu
- children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name));
- children.push(sort_item(fl!("sort-by-trashed"), HeadingOptions::TrashedOn));
- children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size));
+ children.push(sort_item(fl!("sort-by-name"), None, HeadingOptions::Name));
+ children.push(sort_item(
+ fl!("sort-by-trashed"),
+ None,
+ HeadingOptions::TrashedOn,
+ ));
+ children.push(sort_item(fl!("sort-by-size"), None, HeadingOptions::Size));
}
}
}
@@ -351,6 +645,7 @@ pub fn dialog_menu<'a>(
let sort_item = |label, sort, dir| {
menu::Item::CheckBox(
label,
+ None,
sort_name == sort && sort_direction == dir,
Action::SetSort(sort, dir),
)
@@ -382,11 +677,13 @@ pub fn dialog_menu<'a>(
vec![
menu::Item::CheckBox(
fl!("grid-view"),
+ Some(icons::get_handle("grid-symbolic", 14)),
matches!(tab.config.view, tab::View::Grid),
Action::TabViewGrid,
),
menu::Item::CheckBox(
fl!("list-view"),
+ Some(icons::get_handle("list-large-symbolic", 14)),
matches!(tab.config.view, tab::View::List),
Action::TabViewList,
),
@@ -447,24 +744,44 @@ pub fn dialog_menu<'a>(
menu::items(
key_binds,
vec![
- menu::Item::Button(fl!("zoom-in"), Action::ZoomIn),
- menu::Item::Button(fl!("default-size"), Action::ZoomDefault),
- menu::Item::Button(fl!("zoom-out"), Action::ZoomOut),
+ menu::Item::Button(
+ fl!("zoom-in"),
+ Some(icons::get_handle("value-increase-symbolic", 14)),
+ Action::ZoomIn,
+ ),
+ menu::Item::Button(
+ fl!("default-size"),
+ Some(icons::get_handle("loupe-symbolic", 14)),
+ Action::ZoomDefault,
+ ),
+ menu::Item::Button(
+ fl!("zoom-out"),
+ Some(icons::get_handle("value-decrease-symbolic", 14)),
+ Action::ZoomOut,
+ ),
menu::Item::Divider,
menu::Item::CheckBox(
fl!("show-hidden-files"),
+ Some(icons::get_handle("view-conceal-symbolic", 14)),
tab.config.show_hidden,
Action::ToggleShowHidden,
),
menu::Item::CheckBox(
fl!("list-directories-first"),
+ Some(icons::get_handle("folder-symbolic", 14)),
tab.config.folders_first,
Action::ToggleFoldersFirst,
),
- menu::Item::CheckBox(fl!("show-details"), show_details, Action::Preview),
+ menu::Item::CheckBox(
+ fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ show_details,
+ Action::Preview,
+ ),
menu::Item::Divider,
menu_button_optional(
fl!("gallery-preview"),
+ Some(icons::get_handle("image-round-symbolic", 14)),
Action::Gallery,
selected_gallery > 0,
),
@@ -487,6 +804,7 @@ pub fn menu_bar<'a>(
let sort_item = |label, sort, dir| {
menu::Item::CheckBox(
label,
+ None,
sort_options.map_or(false, |(sort_name, sort_direction, _)| {
sort_name == sort && sort_direction == dir
}),
@@ -518,25 +836,70 @@ pub fn menu_bar<'a>(
menu::items(
key_binds,
vec![
- menu::Item::Button(fl!("new-tab"), Action::TabNew),
- menu::Item::Button(fl!("new-window"), Action::WindowNew),
- menu::Item::Button(fl!("new-folder"), Action::NewFolder),
- menu::Item::Button(fl!("new-file"), Action::NewFile),
+ menu::Item::Button(
+ fl!("new-tab"),
+ Some(icons::get_handle("tab-new-filled-symbolic", 14)),
+ Action::TabNew,
+ ),
+ menu::Item::Button(
+ fl!("new-window"),
+ Some(icons::get_handle("edit-copy-symbolic", 14)),
+ Action::WindowNew,
+ ),
+ menu::Item::Button(
+ fl!("new-folder"),
+ Some(icons::get_handle("folder-new-symbolic", 14)),
+ Action::NewFolder,
+ ),
+ menu::Item::Button(
+ fl!("new-file"),
+ Some(icons::get_handle("paper-symbolic", 14)),
+ Action::NewFile,
+ ),
menu_button_optional(
fl!("open"),
+ Some(icons::get_handle("document-open-symbolic", 14)),
Action::Open,
(selected > 0 && selected_dir == 0) || (selected_dir == 1 && selected == 1),
),
- menu_button_optional(fl!("open-with"), Action::OpenWith, selected == 1),
+ menu_button_optional(
+ fl!("open-with"),
+ Some(icons::get_handle("external-link-symbolic", 14)),
+ Action::OpenWith,
+ selected == 1,
+ ),
menu::Item::Divider,
- menu_button_optional(fl!("rename"), Action::Rename, selected > 0),
+ menu_button_optional(
+ fl!("rename"),
+ Some(icons::get_handle("edit-symbolic", 14)),
+ Action::Rename,
+ selected > 0,
+ ),
menu::Item::Divider,
- menu_button_optional(fl!("add-to-sidebar"), Action::AddToSidebar, selected > 0),
+ menu_button_optional(
+ fl!("add-to-sidebar"),
+ Some(icons::get_handle("dock-left-symbolic", 14)),
+ Action::AddToSidebar,
+ selected > 0,
+ ),
menu::Item::Divider,
- menu_button_optional(fl!("move-to-trash"), Action::MoveToTrash, selected > 0),
+ menu_button_optional(
+ fl!("move-to-trash"),
+ Some(icons::get_handle("user-trash-symbolic", 14)),
+ Action::MoveToTrash,
+ selected > 0,
+ ),
menu::Item::Divider,
- menu::Item::Button(fl!("close-tab"), Action::TabClose),
- menu::Item::Button(fl!("quit"), Action::WindowClose),
+ menu::Item::Button(
+ fl!("close-tab"),
+ Some(icons::get_handle("cross-small-square-filled-symbolic", 14)),
+ Action::TabClose,
+ ),
+ menu::Item::Button(
+ fl!("quit"),
+ Some(icons::get_handle("arrow-into-box-symbolic", 14)),
+ Action::WindowClose,
+ ),
],
),
),
@@ -545,12 +908,35 @@ pub fn menu_bar<'a>(
menu::items(
key_binds,
vec![
- menu_button_optional(fl!("cut"), Action::Cut, selected > 0),
- menu_button_optional(fl!("copy"), Action::Copy, selected > 0),
- menu_button_optional(fl!("paste"), Action::Paste, selected > 0),
- menu::Item::Button(fl!("select-all"), Action::SelectAll),
+ menu_button_optional(
+ fl!("cut"),
+ Some(icons::get_handle("cut-symbolic", 14)),
+ Action::Cut,
+ selected > 0,
+ ),
+ menu_button_optional(
+ fl!("copy"),
+ Some(icons::get_handle("copy-symbolic", 14)),
+ Action::Copy,
+ selected > 0,
+ ),
+ menu_button_optional(
+ fl!("paste"),
+ Some(icons::get_handle("clipboard-symbolic", 14)),
+ Action::Paste,
+ selected > 0,
+ ),
+ menu::Item::Button(
+ fl!("select-all"),
+ Some(icons::get_handle("edit-select-all-symbolic", 14)),
+ Action::SelectAll,
+ ),
menu::Item::Divider,
- menu::Item::Button(fl!("history"), Action::EditHistory),
+ menu::Item::Button(
+ fl!("history"),
+ Some(icons::get_handle("history-undo-symbolic", 14)),
+ Action::EditHistory,
+ ),
],
),
),
@@ -559,42 +945,72 @@ pub fn menu_bar<'a>(
menu::items(
key_binds,
vec![
- menu::Item::Button(fl!("zoom-in"), Action::ZoomIn),
- menu::Item::Button(fl!("default-size"), Action::ZoomDefault),
- menu::Item::Button(fl!("zoom-out"), Action::ZoomOut),
+ menu::Item::Button(
+ fl!("zoom-in"),
+ Some(icons::get_handle("value-increase-symbolic", 14)),
+ Action::ZoomIn,
+ ),
+ menu::Item::Button(
+ fl!("default-size"),
+ Some(icons::get_handle("loupe-symbolic", 14)),
+ Action::ZoomDefault,
+ ),
+ menu::Item::Button(
+ fl!("zoom-out"),
+ Some(icons::get_handle("value-decrease-symbolic", 14)),
+ Action::ZoomOut,
+ ),
menu::Item::Divider,
menu::Item::CheckBox(
fl!("grid-view"),
+ Some(icons::get_handle("grid-symbolic", 14)),
tab_opt.map_or(false, |tab| matches!(tab.config.view, tab::View::Grid)),
Action::TabViewGrid,
),
menu::Item::CheckBox(
fl!("list-view"),
+ Some(icons::get_handle("list-large-symbolic", 14)),
tab_opt.map_or(false, |tab| matches!(tab.config.view, tab::View::List)),
Action::TabViewList,
),
menu::Item::Divider,
menu::Item::CheckBox(
fl!("show-hidden-files"),
+ Some(icons::get_handle("view-conceal-symbolic", 14)),
tab_opt.map_or(false, |tab| tab.config.show_hidden),
Action::ToggleShowHidden,
),
menu::Item::CheckBox(
fl!("list-directories-first"),
+ Some(icons::get_handle("folder-symbolic", 14)),
tab_opt.map_or(false, |tab| tab.config.folders_first),
Action::ToggleFoldersFirst,
),
- menu::Item::CheckBox(fl!("show-details"), config.show_details, Action::Preview),
+ menu::Item::CheckBox(
+ fl!("show-details"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ config.show_details,
+ Action::Preview,
+ ),
menu::Item::Divider,
menu_button_optional(
fl!("gallery-preview"),
+ Some(icons::get_handle("image-round-symbolic", 14)),
Action::Gallery,
selected_gallery > 0,
),
menu::Item::Divider,
- menu::Item::Button(fl!("menu-settings"), Action::Settings),
+ menu::Item::Button(
+ fl!("menu-settings"),
+ Some(icons::get_handle("settings-symbolic", 14)),
+ Action::Settings,
+ ),
menu::Item::Divider,
- menu::Item::Button(fl!("menu-about"), Action::About),
+ menu::Item::Button(
+ fl!("menu-about"),
+ Some(icons::get_handle("info-outline-symbolic", 14)),
+ Action::About,
+ ),
],
),
),