diff --git a/Cargo.lock b/Cargo.lock index 7ff93b3..babf1b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cairo-rs" version = "0.18.5" @@ -661,6 +667,7 @@ dependencies = [ "lazy_static", "num_cpus", "parking_lot", + "rand", "rayon", "shellexpand", ] @@ -834,6 +841,15 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro-crate" version = "2.0.0" @@ -894,6 +910,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1328,3 +1374,24 @@ checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] diff --git a/Cargo.toml b/Cargo.toml index 3113121..f033e4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ lazy_static = "1.4.0" parking_lot = "0.12.1" rayon = "1.7" num_cpus = "1.15" +rand = "0.8" [profile.release] lto = true diff --git a/src/gui.rs b/src/gui.rs index 1a4c38c..7f5190e 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -2,10 +2,11 @@ use glib::ControlFlow; use gtk::gdk::Texture; use gtk::gdk_pixbuf::Pixbuf; use gtk::{ - gdk, gio, glib, prelude::*, Application, ApplicationWindow, Button, FlowBox, Image, - ScrolledWindow, + gdk, gio, glib, prelude::*, Application, ApplicationWindow, Box as GtkBox, Button, FlowBox, + Image, MenuButton, PopoverMenu, ScrolledWindow, }; use parking_lot::Mutex; +use rand::seq::SliceRandom; use rayon::prelude::*; use std::{ cell::RefCell, @@ -144,9 +145,28 @@ pub fn build_ui(app: &Application) { } }); - let main_box = gtk::Box::new(gtk::Orientation::Vertical, 5); - main_box.append(&choose_folder_button); + let sort_button = MenuButton::new(); + sort_button.set_label("Sort"); + let sort_menu = gio::Menu::new(); + sort_menu.append(Some("Date"), Some("app.sort_by_date")); + sort_menu.append(Some("Name"), Some("app.sort_by_name")); + let popover = PopoverMenu::from_model(Some(&sort_menu)); + sort_button.set_popover(Some(&popover)); + + let random_button = Button::with_label("Random"); + let exit_button = Button::with_label("Exit"); + + let bottom_box = GtkBox::new(gtk::Orientation::Horizontal, 10); + bottom_box.set_margin_top(10); + bottom_box.set_margin_bottom(10); + bottom_box.set_halign(gtk::Align::Center); + bottom_box.append(&sort_button); + bottom_box.append(&random_button); + bottom_box.append(&exit_button); + + let main_box = GtkBox::new(gtk::Orientation::Vertical, 0); main_box.append(&scrolled_window); + main_box.append(&bottom_box); window.set_child(Some(&main_box)); @@ -163,6 +183,29 @@ pub fn build_ui(app: &Application) { } }); + let sort_by_date_action = gio::SimpleAction::new("sort_by_date", None); + sort_by_date_action.connect_activate(|_, _| { + println!("Sorting by date"); + }); + app.add_action(&sort_by_date_action); + + let sort_by_name_action = gio::SimpleAction::new("sort_by_name", None); + sort_by_name_action.connect_activate(|_, _| { + println!("Sorting by name"); + }); + app.add_action(&sort_by_name_action); + + let flowbox_clone = Rc::clone(&flowbox_ref); + let image_loader_clone = Rc::clone(&image_loader); + random_button.connect_clicked(move |_| { + set_random_wallpaper(&flowbox_clone, &image_loader_clone); + }); + + let app_clone = app.clone(); + exit_button.connect_clicked(move |_| { + app_clone.quit(); + }); + window.present(); } @@ -283,3 +326,34 @@ fn save_last_path(path: &Path) { let content = format!("[Settings]\nfolder = {}", path.to_str().unwrap_or("")); let _ = fs::write(config_path, content); } + +fn set_random_wallpaper(_flowbox: &Rc>, image_loader: &Rc>) { + let image_loader = image_loader.borrow(); + if let Some(current_folder) = &image_loader.current_folder { + if let Ok(entries) = fs::read_dir(current_folder) { + let images: Vec<_> = entries + .filter_map(|entry| { + entry.ok().and_then(|e| { + let path = e.path(); + if path.is_file() + && matches!( + path.extension().and_then(|e| e.to_str()), + Some("png" | "jpg" | "jpeg") + ) + { + Some(path) + } else { + None + } + }) + }) + .collect(); + + if let Some(random_image) = images.choose(&mut rand::thread_rng()) { + if let Some(path_str) = random_image.to_str() { + crate::set_wallpaper(path_str); + } + } + } + } +}