From c9f156b2c4e73e93c1b47b50a0aed1d304747231 Mon Sep 17 00:00:00 2001 From: Alexandre Trendel Date: Sun, 12 Feb 2023 12:18:41 -0500 Subject: [PATCH 1/4] update gtk rs --- Cargo.lock | 108 ++++++++------- Cargo.toml | 14 +- README.md | 2 +- src/app/components/album/album.rs | 31 ++--- src/app/components/artist/mod.rs | 10 +- .../artist_details/artist_details.rs | 14 +- src/app/components/details/album_header.rs | 26 ++-- src/app/components/details/details.rs | 56 +++----- src/app/components/details/release_details.rs | 15 +- src/app/components/headerbar/widget.rs | 60 ++++---- src/app/components/library/library.rs | 17 ++- src/app/components/login/login.rs | 19 ++- src/app/components/navigation/home.rs | 2 +- src/app/components/notification/mod.rs | 2 +- src/app/components/now_playing/now_playing.rs | 10 +- .../components/playback/playback_controls.rs | 33 ++--- src/app/components/playback/playback_info.rs | 14 +- .../components/playback/playback_widget.rs | 42 +++--- src/app/components/playlist/playlist.rs | 4 +- src/app/components/playlist/song.rs | 56 +++----- .../playlist_details/playlist_details.rs | 36 ++--- .../saved_playlists/saved_playlists.rs | 10 +- .../components/saved_tracks/saved_tracks.rs | 10 +- src/app/components/search/search.rs | 24 ++-- src/app/components/selection/widget.rs | 50 +++---- src/app/components/settings/settings.rs | 13 +- .../sidebar_listbox/sidebar_icon_widget.rs | 17 +-- .../sidebar_listbox/sidebar_item.rs | 131 ++++-------------- .../components/sidebar_listbox/sidebar_row.rs | 100 ++++++------- .../components/user_details/user_details.rs | 14 +- src/app/models/album_model.rs | 127 +++-------------- src/app/models/artist_model.rs | 90 +++--------- src/app/models/songs/song_list_model.rs | 81 +++++------ src/app/models/songs/song_model.rs | 105 ++++---------- src/main.rs | 2 +- 35 files changed, 476 insertions(+), 869 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b596c77..7e93b77c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,22 +363,23 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cairo-rs" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a" +checksum = "a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871" dependencies = [ "bitflags", "cairo-sys-rs", "glib", "libc", + "once_cell", "thiserror", ] [[package]] name = "cairo-sys-rs" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +checksum = "f55382a01d30e5e53f185eee269124f5e21ab526595b872751278dfbb463594e" dependencies = [ "glib-sys", "libc", @@ -911,22 +912,23 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.15.6" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8750501d75f318c2ec0314701bc8403901303210def80bafd13f6b6059a3f45" +checksum = "b023fbe0c6b407bd3d9805d107d9800da3829dc5a676653210f1d5f16d7f59bf" dependencies = [ "bitflags", "gdk-pixbuf-sys", "gio", "glib", "libc", + "once_cell", ] [[package]] name = "gdk-pixbuf-sys" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" +checksum = "7b41bd2b44ed49d99277d3925652a163038bd5ed943ec9809338ffb2f4391e3b" dependencies = [ "gio-sys", "glib-sys", @@ -937,9 +939,9 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.4.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df40006277ff44538fe758400fc671146f6f2665978b6b57d2408db3c2becf" +checksum = "6e4887e17b6926db51f1e538d871a8b1f5ceb5dfa3bd0034dc42ec355b390d8f" dependencies = [ "bitflags", "cairo-rs", @@ -953,9 +955,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.4.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b" +checksum = "f4993c019bf03d18137c00ddafb2b23e73f7cbb45ae244f52af2542a3f4a9452" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1020,26 +1022,29 @@ dependencies = [ [[package]] name = "gio" -version = "0.15.7" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb50e113645fba48bc36c8abaee1fe5e43d353e8763966e29dfe69660514e461" +checksum = "1981edf8679d2f2c8ec3120015867f45aa0a1c2d5e3e129ca2f7dda174d3d2a9" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-io", + "futures-util", "gio-sys", "glib", "libc", "once_cell", + "pin-project-lite", + "smallvec", "thiserror", ] [[package]] name = "gio-sys" -version = "0.15.5" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3" +checksum = "b5d3076ecb86c8c3a672c9843d6232b3a344fb81d304d0ba1ac64b23343efa46" dependencies = [ "glib-sys", "gobject-sys", @@ -1050,19 +1055,22 @@ dependencies = [ [[package]] name = "glib" -version = "0.15.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89528258cfdc79b1e54591202705be67896ad254f99e3cc2ea3710e0307148f2" +checksum = "ac347af59233f0544ce00a37bad50f4ac401d006505b26d80ad6d9bbecf6493f" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", + "futures-util", + "gio-sys", "glib-macros", "glib-sys", "gobject-sys", "libc", + "memchr", "once_cell", "smallvec", "thiserror", @@ -1070,9 +1078,9 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.15.3" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1" +checksum = "5965ae1a44aa4bae4e1e6970f25b66c058fef873d2626c9932a41128dbeea03f" dependencies = [ "anyhow", "heck", @@ -1085,9 +1093,9 @@ dependencies = [ [[package]] name = "glib-sys" -version = "0.15.5" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c" +checksum = "9ddcb73fa8236277bedadaaadb76aef49c85d66340f83bece244f46c2d4f0e01" dependencies = [ "libc", "system-deps", @@ -1113,9 +1121,9 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.15.5" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" +checksum = "9a0155d388840c77d61b033b66ef4f9bc7f4133d83df83572d6b4fb234a3be7d" dependencies = [ "glib-sys", "libc", @@ -1124,9 +1132,9 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570" +checksum = "372514f21c7e342e0206a916d6bd522b15337578cfa68855518a3b4960ba8254" dependencies = [ "glib", "graphene-sys", @@ -1135,9 +1143,9 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f311acb023cf7af5537f35de028e03706136eead7f25a31e8fd26f5011e0b3" +checksum = "cf80a4849a8d9565410a8fec6fc3678e9c617f4ac7be182ca55ab75016e07af9" dependencies = [ "glib-sys", "libc", @@ -1147,9 +1155,9 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.4.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf63d454e2f75abd92ee6de0ac9fc5aaf1018cd9c458aaf9de296c5cbab6bb9" +checksum = "432f981e4ea9f0739a5731d8a649acb794a3a729d2254e559ce7d613b17caf95" dependencies = [ "bitflags", "cairo-rs", @@ -1163,9 +1171,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.4.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b" +checksum = "096cb59175b0915ebf69c05a45263c0c989bd8537b8f2169912d0de644ba6a76" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -1179,9 +1187,9 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.4.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e841556e3fe55d8a43ada76b7b08a5f65570bbdfe3b8f72c333053b8832c626" +checksum = "f61aa16bbd4554552645227d4249b58fd730b27985a7e0283fd0a2d479e954a8" dependencies = [ "bitflags", "cairo-rs", @@ -1202,9 +1210,9 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573db42bb64973a4d5f718b73caa7204285a1a665308a23b11723d0ee56ec305" +checksum = "db4676c4f90d8b010e88cb4558f61f47d76d6f6b8e6f6b89e62640f443907f61" dependencies = [ "anyhow", "proc-macro-crate 1.1.0", @@ -1216,9 +1224,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.4.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d" +checksum = "e13cf3bc9559f71963c957eb639060b643e1276ae47b892ef6091d5bc15c3e1b" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1574,10 +1582,12 @@ dependencies = [ [[package]] name = "libadwaita" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4b1d54d907dfa5d6663fdf4bdbe46c34747258b85c787adbf66187ccbaac81" +checksum = "674cbf1bd796f3d4f0c24466c15d91180e33e497ae2e07eea3f3d545468dc839" dependencies = [ + "bitflags", + "futures-channel", "gdk-pixbuf", "gdk4", "gio", @@ -1591,9 +1601,9 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8" +checksum = "0727b85b4fe2b1bed5ac90df6343de15cbf8118bfb96d7c3cc1512681a4b34ac" dependencies = [ "gdk4-sys", "gio-sys", @@ -1601,6 +1611,7 @@ dependencies = [ "gobject-sys", "gtk4-sys", "libc", + "pango-sys", "system-deps", ] @@ -1959,9 +1970,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -2360,11 +2371,12 @@ dependencies = [ [[package]] name = "pango" -version = "0.15.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94" +checksum = "243c048be90312220fb3bd578176eed8290568274a93c95040289d39349384bc" dependencies = [ "bitflags", + "gio", "glib", "libc", "once_cell", @@ -2373,9 +2385,9 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" +checksum = "4293d0f0b5525eb5c24734d30b0ed02cd02aa734f216883f376b54de49625de8" dependencies = [ "glib-sys", "gobject-sys", diff --git a/Cargo.toml b/Cargo.toml index eea8be79..8d450ba7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,19 +5,20 @@ edition = "2018" license = "MIT" [dependencies.gtk] -version = "^0.4.1" +version = "^0.6.0" package = "gtk4" +features = ["gnome_42"] [dependencies.gdk] -version = "^0.4.0" +version = "^0.6.0" package = "gdk4" [dependencies.gio] -version = "^0.15.7" +version = "^0.17.0" features = ["v2_60"] [dependencies.glib] -version = "^0.15.9" +version = "^0.17.0" features = ["v2_60"] [dependencies.librespot] @@ -31,7 +32,6 @@ version = "2.25.2" version = "1" features = ["rt", "macros", "sync"] - [dependencies.futures] package = "futures" version = "0.3.18" @@ -57,8 +57,8 @@ features = ["gettext-system"] [dependencies] secret-service = "^2.0.1" -gdk-pixbuf = "^0.15.6" -libadwaita = "^0.1.0-beta-1" +gdk-pixbuf = "^0.17.0" +libadwaita = "^0.3.0" ref_filter_map = "^1.0.1" regex = "^1.5.5" async-std = "^1.10.0" diff --git a/README.md b/README.md index 6c630c41..955231fd 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ With meson: meson target -Dbuildtype=debug -Doffline=false --prefix="$HOME/.local" ninja install -C target # to run test/linter/etc -meson test -C target +meson test -C target --verbose ``` This will install a `.desktop` file among other things, and the spot executable will be put in `.local/bin` (you might want to add it to your path). diff --git a/src/app/components/album/album.rs b/src/app/components/album/album.rs index 014eb858..ec391efe 100644 --- a/src/app/components/album/album.rs +++ b/src/app/components/album/album.rs @@ -38,7 +38,7 @@ mod imp { type ParentType = libadwaita::Bin; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -58,7 +58,7 @@ glib::wrapper! { impl AlbumWidget { pub fn new() -> Self { display_add_css_provider(resource!("/components/album.css")); - glib::Object::new(&[]).expect("Failed to create an instance of AlbumWidget") + glib::Object::new() } pub fn for_model(album_model: &AlbumModel, worker: Worker) -> Self { @@ -73,21 +73,19 @@ impl AlbumWidget { } fn set_image(&self, pixbuf: Option<&gdk_pixbuf::Pixbuf>) { - imp::AlbumWidget::from_instance(self) - .cover_image - .set_from_pixbuf(pixbuf); + self.imp().cover_image.set_from_pixbuf(pixbuf); } fn bind(&self, album_model: &AlbumModel, worker: Worker) { - let widget = imp::AlbumWidget::from_instance(self); + let widget = self.imp(); widget.cover_image.set_overflow(gtk::Overflow::Hidden); - if let Some(url) = album_model.cover_url() { + if let Some(cover_art) = album_model.cover() { let _self = self.downgrade(); worker.send_local_task(async move { if let Some(_self) = _self.upgrade() { let loader = ImageLoader::new(); - let result = loader.load_remote(&url, "jpg", 200, 200).await; + let result = loader.load_remote(&cover_art, "jpg", 200, 200).await; _self.set_image(result.as_ref()); _self.set_loaded(); } @@ -106,21 +104,14 @@ impl AlbumWidget { .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(); - match album_model.year() { - Some(_) => { - album_model - .bind_property("year", &*widget.year_label, "label") - .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) - .build(); - } - None => { - widget.year_label.hide(); - } - } + album_model + .bind_property("year", &*widget.year_label, "label") + .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) + .build(); } pub fn connect_album_pressed(&self, f: F) { - imp::AlbumWidget::from_instance(self) + self.imp() .cover_btn .connect_clicked(clone!(@weak self as _self => move |_| { f(&_self); diff --git a/src/app/components/artist/mod.rs b/src/app/components/artist/mod.rs index 3d3cac04..46dd29c3 100644 --- a/src/app/components/artist/mod.rs +++ b/src/app/components/artist/mod.rs @@ -30,7 +30,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -49,7 +49,7 @@ glib::wrapper! { impl ArtistWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of ArtistWidget") + glib::Object::new() } pub fn for_model(model: &ArtistModel, worker: Worker) -> Self { @@ -59,7 +59,7 @@ impl ArtistWidget { } pub fn connect_artist_pressed(&self, f: F) { - imp::ArtistWidget::from_instance(self) + self.imp() .avatar_btn .connect_clicked(clone!(@weak self as _self => move |_| { f(&_self); @@ -67,9 +67,9 @@ impl ArtistWidget { } fn bind(&self, model: &ArtistModel, worker: Worker) { - let widget = imp::ArtistWidget::from_instance(self); + let widget = self.imp(); - if let Some(url) = model.image_url() { + if let Some(url) = model.image() { let avatar = widget.avatar.downgrade(); worker.send_local_task(async move { if let Some(avatar) = avatar.upgrade() { diff --git a/src/app/components/artist_details/artist_details.rs b/src/app/components/artist_details/artist_details.rs index 3dca44e5..3d3fdd78 100644 --- a/src/app/components/artist_details/artist_details.rs +++ b/src/app/components/artist_details/artist_details.rs @@ -35,7 +35,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -55,15 +55,11 @@ glib::wrapper! { impl ArtistDetailsWidget { fn new() -> Self { display_add_css_provider(resource!("/components/artist_details.css")); - glib::Object::new(&[]).expect("Failed to create an instance of ArtistDetailsWidget") - } - - fn widget(&self) -> &imp::ArtistDetailsWidget { - imp::ArtistDetailsWidget::from_instance(self) + glib::Object::new() } fn top_tracks_widget(&self) -> >k::ListView { - self.widget().top_tracks.as_ref() + self.imp().top_tracks.as_ref() } fn set_loaded(&self) { @@ -75,7 +71,7 @@ impl ArtistDetailsWidget { where F: Fn() + 'static, { - self.widget() + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -92,7 +88,7 @@ impl ArtistDetailsWidget { ) where F: Fn(String) + Clone + 'static, { - self.widget() + self.imp() .artist_releases .bind_model(Some(store.unsafe_store()), move |item| { let item = item.downcast_ref::().unwrap(); diff --git a/src/app/components/details/album_header.rs b/src/app/components/details/album_header.rs index cf74daf4..2d362314 100644 --- a/src/app/components/details/album_header.rs +++ b/src/app/components/details/album_header.rs @@ -42,7 +42,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -62,39 +62,35 @@ glib::wrapper! { impl AlbumHeaderWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of AlbumHeaderWidget") - } - - pub fn widget(&self) -> &imp::AlbumHeaderWidget { - imp::AlbumHeaderWidget::from_instance(self) + glib::Object::new() } pub fn connect_liked(&self, f: F) where F: Fn() + 'static, { - self.widget().like_button.connect_clicked(move |_| f()); + self.imp().like_button.connect_clicked(move |_| f()); } pub fn connect_info(&self, f: F) where F: Fn() + 'static, { - self.widget().info_button.connect_clicked(move |_| f()); + self.imp().info_button.connect_clicked(move |_| f()); } pub fn connect_artist_clicked(&self, f: F) where F: Fn() + 'static, { - self.widget().artist_button.connect_activate_link(move |_| { + self.imp().artist_button.connect_activate_link(move |_| { f(); glib::signal::Inhibit(true) }); } pub fn set_liked(&self, is_liked: bool) { - self.widget().like_button.set_icon_name(if is_liked { + self.imp().like_button.set_icon_name(if is_liked { "starred-symbolic" } else { "non-starred-symbolic" @@ -102,11 +98,11 @@ impl AlbumHeaderWidget { } pub fn set_artwork(&self, art: &gdk_pixbuf::Pixbuf) { - self.widget().album_art.set_from_pixbuf(Some(art)); + self.imp().album_art.set_from_pixbuf(Some(art)); } pub fn set_album_and_artist_and_year(&self, album: &str, artist: &str, year: Option) { - let widget = self.widget(); + let widget = self.imp(); widget.album_label.set_label(album); widget.artist_button_label.set_label(artist); match year { @@ -116,7 +112,7 @@ impl AlbumHeaderWidget { } pub fn set_centered(&self) { - let widget = self.widget(); + let widget = self.imp(); widget.album_label.set_halign(gtk::Align::Center); widget.album_label.set_justify(gtk::Justification::Center); widget.artist_button.set_halign(gtk::Align::Center); @@ -124,7 +120,7 @@ impl AlbumHeaderWidget { } pub fn hide_actions(&self) { - self.widget().like_button.set_visible(false); - self.widget().info_button.set_visible(false); + self.imp().like_button.set_visible(false); + self.imp().info_button.set_visible(false); } } diff --git a/src/app/components/details/details.rs b/src/app/components/details/details.rs index fcb36c33..501aa0bf 100644 --- a/src/app/components/details/details.rs +++ b/src/app/components/details/details.rs @@ -49,7 +49,7 @@ mod imp { type ParentType = libadwaita::Bin; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -58,8 +58,8 @@ mod imp { } impl ObjectImpl for AlbumDetailsWidget { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); self.header_mobile.set_centered(); self.headerbar.add_classes(&["details__headerbar"]); } @@ -75,15 +75,11 @@ glib::wrapper! { impl AlbumDetailsWidget { fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of AlbumDetailsWidget") - } - - fn widget(&self) -> &imp::AlbumDetailsWidget { - imp::AlbumDetailsWidget::from_instance(self) + glib::Object::new() } fn set_header_visible(&self, visible: bool) -> bool { - let widget = self.widget(); + let widget = self.imp(); let is_up_to_date = widget.header_revealer.reveals_child() == visible; if !is_up_to_date { widget.header_revealer.set_reveal_child(visible); @@ -117,17 +113,15 @@ impl AlbumDetailsWidget { _self.set_header_visible(visible); })); - self.widget() - .scrolled_window - .add_controller(&scroll_controller); - self.add_controller(&swipe_controller); + self.imp().scrolled_window.add_controller(scroll_controller); + self.add_controller(swipe_controller); } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - self.widget() + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -137,11 +131,11 @@ impl AlbumDetailsWidget { } fn headerbar_widget(&self) -> &HeaderBarWidget { - self.widget().headerbar.as_ref() + self.imp().headerbar.as_ref() } fn album_tracks_widget(&self) -> >k::ListView { - self.widget().album_tracks.as_ref() + self.imp().album_tracks.as_ref() } fn set_loaded(&self) { @@ -153,48 +147,44 @@ impl AlbumDetailsWidget { where F: Fn() + Clone + 'static, { - self.widget().header_widget.connect_liked(f.clone()); - self.widget().header_mobile.connect_liked(f); + self.imp().header_widget.connect_liked(f.clone()); + self.imp().header_mobile.connect_liked(f); } fn connect_info(&self, f: F) where F: Fn() + Clone + 'static, { - self.widget().header_widget.connect_info(f.clone()); - self.widget().header_mobile.connect_info(f); + self.imp().header_widget.connect_info(f.clone()); + self.imp().header_mobile.connect_info(f); } fn set_liked(&self, is_liked: bool) { - self.widget().header_widget.set_liked(is_liked); - self.widget().header_mobile.set_liked(is_liked); + self.imp().header_widget.set_liked(is_liked); + self.imp().header_mobile.set_liked(is_liked); } fn set_album_and_artist_and_year(&self, album: &str, artist: &str, year: Option) { - self.widget() + self.imp() .header_widget .set_album_and_artist_and_year(album, artist, year); - self.widget() + self.imp() .header_mobile .set_album_and_artist_and_year(album, artist, year); - self.widget() - .headerbar - .set_title_and_subtitle(album, artist); + self.imp().headerbar.set_title_and_subtitle(album, artist); } fn set_artwork(&self, art: &gdk_pixbuf::Pixbuf) { - self.widget().header_widget.set_artwork(art); - self.widget().header_mobile.set_artwork(art); + self.imp().header_widget.set_artwork(art); + self.imp().header_mobile.set_artwork(art); } fn connect_artist_clicked(&self, f: F) where F: Fn() + Clone + 'static, { - self.widget() - .header_widget - .connect_artist_clicked(f.clone()); - self.widget().header_mobile.connect_artist_clicked(f); + self.imp().header_widget.connect_artist_clicked(f.clone()); + self.imp().header_mobile.connect_artist_clicked(f); } } diff --git a/src/app/components/details/release_details.rs b/src/app/components/details/release_details.rs index 4226a433..ee54aea0 100644 --- a/src/app/components/details/release_details.rs +++ b/src/app/components/details/release_details.rs @@ -1,4 +1,3 @@ -use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::CompositeTemplate; use libadwaita::subclass::prelude::*; @@ -35,7 +34,7 @@ mod imp { type ParentType = libadwaita::Window; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -44,8 +43,8 @@ mod imp { } impl ObjectImpl for ReleaseDetailsWindow { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); } } @@ -60,11 +59,7 @@ glib::wrapper! { impl ReleaseDetailsWindow { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of ReleaseDetailsWindow") - } - - fn widget(&self) -> &imp::ReleaseDetailsWindow { - imp::ReleaseDetailsWindow::from_instance(self) + glib::Object::new() } #[allow(clippy::too_many_arguments)] @@ -77,7 +72,7 @@ impl ReleaseDetailsWindow { track_count: usize, copyright: &str, ) { - let widget = self.widget(); + let widget = self.imp(); widget .album_artist diff --git a/src/app/components/headerbar/widget.rs b/src/app/components/headerbar/widget.rs index 2b90a0b6..7ce34197 100644 --- a/src/app/components/headerbar/widget.rs +++ b/src/app/components/headerbar/widget.rs @@ -48,7 +48,7 @@ mod imp { type Interfaces = (gtk::Buildable,); fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -59,15 +59,9 @@ mod imp { impl ObjectImpl for HeaderBarWidget {} impl BuildableImpl for HeaderBarWidget { - fn add_child( - &self, - buildable: &Self::Type, - builder: >k::Builder, - child: &glib::Object, - type_: Option<&str>, - ) { + fn add_child(&self, builder: >k::Builder, child: &glib::Object, type_: Option<&str>) { if Some("root") == type_ { - self.parent_add_child(buildable, builder, child, type_); + self.parent_add_child(builder, child, type_); } else { self.main_header .set_title_widget(child.downcast_ref::()); @@ -86,46 +80,42 @@ glib::wrapper! { impl HeaderBarWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of HeaderBarWidget") - } - - fn widget(&self) -> &imp::HeaderBarWidget { - imp::HeaderBarWidget::from_instance(self) + glib::Object::new() } pub fn connect_selection_start(&self, f: F) where F: Fn() + 'static, { - self.widget().start_selection.connect_clicked(move |_| f()); + self.imp().start_selection.connect_clicked(move |_| f()); } pub fn connect_select_all(&self, f: F) where F: Fn() + 'static, { - self.widget().select_all.connect_clicked(move |_| f()); + self.imp().select_all.connect_clicked(move |_| f()); } pub fn connect_selection_cancel(&self, f: F) where F: Fn() + 'static, { - self.widget().cancel.connect_clicked(move |_| f()); + self.imp().cancel.connect_clicked(move |_| f()); } pub fn connect_go_back(&self, f: F) where F: Fn() + 'static, { - self.widget().go_back.connect_clicked(move |_| f()); + self.imp().go_back.connect_clicked(move |_| f()); } pub fn bind_to_leaflet(&self, leaflet: &libadwaita::Leaflet) { leaflet .bind_property( "folded", - &*self.widget().main_header, + &*self.imp().main_header, "show-start-title-buttons", ) .build(); @@ -133,63 +123,63 @@ impl HeaderBarWidget { } pub fn set_can_go_back(&self, can_go_back: bool) { - self.widget().go_back.set_visible(can_go_back); + self.imp().go_back.set_visible(can_go_back); } pub fn set_selection_possible(&self, possible: bool) { - self.widget().start_selection.set_visible(possible); + self.imp().start_selection.set_visible(possible); } pub fn set_select_all_possible(&self, possible: bool) { - self.widget().select_all.set_visible(possible); + self.imp().select_all.set_visible(possible); } pub fn set_selection_active(&self, active: bool) { if active { - self.widget() + self.imp() .selection_title .set_title(&labels::n_songs_selected_label(0)); - self.widget().selection_title.show(); - self.widget().selection_header.show(); + self.imp().selection_title.show(); + self.imp().selection_header.show(); } else { - self.widget().selection_title.hide(); - self.widget().selection_header.hide(); + self.imp().selection_title.hide(); + self.imp().selection_header.hide(); } } pub fn set_selection_count(&self, count: usize) { - self.widget() + self.imp() .selection_title .set_title(&labels::n_songs_selected_label(count)); } pub fn add_classes(&self, classes: &[&str]) { - let context = self.widget().main_header.style_context(); + let context = self.imp().main_header.style_context(); for &class in classes { context.add_class(class); } } pub fn remove_classes(&self, classes: &[&str]) { - let context = self.widget().main_header.style_context(); + let context = self.imp().main_header.style_context(); for &class in classes { context.remove_class(class); } } pub fn set_title_visible(&self, visible: bool) { - self.widget().title.set_visible(visible); + self.imp().title.set_visible(visible); } pub fn set_title_and_subtitle(&self, title: &str, subtitle: &str) { - self.widget().title.set_title(title); - self.widget().title.set_subtitle(subtitle); + self.imp().title.set_title(title); + self.imp().title.set_subtitle(subtitle); } pub fn set_title(&self, title: Option<&str>) { - self.widget().title.set_visible(title.is_some()); + self.imp().title.set_visible(title.is_some()); if let Some(title) = title { - self.widget().title.set_title(title); + self.imp().title.set_title(title); } } } diff --git a/src/app/components/library/library.rs b/src/app/components/library/library.rs index 304eabba..74923a54 100644 --- a/src/app/components/library/library.rs +++ b/src/app/components/library/library.rs @@ -35,7 +35,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -54,14 +54,14 @@ glib::wrapper! { impl LibraryWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of LibraryWidget") + glib::Object::new() } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - imp::LibraryWidget::from_instance(self) + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -74,9 +74,9 @@ impl LibraryWidget { where F: Fn(String) + Clone + 'static, { - imp::LibraryWidget::from_instance(self).flowbox.bind_model( - Some(store.unsafe_store()), - move |item| { + self.imp() + .flowbox + .bind_model(Some(store.unsafe_store()), move |item| { wrap_flowbox_item(item, |album_model| { let f = on_album_pressed.clone(); let album = AlbumWidget::for_model(album_model, worker.clone()); @@ -85,12 +85,11 @@ impl LibraryWidget { })); album }) - }, - ); + }); } pub fn status_page(&self) -> &libadwaita::StatusPage { - &imp::LibraryWidget::from_instance(self).status_page + &self.imp().status_page } } diff --git a/src/app/components/login/login.rs b/src/app/components/login/login.rs index ae6e4a29..6e2c3f1a 100644 --- a/src/app/components/login/login.rs +++ b/src/app/components/login/login.rs @@ -22,7 +22,7 @@ mod imp { pub username: TemplateChild, #[template_child] - pub password: TemplateChild, + pub password: TemplateChild, #[template_child] pub close_button: TemplateChild, @@ -41,7 +41,7 @@ mod imp { type ParentType = libadwaita::Window; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -61,15 +61,14 @@ glib::wrapper! { impl LoginWindow { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of LoginWindow") + glib::Object::new() } fn connect_close(&self, on_close: F) where F: Fn() + 'static, { - let widget = imp::LoginWindow::from_instance(self); - widget.close_button.connect_clicked(move |_| { + self.imp().close_button.connect_clicked(move |_| { on_close(); }); } @@ -78,8 +77,6 @@ impl LoginWindow { where SubmitFn: Fn(&str, &str) + Clone + 'static, { - let widget = imp::LoginWindow::from_instance(self); - let on_submit_clone = on_submit.clone(); let controller = gtk::EventControllerKey::new(); controller.set_propagation_phase(gtk::PropagationPhase::Capture); @@ -93,9 +90,9 @@ impl LoginWindow { } }), ); - self.add_controller(&controller); + self.add_controller(controller); - widget + self.imp() .login_button .connect_clicked(clone!(@weak self as _self => move |_| { _self.submit(&on_submit); @@ -103,7 +100,7 @@ impl LoginWindow { } fn show_auth_error(&self, shown: bool) { - let widget = imp::LoginWindow::from_instance(self); + let widget = self.imp(); widget.auth_error_container.set_reveal_child(shown); } @@ -111,7 +108,7 @@ impl LoginWindow { where SubmitFn: Fn(&str, &str), { - let widget = imp::LoginWindow::from_instance(self); + let widget = self.imp(); self.show_auth_error(false); diff --git a/src/app/components/navigation/home.rs b/src/app/components/navigation/home.rs index 313404e2..61422e6a 100644 --- a/src/app/components/navigation/home.rs +++ b/src/app/components/navigation/home.rs @@ -27,7 +27,7 @@ fn add_to_stack_and_listbox( } fn make_playlist_item(playlist_item: AlbumModel) -> SideBarItem { - let mut title = playlist_item.album_title(); + let mut title = playlist_item.album(); if title.is_empty() { title = gettext("Unnamed playlist"); } diff --git a/src/app/components/notification/mod.rs b/src/app/components/notification/mod.rs index becb9848..da105772 100644 --- a/src/app/components/notification/mod.rs +++ b/src/app/components/notification/mod.rs @@ -15,7 +15,7 @@ impl Notification { .title(content) .timeout(4) .build(); - self.toast_overlay.add_toast(&toast); + self.toast_overlay.add_toast(toast); } } diff --git a/src/app/components/now_playing/now_playing.rs b/src/app/components/now_playing/now_playing.rs index 17f119da..c487983e 100644 --- a/src/app/components/now_playing/now_playing.rs +++ b/src/app/components/now_playing/now_playing.rs @@ -29,7 +29,7 @@ mod imp { type ParentType = libadwaita::Bin; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -48,14 +48,14 @@ glib::wrapper! { impl NowPlayingWidget { fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of NowPlayingWidget") + glib::Object::new() } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - imp::NowPlayingWidget::from_instance(self) + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -65,9 +65,7 @@ impl NowPlayingWidget { } fn song_list_widget(&self) -> >k::ListView { - imp::NowPlayingWidget::from_instance(self) - .song_list - .as_ref() + self.imp().song_list.as_ref() } } diff --git a/src/app/components/playback/playback_controls.rs b/src/app/components/playback/playback_controls.rs index 6038f99a..613626bc 100644 --- a/src/app/components/playback/playback_controls.rs +++ b/src/app/components/playback/playback_controls.rs @@ -35,7 +35,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -67,16 +67,13 @@ impl PlaybackControlsWidget { }; let tooltip_text = Some(translated_tooltip.as_str()); - let playback_control = imp::PlaybackControlsWidget::from_instance(self); - + let playback_control = self.imp(); playback_control.play_pause.set_icon_name(playback_icon); playback_control.play_pause.set_tooltip_text(tooltip_text); } pub fn set_shuffled(&self, shuffled: bool) { - imp::PlaybackControlsWidget::from_instance(self) - .shuffle - .set_active(shuffled); + self.imp().shuffle.set_active(shuffled); } pub fn set_repeat_mode(&self, mode: RepeatMode) { @@ -86,53 +83,41 @@ impl PlaybackControlsWidget { RepeatMode::None => "media-playlist-consecutive-symbolic", }; - imp::PlaybackControlsWidget::from_instance(self) - .repeat - .set_icon_name(repeat_mode_icon); + self.imp().repeat.set_icon_name(repeat_mode_icon); } pub fn connect_play_pause(&self, f: F) where F: Fn() + 'static, { - imp::PlaybackControlsWidget::from_instance(self) - .play_pause - .connect_clicked(move |_| f()); + self.imp().play_pause.connect_clicked(move |_| f()); } pub fn connect_prev(&self, f: F) where F: Fn() + 'static, { - imp::PlaybackControlsWidget::from_instance(self) - .prev - .connect_clicked(move |_| f()); + self.imp().prev.connect_clicked(move |_| f()); } pub fn connect_next(&self, f: F) where F: Fn() + 'static, { - imp::PlaybackControlsWidget::from_instance(self) - .next - .connect_clicked(move |_| f()); + self.imp().next.connect_clicked(move |_| f()); } pub fn connect_shuffle(&self, f: F) where F: Fn() + 'static, { - imp::PlaybackControlsWidget::from_instance(self) - .shuffle - .connect_clicked(move |_| f()); + self.imp().shuffle.connect_clicked(move |_| f()); } pub fn connect_repeat(&self, f: F) where F: Fn() + 'static, { - imp::PlaybackControlsWidget::from_instance(self) - .repeat - .connect_clicked(move |_| f()); + self.imp().repeat.connect_clicked(move |_| f()); } } diff --git a/src/app/components/playback/playback_info.rs b/src/app/components/playback/playback_info.rs index a6d4dff6..f18e8813 100644 --- a/src/app/components/playback/playback_info.rs +++ b/src/app/components/playback/playback_info.rs @@ -24,7 +24,7 @@ mod imp { type ParentType = gtk::Button; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -43,7 +43,7 @@ glib::wrapper! { impl PlaybackInfoWidget { pub fn set_title_and_artist(&self, title: &str, artist: &str) { - let widget = imp::PlaybackInfoWidget::from_instance(self); + let widget = self.imp(); let title = glib::markup_escape_text(title); let artist = glib::markup_escape_text(artist); let label = format!("{}\n{}", title.as_str(), artist.as_str()); @@ -51,7 +51,7 @@ impl PlaybackInfoWidget { } pub fn reset_info(&self) { - let widget = imp::PlaybackInfoWidget::from_instance(self); + let widget = self.imp(); widget .current_song_info // translators: Short text displayed instead of a song title when nothing plays @@ -65,14 +65,10 @@ impl PlaybackInfoWidget { } pub fn set_info_visible(&self, visible: bool) { - imp::PlaybackInfoWidget::from_instance(self) - .current_song_info - .set_visible(visible); + self.imp().current_song_info.set_visible(visible); } pub fn set_artwork(&self, art: &gdk_pixbuf::Pixbuf) { - imp::PlaybackInfoWidget::from_instance(self) - .playing_image - .set_from_pixbuf(Some(art)); + self.imp().playing_image.set_from_pixbuf(Some(art)); } } diff --git a/src/app/components/playback/playback_widget.rs b/src/app/components/playback/playback_widget.rs index 073b1431..ff2410aa 100644 --- a/src/app/components/playback/playback_widget.rs +++ b/src/app/components/playback/playback_widget.rs @@ -49,7 +49,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -58,8 +58,8 @@ mod imp { } impl ObjectImpl for PlaybackWidget { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); self.now_playing_mobile.set_info_visible(false); self.now_playing.set_info_visible(true); display_add_css_provider(resource!("/components/playback.css")); @@ -76,19 +76,19 @@ glib::wrapper! { impl PlaybackWidget { pub fn set_title_and_artist(&self, title: &str, artist: &str) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.now_playing.set_title_and_artist(title, artist); } pub fn reset_info(&self) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.now_playing.reset_info(); widget.now_playing_mobile.reset_info(); self.set_song_duration(None); } fn set_artwork(&self, image: &gdk_pixbuf::Pixbuf) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.now_playing.set_artwork(image); widget.now_playing_mobile.set_artwork(image); } @@ -105,7 +105,7 @@ impl PlaybackWidget { } pub fn set_song_duration(&self, duration: Option) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); let class = "seek-bar--active"; let style_context = widget.seek_bar.style_context(); if let Some(duration) = duration { @@ -127,13 +127,13 @@ impl PlaybackWidget { } pub fn set_seek_position(&self, pos: f64) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.seek_bar.set_value(pos); widget.track_position.set_text(&format_duration(pos)); } pub fn increment_seek_position(&self) { - let value = imp::PlaybackWidget::from_instance(self).seek_bar.value() + 1_000.0; + let value = self.imp().seek_bar.value() + 1_000.0; self.set_seek_position(value); } @@ -141,7 +141,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); let f_clone = f.clone(); widget.now_playing.connect_clicked(move |_| f_clone()); widget.now_playing_mobile.connect_clicked(move |_| f()); @@ -152,11 +152,11 @@ impl PlaybackWidget { Seek: Fn(u32) + Clone + 'static, { let debouncer = Debouncer::new(); - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.seek_bar.set_increments(5_000.0, 10_000.0); widget.seek_bar.connect_change_value( clone!(@weak self as _self => @default-return glib::signal::Inhibit(false), move |_, _, requested| { - imp::PlaybackWidget::from_instance(&_self) + _self.imp() .track_position .set_text(&format_duration(requested)); let seek = seek.clone(); @@ -167,7 +167,7 @@ impl PlaybackWidget { } pub fn set_playing(&self, is_playing: bool) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.set_playing(is_playing); widget.controls_mobile.set_playing(is_playing); if is_playing { @@ -180,19 +180,19 @@ impl PlaybackWidget { } pub fn set_repeat_mode(&self, mode: RepeatMode) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.set_repeat_mode(mode); widget.controls_mobile.set_repeat_mode(mode); } pub fn set_shuffled(&self, shuffled: bool) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.set_shuffled(shuffled); widget.controls_mobile.set_shuffled(shuffled); } pub fn set_seekbar_visible(&self, visible: bool) { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.seek_bar.set_visible(visible); } @@ -200,7 +200,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.connect_play_pause(f.clone()); widget.controls_mobile.connect_play_pause(f); } @@ -209,7 +209,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.connect_prev(f.clone()); widget.controls_mobile.connect_prev(f); } @@ -218,7 +218,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.connect_next(f.clone()); widget.controls_mobile.connect_next(f); } @@ -227,7 +227,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.connect_shuffle(f.clone()); widget.controls_mobile.connect_shuffle(f); } @@ -236,7 +236,7 @@ impl PlaybackWidget { where F: Fn() + Clone + 'static, { - let widget = imp::PlaybackWidget::from_instance(self); + let widget = self.imp(); widget.controls.connect_repeat(f.clone()); widget.controls_mobile.connect_repeat(f); } diff --git a/src/app/components/playlist/playlist.rs b/src/app/components/playlist/playlist.rs index 6e7434d2..bf243628 100644 --- a/src/app/components/playlist/playlist.rs +++ b/src/app/components/playlist/playlist.rs @@ -83,7 +83,7 @@ where { pub fn new(listview: gtk::ListView, model: Rc, worker: Worker) -> Self { let list_model = model.song_list_model(); - let selection_model = gtk::NoSelection::new(Some(&list_model)); + let selection_model = gtk::NoSelection::new(Some(list_model.clone())); let factory = gtk::SignalListItemFactory::new(); let style_context = listview.style_context(); @@ -129,12 +129,12 @@ where })); let press_gesture = gtk::GestureLongPress::new(); - listview.add_controller(&press_gesture); press_gesture.set_touch_only(false); press_gesture.set_propagation_phase(gtk::PropagationPhase::Capture); press_gesture.connect_pressed(clone!(@weak model => move |_, _, _| { model.enable_selection(); })); + listview.add_controller(press_gesture.clone()); //FIXME Self { animator: AnimatorDefault::ease_in_out_animator(), diff --git a/src/app/components/playlist/song.rs b/src/app/components/playlist/song.rs index c37a8f96..bbf19c52 100644 --- a/src/app/components/playlist/song.rs +++ b/src/app/components/playlist/song.rs @@ -4,6 +4,8 @@ use crate::app::models::SongModel; use crate::app::Worker; use gio::MenuModel; +use glib::subclass::InitializingObject; + use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::CompositeTemplate; @@ -49,30 +51,18 @@ mod imp { type ParentType = gtk::Grid; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } - fn instance_init(obj: &glib::subclass::InitializingObject) { + fn instance_init(obj: &InitializingObject) { obj.init_template(); } } lazy_static! { static ref PROPERTIES: [glib::ParamSpec; 2] = [ - glib::ParamSpecBoolean::new( - "playing", - "Playing", - "", - false, - glib::ParamFlags::READWRITE - ), - glib::ParamSpecBoolean::new( - "selected", - "Selected", - "", - false, - glib::ParamFlags::READWRITE, - ), + glib::ParamSpecBoolean::builder("playing").build(), + glib::ParamSpecBoolean::builder("selected").build() ]; } @@ -81,19 +71,13 @@ mod imp { &*PROPERTIES } - fn set_property( - &self, - obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { + fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { match pspec.name() { "playing" => { let is_playing = value .get() .expect("type conformity checked by `Object::set_property`"); - let context = obj.style_context(); + let context = self.obj().style_context(); if is_playing { context.add_class(SONG_CLASS); } else { @@ -110,21 +94,21 @@ mod imp { } } - fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.name() { - "playing" => obj.style_context().has_class(SONG_CLASS).to_value(), + "playing" => self.obj().style_context().has_class(SONG_CLASS).to_value(), "selected" => self.song_checkbox.is_active().to_value(), _ => unimplemented!(), } } - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); self.song_checkbox.set_sensitive(false); } - fn dispose(&self, obj: &Self::Type) { - while let Some(child) = obj.first_child() { + fn dispose(&self) { + while let Some(child) = self.obj().first_child() { child.unparent(); } } @@ -141,11 +125,7 @@ glib::wrapper! { impl SongWidget { pub fn new() -> Self { display_add_css_provider(resource!("/components/song.css")); - glib::Object::new(&[]).expect("Failed to create an instance of SongWidget") - } - - fn widget(&self) -> &imp::SongWidget { - imp::SongWidget::from_instance(self) + glib::Object::new() } pub fn set_actions(&self, actions: Option<&gio::ActionGroup>) { @@ -154,7 +134,7 @@ impl SongWidget { pub fn set_menu(&self, menu: Option<&MenuModel>) { if menu.is_some() { - let widget = self.widget(); + let widget = self.imp(); widget.menu_btn.set_menu_model(menu); widget .menu_btn @@ -174,7 +154,7 @@ impl SongWidget { } fn set_image(&self, pixbuf: Option<&gdk_pixbuf::Pixbuf>) { - self.widget().song_cover.set_from_pixbuf(pixbuf); + self.imp().song_cover.set_from_pixbuf(pixbuf); } pub fn set_art(&self, model: &SongModel, worker: Worker) { @@ -191,7 +171,7 @@ impl SongWidget { } pub fn bind(&self, model: &SongModel, worker: Worker, show_cover: bool) { - let widget = self.widget(); + let widget = self.imp(); model.bind_title(&*widget.song_title, "label"); model.bind_artist(&*widget.song_artist, "label"); diff --git a/src/app/components/playlist_details/playlist_details.rs b/src/app/components/playlist_details/playlist_details.rs index ad78c4f5..0628da5e 100644 --- a/src/app/components/playlist_details/playlist_details.rs +++ b/src/app/components/playlist_details/playlist_details.rs @@ -42,7 +42,7 @@ mod imp { type ParentType = libadwaita::Bin; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -51,8 +51,8 @@ mod imp { } impl ObjectImpl for PlaylistDetailsWidget { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); self.header_mobile.set_centered(); self.header_mobile.hide_actions(); self.header_widget.hide_actions(); @@ -69,22 +69,18 @@ glib::wrapper! { impl PlaylistDetailsWidget { fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of PlaylistDetailsWidget") - } - - fn widget(&self) -> &imp::PlaylistDetailsWidget { - imp::PlaylistDetailsWidget::from_instance(self) + glib::Object::new() } fn playlist_tracks_widget(&self) -> >k::ListView { - self.widget().tracks.as_ref() + self.imp().tracks.as_ref() } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - self.widget() + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -94,7 +90,7 @@ impl PlaylistDetailsWidget { } fn set_header_visible(&self, visible: bool) -> bool { - let widget = self.widget(); + let widget = self.imp(); let is_up_to_date = widget.header_revealer.reveals_child() == visible; if !is_up_to_date { widget.header_revealer.set_reveal_child(visible); @@ -113,8 +109,8 @@ impl PlaylistDetailsWidget { }), ); - let widget = self.widget(); - widget.scrolled_window.add_controller(&scroll_controller); + let widget = self.imp(); + widget.scrolled_window.add_controller(scroll_controller); } fn set_loaded(&self) { @@ -123,27 +119,25 @@ impl PlaylistDetailsWidget { } fn set_album_and_artist(&self, album: &str, artist: &str) { - self.widget() + self.imp() .header_widget .set_album_and_artist_and_year(album, artist, None); - self.widget() + self.imp() .header_mobile .set_album_and_artist_and_year(album, artist, None); } fn set_artwork(&self, art: &gdk_pixbuf::Pixbuf) { - self.widget().header_widget.set_artwork(art); - self.widget().header_mobile.set_artwork(art); + self.imp().header_widget.set_artwork(art); + self.imp().header_mobile.set_artwork(art); } fn connect_artist_clicked(&self, f: F) where F: Fn() + Clone + 'static, { - self.widget() - .header_widget - .connect_artist_clicked(f.clone()); - self.widget().header_mobile.connect_artist_clicked(f); + self.imp().header_widget.connect_artist_clicked(f.clone()); + self.imp().header_mobile.connect_artist_clicked(f); } } diff --git a/src/app/components/saved_playlists/saved_playlists.rs b/src/app/components/saved_playlists/saved_playlists.rs index d496d472..6b5fdcde 100644 --- a/src/app/components/saved_playlists/saved_playlists.rs +++ b/src/app/components/saved_playlists/saved_playlists.rs @@ -33,7 +33,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -52,14 +52,14 @@ glib::wrapper! { impl SavedPlaylistsWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of SavedPlaylistsWidget") + glib::Object::new() } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - imp::SavedPlaylistsWidget::from_instance(self) + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -72,7 +72,7 @@ impl SavedPlaylistsWidget { where F: Fn(String) + Clone + 'static, { - imp::SavedPlaylistsWidget::from_instance(self) + self.imp() .flowbox .bind_model(Some(store.unsafe_store()), move |item| { let album_model = item.downcast_ref::().unwrap(); @@ -89,7 +89,7 @@ impl SavedPlaylistsWidget { }); } pub fn get_status_page(&self) -> &libadwaita::StatusPage { - &imp::SavedPlaylistsWidget::from_instance(self).status_page + &self.imp().status_page } } diff --git a/src/app/components/saved_tracks/saved_tracks.rs b/src/app/components/saved_tracks/saved_tracks.rs index 76f8881a..715ac28b 100644 --- a/src/app/components/saved_tracks/saved_tracks.rs +++ b/src/app/components/saved_tracks/saved_tracks.rs @@ -30,7 +30,7 @@ mod imp { type ParentType = libadwaita::Bin; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -49,14 +49,14 @@ glib::wrapper! { impl SavedTracksWidget { fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of SavedTracksWidget") + glib::Object::new() } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - imp::SavedTracksWidget::from_instance(self) + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -66,9 +66,7 @@ impl SavedTracksWidget { } fn song_list_widget(&self) -> >k::ListView { - imp::SavedTracksWidget::from_instance(self) - .song_list - .as_ref() + self.imp().song_list.as_ref() } } diff --git a/src/app/components/search/search.rs b/src/app/components/search/search.rs index 46d516e4..7f2c6671 100644 --- a/src/app/components/search/search.rs +++ b/src/app/components/search/search.rs @@ -46,7 +46,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -58,7 +58,7 @@ mod imp { impl BoxImpl for SearchResultsWidget {} impl WidgetImpl for SearchResultsWidget { - fn grab_focus(&self, _: &Self::Type) -> bool { + fn grab_focus(&self) -> bool { self.search_entry.grab_focus() } } @@ -70,18 +70,14 @@ glib::wrapper! { impl SearchResultsWidget { pub fn new() -> Self { - glib::Object::new(&[]).expect("Failed to create an instance of SearchResultsWidget") - } - - fn widget(&self) -> &imp::SearchResultsWidget { - imp::SearchResultsWidget::from_instance(self) + glib::Object::new() } pub fn bind_to_leaflet(&self, leaflet: &libadwaita::Leaflet) { leaflet .bind_property( "folded", - &*self.widget().main_header, + &*self.imp().main_header, "show-start-title-buttons", ) .build(); @@ -92,20 +88,20 @@ impl SearchResultsWidget { where F: Fn() + 'static, { - self.widget().go_back.connect_clicked(move |_| f()); + self.imp().go_back.connect_clicked(move |_| f()); } pub fn connect_search_updated(&self, f: F) where F: Fn(String) + 'static, { - self.widget() + self.imp() .search_entry .connect_changed(clone!(@weak self as _self => move |s| { let query = s.text(); let query = query.as_str(); - _self.widget().status_page.set_visible(query.is_empty()); - _self.widget().search_results.set_visible(!query.is_empty()); + _self.imp().status_page.set_visible(query.is_empty()); + _self.imp().search_results.set_visible(!query.is_empty()); if !query.is_empty() { f(query.to_string()); } @@ -116,7 +112,7 @@ impl SearchResultsWidget { where F: Fn(String) + Clone + 'static, { - self.widget() + self.imp() .albums_results .bind_model(Some(store), move |item| { wrap_flowbox_item(item, |album_model| { @@ -134,7 +130,7 @@ impl SearchResultsWidget { where F: Fn(String) + Clone + 'static, { - self.widget() + self.imp() .artist_results .bind_model(Some(store), move |item| { wrap_flowbox_item(item, |artist_model| { diff --git a/src/app/components/selection/widget.rs b/src/app/components/selection/widget.rs index 7f3c9f66..9a1ae8dc 100644 --- a/src/app/components/selection/widget.rs +++ b/src/app/components/selection/widget.rs @@ -43,7 +43,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -52,8 +52,8 @@ mod imp { } impl ObjectImpl for SelectionToolbarWidget { - fn constructed(&self, obj: &Self::Type) { - self.parent_constructed(obj); + fn constructed(&self) { + self.parent_constructed(); display_add_css_provider(resource!("/components/selection_toolbar.css")); } } @@ -83,75 +83,71 @@ impl SelectionToolState { } impl SelectionToolbarWidget { - fn widget(&self) -> &imp::SelectionToolbarWidget { - imp::SelectionToolbarWidget::from_instance(self) - } - pub fn connect_move_down(&self, f: F) where F: Fn() + 'static, { - self.widget().move_down.connect_clicked(move |_| f()); + self.imp().move_down.connect_clicked(move |_| f()); } pub fn connect_move_up(&self, f: F) where F: Fn() + 'static, { - self.widget().move_up.connect_clicked(move |_| f()); + self.imp().move_up.connect_clicked(move |_| f()); } pub fn connect_queue(&self, f: F) where F: Fn() + 'static, { - self.widget().queue.connect_clicked(move |_| f()); + self.imp().queue.connect_clicked(move |_| f()); } pub fn connect_save(&self, f: F) where F: Fn() + 'static, { - self.widget().save.connect_clicked(move |_| f()); + self.imp().save.connect_clicked(move |_| f()); } pub fn connect_remove(&self, f: F) where F: Fn() + 'static, { - self.widget().remove.connect_clicked(move |_| f()); + self.imp().remove.connect_clicked(move |_| f()); } pub fn set_move(&self, state: SelectionToolState) { - self.widget().move_up.set_sensitive(state.sensitive()); - self.widget().move_up.set_visible(state.visible()); - self.widget().move_down.set_sensitive(state.sensitive()); - self.widget().move_down.set_visible(state.visible()); + self.imp().move_up.set_sensitive(state.sensitive()); + self.imp().move_up.set_visible(state.visible()); + self.imp().move_down.set_sensitive(state.sensitive()); + self.imp().move_down.set_visible(state.visible()); } pub fn set_queue(&self, state: SelectionToolState) { - self.widget().queue.set_sensitive(state.sensitive()); - self.widget().queue.set_visible(state.visible()); + self.imp().queue.set_sensitive(state.sensitive()); + self.imp().queue.set_visible(state.visible()); } pub fn set_add(&self, state: SelectionToolState) { - self.widget().add.set_sensitive(state.sensitive()); - self.widget().add.set_visible(state.visible()); + self.imp().add.set_sensitive(state.sensitive()); + self.imp().add.set_visible(state.visible()); } pub fn set_remove(&self, state: SelectionToolState) { - self.widget().remove.set_sensitive(state.sensitive()); - self.widget().remove.set_visible(state.visible()); + self.imp().remove.set_sensitive(state.sensitive()); + self.imp().remove.set_visible(state.visible()); } pub fn set_save(&self, state: SelectionToolState) { - self.widget().save.set_sensitive(state.sensitive()); - self.widget().save.set_visible(state.visible()); + self.imp().save.set_sensitive(state.sensitive()); + self.imp().save.set_visible(state.visible()); } pub fn set_visible(&self, visible: bool) { gtk::Widget::set_visible(self.upcast_ref(), visible); - self.widget().action_bar.set_revealed(visible); + self.imp().action_bar.set_revealed(visible); } pub fn connect_playlists(&self, playlists: &[PlaylistSummary], on_playlist_selected: F) @@ -179,8 +175,8 @@ impl SelectionToolbarWidget { } let popover = gtk::PopoverMenu::from_model(Some(&menu)); - self.widget().add.set_popover(Some(&popover)); - self.widget() + self.imp().add.set_popover(Some(&popover)); + self.imp() .add .insert_action_group("add_to", Some(&action_group)); } diff --git a/src/app/components/settings/settings.rs b/src/app/components/settings/settings.rs index 63eb0644..13c1a663 100644 --- a/src/app/components/settings/settings.rs +++ b/src/app/components/settings/settings.rs @@ -45,7 +45,7 @@ mod imp { type ParentType = libadwaita::PreferencesWindow; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -66,8 +66,7 @@ glib::wrapper! { impl SettingsWindow { pub fn new() -> Self { - let window: Self = - glib::Object::new(&[]).expect("Failed to create an instance of SettingsWindow"); + let window: Self = glib::Object::new(); window.bind_backend_and_device(); window.bind_settings(); @@ -76,7 +75,7 @@ impl SettingsWindow { } fn bind_backend_and_device(&self) { - let widget = imp::SettingsWindow::from_instance(self); + let widget = self.imp(); let audio_backend = widget .audio_backend @@ -89,7 +88,7 @@ impl SettingsWindow { audio_backend .bind_property("selected", alsa_device_row, "visible") - .transform_to(|_, value| value.get::().ok().map(|u| (u == 1).to_value())) + .transform_to(|_, value: u32| Some(value == 1)) //FIXME .build(); if audio_backend.selected() == 0 { @@ -98,7 +97,7 @@ impl SettingsWindow { } fn bind_settings(&self) { - let widget = imp::SettingsWindow::from_instance(self); + let widget = self.imp(); let settings = gio::Settings::new(SETTINGS); let player_bitrate = widget @@ -182,7 +181,7 @@ impl SettingsWindow { } fn connect_theme_select(&self) { - let widget = imp::SettingsWindow::from_instance(self); + let widget = self.imp(); let theme = widget.theme.downcast_ref::().unwrap(); theme.connect_selected_notify(|theme| { let prefers_dark_theme = theme.selected() == 1; diff --git a/src/app/components/sidebar_listbox/sidebar_icon_widget.rs b/src/app/components/sidebar_listbox/sidebar_icon_widget.rs index 6be73f5b..cd9f0c7b 100644 --- a/src/app/components/sidebar_listbox/sidebar_icon_widget.rs +++ b/src/app/components/sidebar_listbox/sidebar_icon_widget.rs @@ -23,7 +23,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -32,8 +32,8 @@ mod imp { } impl ObjectImpl for SideBarItemWidgetIcon { - fn dispose(&self, obj: &Self::Type) { - while let Some(child) = obj.first_child() { + fn dispose(&self) { + while let Some(child) = self.obj().first_child() { child.unparent(); } } @@ -49,15 +49,10 @@ glib::wrapper! { impl SideBarItemWidgetIcon { pub fn new(title: &str, iconname: Option<&str>) -> Self { - let s: SideBarItemWidgetIcon = - glib::Object::new(&[]).expect("Failed to create an instance of SideBarItemWidgetIcon"); - s.widget().title.set_text(title); - s.widget().icon.set_icon_name(iconname); + let s: Self = glib::Object::new(); + s.imp().title.set_text(title); + s.imp().icon.set_icon_name(iconname); s.set_tooltip_text(Option::from(title)); s } - - pub fn widget(&self) -> &imp::SideBarItemWidgetIcon { - imp::SideBarItemWidgetIcon::from_instance(self) - } } diff --git a/src/app/components/sidebar_listbox/sidebar_item.rs b/src/app/components/sidebar_listbox/sidebar_item.rs index 270fa0d1..2d275fb0 100644 --- a/src/app/components/sidebar_listbox/sidebar_item.rs +++ b/src/app/components/sidebar_listbox/sidebar_item.rs @@ -1,45 +1,38 @@ +use glib::Properties; use gtk::prelude::*; use gtk::subclass::prelude::*; impl SideBarItem { - pub fn new(id: &str, title: &str, iconname: &str, grayedout: bool) -> SideBarItem { - glib::Object::new::(&[ - ("id", &id), - ("title", &title), - ("iconname", &iconname), - ("grayedout", &grayedout), - ]) - .expect("Failed to create") - } - - pub(crate) fn id(&self) -> String { - self.property::("id") - } - - pub(crate) fn title(&self) -> String { - self.property::("title") - } - - pub(crate) fn iconname(&self) -> String { - self.property::("iconname") - } - - pub(crate) fn grayedout(&self) -> bool { - self.property::("grayedout") + pub fn new(id: &str, title: &str, icon_name: &str, grayed_out: bool) -> SideBarItem { + glib::Object::builder() + .property("id", &id) + .property("title", &title) + .property("icon-name", &icon_name) + .property("grayed-out", &grayed_out) + .build() } } mod imp { use super::*; use gdk::cairo::glib::ParamSpec; - use std::cell::RefCell; + use std::cell::{Cell, RefCell}; + use std::convert::TryFrom; - #[derive(Debug, Default)] + #[derive(Debug, Default, Properties)] + #[properties(wrapper_type = super::SideBarItem)] pub struct SideBarItem { - pub id: RefCell>, - pub title: RefCell>, - pub iconname: RefCell>, - pub grayedout: RefCell, + #[property(get, set)] + pub id: RefCell, + + #[property(get, set)] + pub title: RefCell, + + #[property(get, set, name = "icon-name")] + pub icon_name: RefCell, + + #[property(get, set, name = "grayed-out")] + pub grayed_out: Cell, } #[glib::object_subclass] @@ -47,87 +40,19 @@ mod imp { const NAME: &'static str = "SideBarItem"; type Type = super::SideBarItem; type ParentType = glib::Object; - - fn new() -> Self { - Self { - id: RefCell::new(None), - title: RefCell::new(None), - iconname: RefCell::new(None), - grayedout: RefCell::new(false), - } - } - } - - lazy_static! { - static ref PROPERTIES: [glib::ParamSpec; 4] = [ - glib::ParamSpecString::new("id", "ID", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("title", "Title", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new( - "iconname", - "IconName", - "", - None, - glib::ParamFlags::READWRITE - ), - glib::ParamSpecBoolean::new( - "grayedout", - "GrayedOut", - "", - false, - glib::ParamFlags::READWRITE - ), - ]; } impl ObjectImpl for SideBarItem { fn properties() -> &'static [ParamSpec] { - &*PROPERTIES + Self::derived_properties() } - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { - match pspec.name() { - "id" => { - let id = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.id.replace(id); - } - "title" => { - let title = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.title.replace(title); - } - "iconname" => { - let iconname = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.iconname.replace(iconname); - } - "grayedout" => { - let grayedout = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.grayedout.replace(grayedout); - } - _ => unimplemented!(), - } + fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + self.derived_set_property(id, value, pspec); } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { - match pspec.name() { - "id" => self.id.borrow().to_value(), - "title" => self.title.borrow().to_value(), - "iconname" => self.iconname.borrow().to_value(), - "grayedout" => self.grayedout.borrow().to_value(), - _ => unimplemented!(), - } + fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + self.derived_property(id, pspec) } } } diff --git a/src/app/components/sidebar_listbox/sidebar_row.rs b/src/app/components/sidebar_listbox/sidebar_row.rs index c7d6d5c5..df92f5ce 100644 --- a/src/app/components/sidebar_listbox/sidebar_row.rs +++ b/src/app/components/sidebar_listbox/sidebar_row.rs @@ -7,40 +7,55 @@ use gtk::subclass::prelude::*; impl SideBarRow { pub fn new(item: &SideBarItem) -> SideBarRow { display_add_css_provider(resource!("/sidebar_listbox/sidebar.css")); - let id = item.id(); - let t = item.title(); - let row = - glib::Object::new::(&[("id", &id.as_str())]).expect("Failed to create"); - if item.grayedout() { - let label = gtk::Label::new(Option::from(t.as_str())); - let gtk_box = gtk::Box::new(gtk::Orientation::Horizontal, 12); - gtk_box.append(&label); - row.set_child(Option::from(>k_box)); - row.set_activatable(false); - row.set_selectable(false); - row.set_sensitive(false); - label.add_css_class("caption-heading"); - label.add_css_class("item_sidebar"); - } else { - let widget = SideBarItemWidgetIcon::new(t.as_str(), Some(item.iconname().as_str())); - row.set_child(Option::from(&widget)); - } - row + glib::Object::builder::() + .property("item", item) + .build() } pub fn id(&self) -> String { - self.property::("id") + self.item().id() } } mod imp { use super::*; use gdk::cairo::glib::ParamSpec; + use glib::Properties; use std::cell::RefCell; + use std::convert::TryFrom; - #[derive(Debug, Default)] + #[derive(Debug, Properties)] + #[properties(wrapper_type = super::SideBarRow)] pub struct SideBarRow { - pub id: RefCell>, + #[property(get, set = Self::set_item)] + pub item: RefCell, + } + + impl SideBarRow { + fn set_item(&self, item: SideBarItem) { + let t = item.title(); + let row = self.obj(); + + if item.grayed_out() { + row.set_activatable(false); + row.set_selectable(false); + row.set_sensitive(false); + + let label = gtk::Label::new(Some(t.as_str())); + label.add_css_class("caption-heading"); + label.add_css_class("item_sidebar"); + + let _box = gtk::Box::new(gtk::Orientation::Horizontal, 12); + _box.append(&label); + + row.set_child(Some(&_box)); + } else { + let child = SideBarItemWidgetIcon::new(t.as_str(), Some(item.icon_name().as_str())); + row.set_child(Some(&child)); + } + + self.item.replace(item); + } } #[glib::object_subclass] @@ -51,56 +66,29 @@ mod imp { fn new() -> Self { Self { - id: RefCell::new(None), + item: RefCell::new(glib::Object::new()), } } } - lazy_static! { - static ref PROPERTIES: [glib::ParamSpec; 1] = [glib::ParamSpecString::new( - "id", - "ID", - "", - None, - glib::ParamFlags::READWRITE - ),]; - } - impl ObjectImpl for SideBarRow { fn properties() -> &'static [ParamSpec] { - &*PROPERTIES + Self::derived_properties() } - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { - match pspec.name() { - "id" => { - let id = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.id.replace(id); - } - _ => unimplemented!(), - } + fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + self.derived_set_property(id, value, pspec); } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { - match pspec.name() { - "id" => self.id.borrow().to_value(), - _ => unimplemented!(), - } + fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + self.derived_property(id, pspec) } } impl WidgetImpl for SideBarRow {} - impl ListBoxRowImpl for SideBarRow {} } + glib::wrapper! { pub struct SideBarRow(ObjectSubclass) @extends gtk::Widget, gtk::ListBoxRow; } diff --git a/src/app/components/user_details/user_details.rs b/src/app/components/user_details/user_details.rs index 35225389..392684c5 100644 --- a/src/app/components/user_details/user_details.rs +++ b/src/app/components/user_details/user_details.rs @@ -34,7 +34,7 @@ mod imp { type ParentType = gtk::Box; fn class_init(klass: &mut Self::Class) { - Self::bind_template(klass); + klass.bind_template(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -54,24 +54,20 @@ glib::wrapper! { impl UserDetailsWidget { fn new() -> Self { display_add_css_provider(resource!("/components/user_details.css")); - glib::Object::new(&[]).expect("Failed to create an instance of UserDetailsWidget") - } - - fn widget(&self) -> &imp::UserDetailsWidget { - imp::UserDetailsWidget::from_instance(self) + glib::Object::new() } fn set_user_name(&self, name: &str) { let context = self.style_context(); context.add_class("user__loaded"); - self.widget().user_name.set_text(name); + self.imp().user_name.set_text(name); } fn connect_bottom_edge(&self, f: F) where F: Fn() + 'static, { - self.widget() + self.imp() .scrolled_window .connect_edge_reached(move |_, pos| { if let gtk::PositionType::Bottom = pos { @@ -84,7 +80,7 @@ impl UserDetailsWidget { where F: Fn(String) + Clone + 'static, { - self.widget() + self.imp() .user_playlists .bind_model(Some(store.unsafe_store()), move |item| { wrap_flowbox_item(item, |item: &AlbumModel| { diff --git a/src/app/models/album_model.rs b/src/app/models/album_model.rs index d7b932ff..9ebbd55a 100644 --- a/src/app/models/album_model.rs +++ b/src/app/models/album_model.rs @@ -2,13 +2,12 @@ use gio::prelude::*; use glib::subclass::prelude::*; +use glib::Properties; glib::wrapper! { pub struct AlbumModel(ObjectSubclass); } -// Constructor for new instances. This simply calls glib::Object::new() with -// initial values for our two properties and then returns the new instance impl AlbumModel { pub fn new( artist: &String, @@ -18,33 +17,13 @@ impl AlbumModel { uri: &String, ) -> AlbumModel { let year = &year.unwrap_or(0); - glib::Object::new::(&[ - ("artist", artist), - ("album", album), - ("year", year), - ("cover", &cover), - ("uri", uri), - ]) - .expect("Failed to create") - } - - pub fn year(&self) -> Option { - match self.property::("year") { - 0 => None, - year => Some(year), - } - } - - pub fn cover_url(&self) -> Option { - self.property("cover") - } - - pub fn uri(&self) -> String { - self.property("uri") - } - - pub fn album_title(&self) -> String { - self.property("album") + glib::Object::builder() + .property("artist", artist) + .property("album", album) + .property("year", year) + .property("cover", &cover) + .property("uri", uri) + .build() } } @@ -53,105 +32,41 @@ mod imp { use super::*; use std::cell::{Cell, RefCell}; + use std::convert::TryFrom; - // Static array for defining the properties of the new type. - lazy_static! { - static ref PROPERTIES: [glib::ParamSpec; 5] = [ - glib::ParamSpecString::new("artist", "Artist", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("album", "Album", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecUInt::new("year", "Year", "", 0, 9999, 0, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("cover", "Cover", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("uri", "URI", "", None, glib::ParamFlags::READWRITE), - ]; - } - - // This is the struct containing all state carried with - // the new type. Generally this has to make use of - // interior mutability. - #[derive(Default)] + #[derive(Default, Properties)] + #[properties(wrapper_type = super::AlbumModel)] pub struct AlbumModel { + #[property(get, set)] album: RefCell, + #[property(get, set)] artist: RefCell, + #[property(get, set)] year: Cell, + #[property(get, set)] cover: RefCell>, + #[property(get, set)] uri: RefCell, } - // ObjectSubclass is the trait that defines the new type and - // contains all information needed by the GObject type system, - // including the new type's name, parent type, etc. #[glib::object_subclass] impl ObjectSubclass for AlbumModel { - // This type name must be unique per process. const NAME: &'static str = "AlbumModel"; - type Type = super::AlbumModel; - - // The parent type this one is inheriting from. type ParentType = glib::Object; } - // Trait that is used to override virtual methods of glib::Object. impl ObjectImpl for AlbumModel { fn properties() -> &'static [glib::ParamSpec] { - &*PROPERTIES + Self::derived_properties() } - // Called whenever a property is set on this instance. The id - // is the same as the index of the property in the PROPERTIES array. - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { - match pspec.name() { - "album" => { - let album = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.album.replace(album); - } - "artist" => { - let artist = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.artist.replace(artist); - } - "year" => { - let year = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.year.replace(year); - } - "cover" => { - let cover: Option = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.cover.replace(cover); - } - "uri" => { - let uri = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.uri.replace(uri); - } - _ => unimplemented!(), - } + fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + self.derived_set_property(id, value, pspec) } - // Called whenever a property is retrieved from this instance. The id - // is the same as the index of the property in the PROPERTIES array. - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { - match pspec.name() { - "album" => self.album.borrow().to_value(), - "artist" => self.artist.borrow().to_value(), - "year" => self.year.get().to_value(), - "cover" => self.cover.borrow().to_value(), - "uri" => self.uri.borrow().to_value(), - _ => unimplemented!(), - } + fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + self.derived_property(id, pspec) } } } diff --git a/src/app/models/artist_model.rs b/src/app/models/artist_model.rs index 0cf7fcb7..61d42d0c 100644 --- a/src/app/models/artist_model.rs +++ b/src/app/models/artist_model.rs @@ -2,25 +2,19 @@ use gio::prelude::*; use glib::subclass::prelude::*; +use glib::Properties; glib::wrapper! { pub struct ArtistModel(ObjectSubclass); } -// Constructor for new instances. This simply calls glib::Object::new() with -// initial values for our two properties and then returns the new instance impl ArtistModel { pub fn new(artist: &str, image: &Option, id: &str) -> ArtistModel { - glib::Object::new::(&[("artist", &artist), ("image", image), ("id", &id)]) - .expect("Failed to create") - } - - pub fn image_url(&self) -> Option { - self.property("image") - } - - pub fn id(&self) -> String { - self.property("id") + glib::Object::builder() + .property("artist", &artist) + .property("image", image) + .property("id", &id) + .build() } } @@ -28,87 +22,37 @@ mod imp { use super::*; use std::cell::RefCell; + use std::convert::TryFrom; - // Static array for defining the properties of the new type. - lazy_static! { - static ref PROPERTIES: [glib::ParamSpec; 3] = [ - glib::ParamSpecString::new("artist", "Artist", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("image", "Image", "", None, glib::ParamFlags::READWRITE), - glib::ParamSpecString::new("id", "id", "", None, glib::ParamFlags::READWRITE), - ]; - } - - // This is the struct containing all state carried with - // the new type. Generally this has to make use of - // interior mutability. - #[derive(Default)] + #[derive(Default, Properties)] + #[properties(wrapper_type = super::ArtistModel)] pub struct ArtistModel { + #[property(get, set)] artist: RefCell, + #[property(get, set)] image: RefCell>, + #[property(get, set)] id: RefCell, } - // ObjectSubclass is the trait that defines the new type and - // contains all information needed by the GObject type system, - // including the new type's name, parent type, etc. #[glib::object_subclass] impl ObjectSubclass for ArtistModel { - // This type name must be unique per process. const NAME: &'static str = "ArtistModel"; - type Type = super::ArtistModel; - - // The parent type this one is inheriting from. type ParentType = glib::Object; } - // Trait that is used to override virtual methods of glib::Object. impl ObjectImpl for ArtistModel { fn properties() -> &'static [glib::ParamSpec] { - &*PROPERTIES + Self::derived_properties() } - // Called whenever a property is set on this instance. The id - // is the same as the index of the property in the PROPERTIES array. - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { - match pspec.name() { - "artist" => { - let artist = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.artist.replace(artist); - } - "image" => { - let image = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.image.replace(image); - } - "id" => { - let id = value - .get() - .expect("type conformity checked by `Object::set_property`"); - self.id.replace(id); - } - _ => unimplemented!(), - } + fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + self.derived_set_property(id, value, pspec) } - // Called whenever a property is retrieved from this instance. The id - // is the same as the index of the property in the PROPERTIES array. - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { - match pspec.name() { - "artist" => self.artist.borrow().to_value(), - "image" => self.image.borrow().to_value(), - "id" => self.id.borrow().to_value(), - _ => unimplemented!(), - } + fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + self.derived_property(id, pspec) } } } diff --git a/src/app/models/songs/song_list_model.rs b/src/app/models/songs/song_list_model.rs index d1d5f1cf..2c56751a 100644 --- a/src/app/models/songs/song_list_model.rs +++ b/src/app/models/songs/song_list_model.rs @@ -1,8 +1,9 @@ use gio::prelude::*; use gio::ListModel; +use glib::Properties; use glib::StaticType; use gtk::subclass::prelude::*; -use std::cell::{Ref, RefCell, RefMut}; +use std::cell::{Cell, Ref, RefCell, RefMut}; use super::support::*; use crate::app::models::*; @@ -60,15 +61,17 @@ glib::wrapper! { impl SongListModel { pub fn new(batch_size: u32) -> Self { - glib::Object::new(&[("batch-size", &batch_size)]).unwrap() + glib::Object::builder() + .property("batch-size", batch_size) + .build() } fn inner_mut(&mut self) -> RefMut { - imp::SongListModel::from_instance(self).get_mut() + self.imp().get_mut() } fn inner(&self) -> Ref { - imp::SongListModel::from_instance(self).get() + self.imp().get() } fn notify_changes(&self, changes: impl IntoIterator + 'static) { @@ -170,74 +173,56 @@ impl SongListModel { mod imp { use super::*; + use std::convert::TryFrom; - pub struct SongListModel(RefCell>); + #[derive(Default, Properties)] + #[properties(wrapper_type = super::SongListModel)] + pub struct SongListModel { + #[property(get, set = Self::set_batch_size, name = "batch-size")] + batch_size: Cell, + song_list: RefCell>, + } + + impl SongListModel { + fn set_batch_size(&self, batch_size: u32) { + self.batch_size.set(batch_size); + self.song_list + .replace(Some(SongList::new_sized(batch_size as usize))); + } + } #[glib::object_subclass] impl ObjectSubclass for SongListModel { const NAME: &'static str = "SongList"; - type Type = super::SongListModel; type ParentType = glib::Object; type Interfaces = (ListModel,); - - fn new() -> Self { - Self(RefCell::new(None)) - } - } - - lazy_static! { - static ref PROPERTIES: [glib::ParamSpec; 1] = [glib::ParamSpecUInt::new( - "batch-size", - "Size of the batches", - "", - 1, - u32::MAX, - 1, - glib::ParamFlags::READWRITE, - )]; } impl ObjectImpl for SongListModel { fn properties() -> &'static [glib::ParamSpec] { - &*PROPERTIES + Self::derived_properties() } - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { - if "batch-size" == pspec.name() { - let batch_size = value.get::().unwrap(); - *self.0.borrow_mut() = Some(SongList::new_sized(batch_size as usize)) - } else { - unimplemented!() - } + fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + self.derived_set_property(id, value, pspec); } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { - if "batch-size" == pspec.name() { - let size = self.get().batch_size() as u32; - size.to_value() - } else { - unimplemented!() - } + fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + self.derived_property(id, pspec) } } impl ListModelImpl for SongListModel { - fn item_type(&self, _: &Self::Type) -> glib::Type { + fn item_type(&self) -> glib::Type { SongModel::static_type() } - fn n_items(&self, _: &Self::Type) -> u32 { + fn n_items(&self) -> u32 { self.get().partial_len() as u32 } - fn item(&self, _: &Self::Type, position: u32) -> Option { + fn item(&self, position: u32) -> Option { self.get() .index_continuous(position as usize) .map(|m| m.clone().upcast()) @@ -246,13 +231,13 @@ mod imp { impl SongListModel { pub fn get_mut(&self) -> RefMut { - RefMut::map(self.0.borrow_mut(), |s| { + RefMut::map(self.song_list.borrow_mut(), |s| { s.as_mut().expect("set at construction") }) } pub fn get(&self) -> Ref { - Ref::map(self.0.borrow(), |s| { + Ref::map(self.song_list.borrow(), |s| { s.as_ref().expect("set at construction") }) } diff --git a/src/app/models/songs/song_model.rs b/src/app/models/songs/song_model.rs index 3141dbe2..e83c1ba0 100644 --- a/src/app/models/songs/song_model.rs +++ b/src/app/models/songs/song_model.rs @@ -13,8 +13,8 @@ glib::wrapper! { impl SongModel { pub fn new(song: SongDescription) -> Self { - let o: Self = glib::Object::new(&[]).unwrap(); - imp::SongModel::from_instance(&o).song.replace(Some(song)); + let o: Self = glib::Object::new(); + o.imp().song.replace(Some(song)); o } @@ -39,7 +39,7 @@ impl SongModel { } pub fn bind_index(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("index", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -47,7 +47,7 @@ impl SongModel { } pub fn bind_artist(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("artist", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -55,7 +55,7 @@ impl SongModel { } pub fn bind_title(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("title", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -63,7 +63,7 @@ impl SongModel { } pub fn bind_duration(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("duration", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -71,7 +71,7 @@ impl SongModel { } pub fn bind_playing(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("playing", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -79,7 +79,7 @@ impl SongModel { } pub fn bind_selected(&self, o: &impl ObjectType, property: &str) { - imp::SongModel::from_instance(self).push_binding( + self.imp().push_binding( self.bind_property("selected", o, property) .flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE) .build(), @@ -87,17 +87,17 @@ impl SongModel { } pub fn unbind_all(&self) { - imp::SongModel::from_instance(self).unbind_all(self); + self.imp().unbind_all(self); } pub fn description(&self) -> impl Deref + '_ { - Ref::map(imp::SongModel::from_instance(self).song.borrow(), |s| { + Ref::map(self.imp().song.borrow(), |s| { s.as_ref().expect("song set at constructor") }) } pub fn into_description(&self) -> SongDescription { - imp::SongModel::from_instance(&self) + self.imp() .song .borrow() .as_ref() @@ -139,6 +139,7 @@ mod imp { bindings.bindings.drain(..).for_each(|b| b.unbind()); } } + #[glib::object_subclass] impl ObjectSubclass for SongModel { const NAME: &'static str = "SongModel"; @@ -148,64 +149,20 @@ mod imp { lazy_static! { static ref PROPERTIES: [glib::ParamSpec; 8] = [ - glib::ParamSpecString::new( - "id", - "Spotify identifier", - "", - None, - glib::ParamFlags::READABLE - ), - glib::ParamSpecUInt::new( - "index", - "Track number within an album", - "", - 1, - u32::MAX, - 1, - glib::ParamFlags::READABLE, - ), - glib::ParamSpecString::new( - "title", - "Title of the track", - "", - None, - glib::ParamFlags::READABLE - ), - glib::ParamSpecString::new( - "artist", - "Artists, comma separated", - "", - None, - glib::ParamFlags::READABLE - ), - glib::ParamSpecString::new( - "duration", - "Duration (formatted)", - "", - None, - glib::ParamFlags::READABLE, - ), - glib::ParamSpecString::new( - "art", - "URL to the cover art", - "", - None, - glib::ParamFlags::READABLE, - ), - glib::ParamSpecBoolean::new( - "playing", - "Playing", - "", - false, - glib::ParamFlags::READWRITE - ), - glib::ParamSpecBoolean::new( - "selected", - "Selected", - "", - false, - glib::ParamFlags::READWRITE, - ), + glib::ParamSpecString::builder("id").read_only().build(), + glib::ParamSpecUInt::builder("index").read_only().build(), + glib::ParamSpecString::builder("title").read_only().build(), + glib::ParamSpecString::builder("artist").read_only().build(), + glib::ParamSpecString::builder("duration") + .read_only() + .build(), + glib::ParamSpecString::builder("art").read_only().build(), + glib::ParamSpecBoolean::builder("playing") + .readwrite() + .build(), + glib::ParamSpecBoolean::builder("selected") + .readwrite() + .build(), ]; } @@ -214,13 +171,7 @@ mod imp { &*PROPERTIES } - fn set_property( - &self, - _obj: &Self::Type, - _id: usize, - value: &glib::Value, - pspec: &glib::ParamSpec, - ) { + fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { match pspec.name() { "playing" => { let is_playing = value @@ -246,7 +197,7 @@ mod imp { } } - fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.name() { "index" => self .song diff --git a/src/main.rs b/src/main.rs index d93633f7..607ed650 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,7 +91,7 @@ fn main() { fn startup(settings: &settings::SpotSettings) { gtk::init().unwrap_or_else(|_| panic!("Failed to initialize GTK")); - libadwaita::init(); + libadwaita::init().unwrap_or_else(|_| panic!("Failed to initialize libadwaita")); let manager = libadwaita::StyleManager::default(); let res = gio::Resource::load(config::PKGDATADIR.to_owned() + "/spot.gresource") From 8edf17e4434bb6ef1b167f8de950fd72266334bd Mon Sep 17 00:00:00 2001 From: Alexandre Trendel Date: Sun, 12 Feb 2023 12:25:29 -0500 Subject: [PATCH 2/4] update cargo sources --- cargo-sources.json | 240 ++++++++++++++++++++++----------------------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/cargo-sources.json b/cargo-sources.json index bcd8e811..d395f8ba 100644 --- a/cargo-sources.json +++ b/cargo-sources.json @@ -456,28 +456,28 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/cairo-rs/cairo-rs-0.15.1.crate", - "sha256": "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a", + "url": "https://static.crates.io/crates/cairo-rs/cairo-rs-0.17.0.crate", + "sha256": "a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871", "dest": "cargo/vendor", - "dest-filename": "cairo-rs-0.15.1.crate" + "dest-filename": "cairo-rs-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/cairo-rs-0.15.1", + "url": "data:%7B%22package%22%3A%20%22a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/cairo-rs-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/cairo-sys-rs/cairo-sys-rs-0.15.1.crate", - "sha256": "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8", + "url": "https://static.crates.io/crates/cairo-sys-rs/cairo-sys-rs-0.17.0.crate", + "sha256": "f55382a01d30e5e53f185eee269124f5e21ab526595b872751278dfbb463594e", "dest": "cargo/vendor", - "dest-filename": "cairo-sys-rs-0.15.1.crate" + "dest-filename": "cairo-sys-rs-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%223c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/cairo-sys-rs-0.15.1", + "url": "data:%7B%22package%22%3A%20%22f55382a01d30e5e53f185eee269124f5e21ab526595b872751278dfbb463594e%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/cairo-sys-rs-0.17.0", "dest-filename": ".cargo-checksum.json" }, { @@ -1158,54 +1158,54 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/gdk-pixbuf/gdk-pixbuf-0.15.6.crate", - "sha256": "d8750501d75f318c2ec0314701bc8403901303210def80bafd13f6b6059a3f45", + "url": "https://static.crates.io/crates/gdk-pixbuf/gdk-pixbuf-0.17.0.crate", + "sha256": "b023fbe0c6b407bd3d9805d107d9800da3829dc5a676653210f1d5f16d7f59bf", "dest": "cargo/vendor", - "dest-filename": "gdk-pixbuf-0.15.6.crate" + "dest-filename": "gdk-pixbuf-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22d8750501d75f318c2ec0314701bc8403901303210def80bafd13f6b6059a3f45%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gdk-pixbuf-0.15.6", + "url": "data:%7B%22package%22%3A%20%22b023fbe0c6b407bd3d9805d107d9800da3829dc5a676653210f1d5f16d7f59bf%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gdk-pixbuf-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gdk-pixbuf-sys/gdk-pixbuf-sys-0.15.1.crate", - "sha256": "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171", + "url": "https://static.crates.io/crates/gdk-pixbuf-sys/gdk-pixbuf-sys-0.17.0.crate", + "sha256": "7b41bd2b44ed49d99277d3925652a163038bd5ed943ec9809338ffb2f4391e3b", "dest": "cargo/vendor", - "dest-filename": "gdk-pixbuf-sys-0.15.1.crate" + "dest-filename": "gdk-pixbuf-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gdk-pixbuf-sys-0.15.1", + "url": "data:%7B%22package%22%3A%20%227b41bd2b44ed49d99277d3925652a163038bd5ed943ec9809338ffb2f4391e3b%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gdk-pixbuf-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gdk4/gdk4-0.4.6.crate", - "sha256": "d9df40006277ff44538fe758400fc671146f6f2665978b6b57d2408db3c2becf", + "url": "https://static.crates.io/crates/gdk4/gdk4-0.6.0.crate", + "sha256": "6e4887e17b6926db51f1e538d871a8b1f5ceb5dfa3bd0034dc42ec355b390d8f", "dest": "cargo/vendor", - "dest-filename": "gdk4-0.4.6.crate" + "dest-filename": "gdk4-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22d9df40006277ff44538fe758400fc671146f6f2665978b6b57d2408db3c2becf%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gdk4-0.4.6", + "url": "data:%7B%22package%22%3A%20%226e4887e17b6926db51f1e538d871a8b1f5ceb5dfa3bd0034dc42ec355b390d8f%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gdk4-0.6.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gdk4-sys/gdk4-sys-0.4.2.crate", - "sha256": "48a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b", + "url": "https://static.crates.io/crates/gdk4-sys/gdk4-sys-0.6.0.crate", + "sha256": "f4993c019bf03d18137c00ddafb2b23e73f7cbb45ae244f52af2542a3f4a9452", "dest": "cargo/vendor", - "dest-filename": "gdk4-sys-0.4.2.crate" + "dest-filename": "gdk4-sys-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%2248a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gdk4-sys-0.4.2", + "url": "data:%7B%22package%22%3A%20%22f4993c019bf03d18137c00ddafb2b23e73f7cbb45ae244f52af2542a3f4a9452%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gdk4-sys-0.6.0", "dest-filename": ".cargo-checksum.json" }, { @@ -1275,67 +1275,67 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/gio/gio-0.15.7.crate", - "sha256": "bb50e113645fba48bc36c8abaee1fe5e43d353e8763966e29dfe69660514e461", + "url": "https://static.crates.io/crates/gio/gio-0.17.0.crate", + "sha256": "1981edf8679d2f2c8ec3120015867f45aa0a1c2d5e3e129ca2f7dda174d3d2a9", "dest": "cargo/vendor", - "dest-filename": "gio-0.15.7.crate" + "dest-filename": "gio-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22bb50e113645fba48bc36c8abaee1fe5e43d353e8763966e29dfe69660514e461%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gio-0.15.7", + "url": "data:%7B%22package%22%3A%20%221981edf8679d2f2c8ec3120015867f45aa0a1c2d5e3e129ca2f7dda174d3d2a9%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gio-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gio-sys/gio-sys-0.15.5.crate", - "sha256": "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3", + "url": "https://static.crates.io/crates/gio-sys/gio-sys-0.17.0.crate", + "sha256": "b5d3076ecb86c8c3a672c9843d6232b3a344fb81d304d0ba1ac64b23343efa46", "dest": "cargo/vendor", - "dest-filename": "gio-sys-0.15.5.crate" + "dest-filename": "gio-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%224f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gio-sys-0.15.5", + "url": "data:%7B%22package%22%3A%20%22b5d3076ecb86c8c3a672c9843d6232b3a344fb81d304d0ba1ac64b23343efa46%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gio-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/glib/glib-0.15.9.crate", - "sha256": "89528258cfdc79b1e54591202705be67896ad254f99e3cc2ea3710e0307148f2", + "url": "https://static.crates.io/crates/glib/glib-0.17.0.crate", + "sha256": "ac347af59233f0544ce00a37bad50f4ac401d006505b26d80ad6d9bbecf6493f", "dest": "cargo/vendor", - "dest-filename": "glib-0.15.9.crate" + "dest-filename": "glib-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%2289528258cfdc79b1e54591202705be67896ad254f99e3cc2ea3710e0307148f2%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/glib-0.15.9", + "url": "data:%7B%22package%22%3A%20%22ac347af59233f0544ce00a37bad50f4ac401d006505b26d80ad6d9bbecf6493f%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/glib-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/glib-macros/glib-macros-0.15.3.crate", - "sha256": "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1", + "url": "https://static.crates.io/crates/glib-macros/glib-macros-0.17.0.crate", + "sha256": "5965ae1a44aa4bae4e1e6970f25b66c058fef873d2626c9932a41128dbeea03f", "dest": "cargo/vendor", - "dest-filename": "glib-macros-0.15.3.crate" + "dest-filename": "glib-macros-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/glib-macros-0.15.3", + "url": "data:%7B%22package%22%3A%20%225965ae1a44aa4bae4e1e6970f25b66c058fef873d2626c9932a41128dbeea03f%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/glib-macros-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/glib-sys/glib-sys-0.15.5.crate", - "sha256": "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c", + "url": "https://static.crates.io/crates/glib-sys/glib-sys-0.17.0.crate", + "sha256": "9ddcb73fa8236277bedadaaadb76aef49c85d66340f83bece244f46c2d4f0e01", "dest": "cargo/vendor", - "dest-filename": "glib-sys-0.15.5.crate" + "dest-filename": "glib-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/glib-sys-0.15.5", + "url": "data:%7B%22package%22%3A%20%229ddcb73fa8236277bedadaaadb76aef49c85d66340f83bece244f46c2d4f0e01%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/glib-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { @@ -1366,106 +1366,106 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/gobject-sys/gobject-sys-0.15.5.crate", - "sha256": "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a", + "url": "https://static.crates.io/crates/gobject-sys/gobject-sys-0.17.0.crate", + "sha256": "9a0155d388840c77d61b033b66ef4f9bc7f4133d83df83572d6b4fb234a3be7d", "dest": "cargo/vendor", - "dest-filename": "gobject-sys-0.15.5.crate" + "dest-filename": "gobject-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gobject-sys-0.15.5", + "url": "data:%7B%22package%22%3A%20%229a0155d388840c77d61b033b66ef4f9bc7f4133d83df83572d6b4fb234a3be7d%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gobject-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/graphene-rs/graphene-rs-0.15.1.crate", - "sha256": "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570", + "url": "https://static.crates.io/crates/graphene-rs/graphene-rs-0.17.0.crate", + "sha256": "372514f21c7e342e0206a916d6bd522b15337578cfa68855518a3b4960ba8254", "dest": "cargo/vendor", - "dest-filename": "graphene-rs-0.15.1.crate" + "dest-filename": "graphene-rs-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%227c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/graphene-rs-0.15.1", + "url": "data:%7B%22package%22%3A%20%22372514f21c7e342e0206a916d6bd522b15337578cfa68855518a3b4960ba8254%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/graphene-rs-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/graphene-sys/graphene-sys-0.15.1.crate", - "sha256": "03f311acb023cf7af5537f35de028e03706136eead7f25a31e8fd26f5011e0b3", + "url": "https://static.crates.io/crates/graphene-sys/graphene-sys-0.17.0.crate", + "sha256": "cf80a4849a8d9565410a8fec6fc3678e9c617f4ac7be182ca55ab75016e07af9", "dest": "cargo/vendor", - "dest-filename": "graphene-sys-0.15.1.crate" + "dest-filename": "graphene-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%2203f311acb023cf7af5537f35de028e03706136eead7f25a31e8fd26f5011e0b3%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/graphene-sys-0.15.1", + "url": "data:%7B%22package%22%3A%20%22cf80a4849a8d9565410a8fec6fc3678e9c617f4ac7be182ca55ab75016e07af9%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/graphene-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gsk4/gsk4-0.4.6.crate", - "sha256": "1bf63d454e2f75abd92ee6de0ac9fc5aaf1018cd9c458aaf9de296c5cbab6bb9", + "url": "https://static.crates.io/crates/gsk4/gsk4-0.6.0.crate", + "sha256": "432f981e4ea9f0739a5731d8a649acb794a3a729d2254e559ce7d613b17caf95", "dest": "cargo/vendor", - "dest-filename": "gsk4-0.4.6.crate" + "dest-filename": "gsk4-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%221bf63d454e2f75abd92ee6de0ac9fc5aaf1018cd9c458aaf9de296c5cbab6bb9%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gsk4-0.4.6", + "url": "data:%7B%22package%22%3A%20%22432f981e4ea9f0739a5731d8a649acb794a3a729d2254e559ce7d613b17caf95%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gsk4-0.6.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gsk4-sys/gsk4-sys-0.4.2.crate", - "sha256": "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b", + "url": "https://static.crates.io/crates/gsk4-sys/gsk4-sys-0.6.0.crate", + "sha256": "096cb59175b0915ebf69c05a45263c0c989bd8537b8f2169912d0de644ba6a76", "dest": "cargo/vendor", - "dest-filename": "gsk4-sys-0.4.2.crate" + "dest-filename": "gsk4-sys-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gsk4-sys-0.4.2", + "url": "data:%7B%22package%22%3A%20%22096cb59175b0915ebf69c05a45263c0c989bd8537b8f2169912d0de644ba6a76%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gsk4-sys-0.6.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gtk4/gtk4-0.4.6.crate", - "sha256": "9e841556e3fe55d8a43ada76b7b08a5f65570bbdfe3b8f72c333053b8832c626", + "url": "https://static.crates.io/crates/gtk4/gtk4-0.6.0.crate", + "sha256": "f61aa16bbd4554552645227d4249b58fd730b27985a7e0283fd0a2d479e954a8", "dest": "cargo/vendor", - "dest-filename": "gtk4-0.4.6.crate" + "dest-filename": "gtk4-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%229e841556e3fe55d8a43ada76b7b08a5f65570bbdfe3b8f72c333053b8832c626%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gtk4-0.4.6", + "url": "data:%7B%22package%22%3A%20%22f61aa16bbd4554552645227d4249b58fd730b27985a7e0283fd0a2d479e954a8%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gtk4-0.6.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gtk4-macros/gtk4-macros-0.4.3.crate", - "sha256": "573db42bb64973a4d5f718b73caa7204285a1a665308a23b11723d0ee56ec305", + "url": "https://static.crates.io/crates/gtk4-macros/gtk4-macros-0.6.0.crate", + "sha256": "db4676c4f90d8b010e88cb4558f61f47d76d6f6b8e6f6b89e62640f443907f61", "dest": "cargo/vendor", - "dest-filename": "gtk4-macros-0.4.3.crate" + "dest-filename": "gtk4-macros-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22573db42bb64973a4d5f718b73caa7204285a1a665308a23b11723d0ee56ec305%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gtk4-macros-0.4.3", + "url": "data:%7B%22package%22%3A%20%22db4676c4f90d8b010e88cb4558f61f47d76d6f6b8e6f6b89e62640f443907f61%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gtk4-macros-0.6.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/gtk4-sys/gtk4-sys-0.4.5.crate", - "sha256": "c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d", + "url": "https://static.crates.io/crates/gtk4-sys/gtk4-sys-0.6.0.crate", + "sha256": "e13cf3bc9559f71963c957eb639060b643e1276ae47b892ef6091d5bc15c3e1b", "dest": "cargo/vendor", - "dest-filename": "gtk4-sys-0.4.5.crate" + "dest-filename": "gtk4-sys-0.6.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/gtk4-sys-0.4.5", + "url": "data:%7B%22package%22%3A%20%22e13cf3bc9559f71963c957eb639060b643e1276ae47b892ef6091d5bc15c3e1b%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/gtk4-sys-0.6.0", "dest-filename": ".cargo-checksum.json" }, { @@ -1912,28 +1912,28 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/libadwaita/libadwaita-0.1.0.crate", - "sha256": "0d4b1d54d907dfa5d6663fdf4bdbe46c34747258b85c787adbf66187ccbaac81", + "url": "https://static.crates.io/crates/libadwaita/libadwaita-0.3.0.crate", + "sha256": "674cbf1bd796f3d4f0c24466c15d91180e33e497ae2e07eea3f3d545468dc839", "dest": "cargo/vendor", - "dest-filename": "libadwaita-0.1.0.crate" + "dest-filename": "libadwaita-0.3.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%220d4b1d54d907dfa5d6663fdf4bdbe46c34747258b85c787adbf66187ccbaac81%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/libadwaita-0.1.0", + "url": "data:%7B%22package%22%3A%20%22674cbf1bd796f3d4f0c24466c15d91180e33e497ae2e07eea3f3d545468dc839%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/libadwaita-0.3.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/libadwaita-sys/libadwaita-sys-0.1.0.crate", - "sha256": "f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8", + "url": "https://static.crates.io/crates/libadwaita-sys/libadwaita-sys-0.3.0.crate", + "sha256": "0727b85b4fe2b1bed5ac90df6343de15cbf8118bfb96d7c3cc1512681a4b34ac", "dest": "cargo/vendor", - "dest-filename": "libadwaita-sys-0.1.0.crate" + "dest-filename": "libadwaita-sys-0.3.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22f18b6ac4cadd252a89f5cba0a5a4e99836131795d6fad37b859ac79e8cb7d2c8%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/libadwaita-sys-0.1.0", + "url": "data:%7B%22package%22%3A%20%220727b85b4fe2b1bed5ac90df6343de15cbf8118bfb96d7c3cc1512681a4b34ac%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/libadwaita-sys-0.3.0", "dest-filename": ".cargo-checksum.json" }, { @@ -2263,15 +2263,15 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/memchr/memchr-2.4.1.crate", - "sha256": "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a", + "url": "https://static.crates.io/crates/memchr/memchr-2.5.0.crate", + "sha256": "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d", "dest": "cargo/vendor", - "dest-filename": "memchr-2.4.1.crate" + "dest-filename": "memchr-2.5.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%22308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/memchr-2.4.1", + "url": "data:%7B%22package%22%3A%20%222dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/memchr-2.5.0", "dest-filename": ".cargo-checksum.json" }, { @@ -2770,28 +2770,28 @@ }, { "type": "file", - "url": "https://static.crates.io/crates/pango/pango-0.15.2.crate", - "sha256": "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94", + "url": "https://static.crates.io/crates/pango/pango-0.17.0.crate", + "sha256": "243c048be90312220fb3bd578176eed8290568274a93c95040289d39349384bc", "dest": "cargo/vendor", - "dest-filename": "pango-0.15.2.crate" + "dest-filename": "pango-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%2279211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/pango-0.15.2", + "url": "data:%7B%22package%22%3A%20%22243c048be90312220fb3bd578176eed8290568274a93c95040289d39349384bc%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/pango-0.17.0", "dest-filename": ".cargo-checksum.json" }, { "type": "file", - "url": "https://static.crates.io/crates/pango-sys/pango-sys-0.15.1.crate", - "sha256": "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2", + "url": "https://static.crates.io/crates/pango-sys/pango-sys-0.17.0.crate", + "sha256": "4293d0f0b5525eb5c24734d30b0ed02cd02aa734f216883f376b54de49625de8", "dest": "cargo/vendor", - "dest-filename": "pango-sys-0.15.1.crate" + "dest-filename": "pango-sys-0.17.0.crate" }, { "type": "file", - "url": "data:%7B%22package%22%3A%20%227022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2%22%2C%20%22files%22%3A%20%7B%7D%7D", - "dest": "cargo/vendor/pango-sys-0.15.1", + "url": "data:%7B%22package%22%3A%20%224293d0f0b5525eb5c24734d30b0ed02cd02aa734f216883f376b54de49625de8%22%2C%20%22files%22%3A%20%7B%7D%7D", + "dest": "cargo/vendor/pango-sys-0.17.0", "dest-filename": ".cargo-checksum.json" }, { From a7379670b34e4826f1344f8a225cf94749b14292 Mon Sep 17 00:00:00 2001 From: Alexandre Trendel Date: Sun, 12 Feb 2023 12:45:55 -0500 Subject: [PATCH 3/4] better clippy fix --- build-aux/clippy.sh | 3 +- src/app/dispatch.rs | 2 +- src/player/player.rs | 97 +++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/build-aux/clippy.sh b/build-aux/clippy.sh index d4ea9c20..1c073db9 100644 --- a/build-aux/clippy.sh +++ b/build-aux/clippy.sh @@ -11,5 +11,4 @@ fi cargo clippy --manifest-path "$SRC"/Cargo.toml -- -D warnings \ -A clippy::module_inception \ -A clippy::new_without_default \ --A clippy::enum-variant-names \ --A clippy::await_holding_refcell_ref # not sure how to solve this one yet +-A clippy::enum-variant-names diff --git a/src/app/dispatch.rs b/src/app/dispatch.rs index 4040c7ad..28c6b81b 100644 --- a/src/app/dispatch.rs +++ b/src/app/dispatch.rs @@ -82,7 +82,7 @@ impl DispatchLoop { self.receiver .for_each(|action| { handler(action); - async move {} + async {} }) .await; } diff --git a/src/player/player.rs b/src/player/player.rs index 81894130..e15bba02 100644 --- a/src/player/player.rs +++ b/src/player/player.rs @@ -76,77 +76,84 @@ impl Default for SpotifyPlayerSettings { } pub struct SpotifyPlayer { - settings: RefCell, - player: RefCell>, - mixer: RefCell>>, - session: RefCell>, + settings: SpotifyPlayerSettings, + player: Option, + mixer: Option>, + session: Option, delegate: Rc, } impl SpotifyPlayer { pub fn new(settings: SpotifyPlayerSettings, delegate: Rc) -> Self { Self { - settings: RefCell::new(settings), - mixer: RefCell::new(None), - player: RefCell::new(None), - session: RefCell::new(None), + settings, + mixer: None, + player: None, + session: None, delegate, } } - async fn handle(&self, action: Command) -> Result<(), SpotifyError> { - let mut player = self.player.borrow_mut(); - let mut session = self.session.borrow_mut(); + async fn handle(&mut self, action: Command) -> Result<(), SpotifyError> { match action { Command::PlayerSetVolume(volume) => { - if let Some(mixer) = self.mixer.borrow_mut().as_mut() { + if let Some(mixer) = self.mixer.as_mut() { mixer.set_volume((VolumeCtrl::MAX_VOLUME as f64 * volume) as u16); } Ok(()) } Command::PlayerResume => { - let player = player.as_ref().ok_or(SpotifyError::PlayerNotReady)?; - player.play(); + self.player + .as_ref() + .ok_or(SpotifyError::PlayerNotReady)? + .play(); Ok(()) } Command::PlayerPause => { - let player = player.as_ref().ok_or(SpotifyError::PlayerNotReady)?; - player.pause(); + self.player + .as_ref() + .ok_or(SpotifyError::PlayerNotReady)? + .pause(); Ok(()) } Command::PlayerStop => { - let player = player.as_ref().ok_or(SpotifyError::PlayerNotReady)?; - player.stop(); + self.player + .as_ref() + .ok_or(SpotifyError::PlayerNotReady)? + .stop(); Ok(()) } Command::PlayerSeek(position) => { - let player = player.as_ref().ok_or(SpotifyError::PlayerNotReady)?; - player.seek(position); + self.player + .as_ref() + .ok_or(SpotifyError::PlayerNotReady)? + .seek(position); Ok(()) } Command::PlayerLoad(track) => { - let player = player.as_mut().ok_or(SpotifyError::PlayerNotReady)?; - player.load(track, true, 0); + self.player + .as_mut() + .ok_or(SpotifyError::PlayerNotReady)? + .load(track, true, 0); Ok(()) } Command::RefreshToken => { - let session = session.as_ref().ok_or(SpotifyError::PlayerNotReady)?; + let session = self.session.as_ref().ok_or(SpotifyError::PlayerNotReady)?; let (token, token_expiry_time) = get_access_token_and_expiry_time(session).await?; self.delegate.refresh_successful(token, token_expiry_time); Ok(()) } Command::Logout => { - session + self.session .take() .ok_or(SpotifyError::PlayerNotReady)? .shutdown(); - let _ = player.take(); + let _ = self.player.take(); Ok(()) } Command::PasswordLogin { username, password } => { let credentials = Credentials::with_password(username, password.clone()); - let new_session = - create_session(credentials, self.settings.borrow().ap_port).await?; + let new_session = create_session(credentials, self.settings.ap_port).await?; let (token, token_expiry_time) = get_access_token_and_expiry_time(&new_session).await?; let credentials = credentials::Credentials { @@ -160,8 +167,8 @@ impl SpotifyPlayer { let (new_player, channel) = self.create_player(new_session.clone()); tokio::task::spawn_local(player_setup_delegate(channel, Rc::clone(&self.delegate))); - player.replace(new_player); - session.replace(new_session); + self.player.replace(new_player); + self.session.replace(new_session); Ok(()) } @@ -171,45 +178,42 @@ impl SpotifyPlayer { auth_type: AuthenticationType::AUTHENTICATION_SPOTIFY_TOKEN, auth_data: token.clone().into_bytes(), }; - let new_session = - create_session(credentials, self.settings.borrow().ap_port).await?; + let new_session = create_session(credentials, self.settings.ap_port).await?; self.delegate .token_login_successful(new_session.username(), token); let (new_player, channel) = self.create_player(new_session.clone()); tokio::task::spawn_local(player_setup_delegate(channel, Rc::clone(&self.delegate))); - player.replace(new_player); - session.replace(new_session); + self.player.replace(new_player); + self.session.replace(new_session); Ok(()) } Command::ReloadSettings => { let settings = SpotSettings::new_from_gsettings().unwrap_or_default(); - self.settings.replace(settings.player_settings); + self.settings = settings.player_settings; - let session = session.as_ref().ok_or(SpotifyError::PlayerNotReady)?; - let (new_player, channel) = self.create_player(session.clone()); + let session = self.session.take().ok_or(SpotifyError::PlayerNotReady)?; + let (new_player, channel) = self.create_player(session); tokio::task::spawn_local(player_setup_delegate(channel, Rc::clone(&self.delegate))); - player.replace(new_player); + self.player.replace(new_player); Ok(()) } } } - fn create_player(&self, session: Session) -> (Player, PlayerEventChannel) { - let settings = self.settings.borrow(); - let backend = settings.backend.clone(); + fn create_player(&mut self, session: Session) -> (Player, PlayerEventChannel) { + let backend = self.settings.backend.clone(); let player_config = PlayerConfig { - bitrate: settings.bitrate, + bitrate: self.settings.bitrate, ..Default::default() }; info!("bitrate: {:?}", &player_config.bitrate); - let filter = self - .mixer - .borrow_mut() + let mixer = &mut self.mixer; + let filter = mixer .get_or_insert_with(|| { let mix = Box::new(SoftMixer::open(MixerConfig { // This value feels reasonable to me. Feel free to change it @@ -237,9 +241,10 @@ impl SpotifyPlayer { } pub async fn start(self, receiver: UnboundedReceiver) -> Result<(), ()> { - let _self = &self; + let _self = RefCell::new(self); receiver - .for_each(|action| async move { + .for_each(|action| async { + let mut _self = _self.borrow_mut(); match _self.handle(action).await { Ok(_) => {} Err(err) => _self.delegate.report_error(err), From 3398418edbbd5316881236ba6cd3acba4b38e1c3 Mon Sep 17 00:00:00 2001 From: Alexandre Trendel Date: Sun, 12 Feb 2023 13:09:51 -0500 Subject: [PATCH 4/4] missing fix --- src/app/components/playlist/playlist.rs | 4 +--- src/app/components/settings/settings.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/components/playlist/playlist.rs b/src/app/components/playlist/playlist.rs index bf243628..e6e7a12c 100644 --- a/src/app/components/playlist/playlist.rs +++ b/src/app/components/playlist/playlist.rs @@ -73,7 +73,6 @@ pub trait PlaylistModel { pub struct Playlist { animator: AnimatorDefault, listview: gtk::ListView, - _press_gesture: gtk::GestureLongPress, model: Rc, } @@ -134,12 +133,11 @@ where press_gesture.connect_pressed(clone!(@weak model => move |_, _, _| { model.enable_selection(); })); - listview.add_controller(press_gesture.clone()); //FIXME + listview.add_controller(press_gesture); Self { animator: AnimatorDefault::ease_in_out_animator(), listview, - _press_gesture: press_gesture, model, } } diff --git a/src/app/components/settings/settings.rs b/src/app/components/settings/settings.rs index 13c1a663..ffcb38c6 100644 --- a/src/app/components/settings/settings.rs +++ b/src/app/components/settings/settings.rs @@ -88,7 +88,7 @@ impl SettingsWindow { audio_backend .bind_property("selected", alsa_device_row, "visible") - .transform_to(|_, value: u32| Some(value == 1)) //FIXME + .transform_to(|_, value: u32| Some(value == 1)) .build(); if audio_backend.selected() == 0 {