diff --git a/Cargo.lock b/Cargo.lock index a70c7f6..203a9ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aes" version = "0.6.0" @@ -194,6 +196,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "cfg-expr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571" +dependencies = [ + "smallvec", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -565,9 +576,9 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03132f21de5fe15ded4f950328fb44e007037aea7c6bbbc3f082493d5d3c164" +checksum = "4c0f7f98ad25b81ac9462f74a091b0e4c0983ed1e74d19a38230c772b4dcef81" dependencies = [ "bitflags", "cairo-rs", @@ -581,9 +592,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3453f8dc11a6167a7269355fcfbd6b96d10625395e87f77199e7dbba9077b58c" +checksum = "262a79666b42e1884577f11a050439a964b95dec55343ac6ace7930e1415fa18" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -593,7 +604,7 @@ dependencies = [ "graphene-sys", "libc", "pango-sys", - "system-deps 3.1.1", + "system-deps 4.0.0", ] [[package]] @@ -813,9 +824,9 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2699e9ff7ba3ca3582043bfd45ea3af3c45fa461fea75a369bcc6ab77eacde2" +checksum = "20b71f2e2cc699c2e0fbfa22899eeaffd84f9c1dc01e9263deac8664eec22dc0" dependencies = [ "bitflags", "cairo-rs", @@ -829,9 +840,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27cf692f33ec2f438a89cb57018f57260b73193929da9d37b873e47a7662a7e0" +checksum = "30468aff80e4faadf22f9ba164ea17511a69a9995d7a13827a13424ef47b2472" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -840,7 +851,7 @@ dependencies = [ "graphene-sys", "libc", "pango-sys", - "system-deps 3.1.1", + "system-deps 4.0.0", ] [[package]] @@ -1016,9 +1027,9 @@ checksum = "da5bf7748fd4cd0b2490df8debcc911809dbcbee4ece9531b96c29a9c729de5a" [[package]] name = "gtk4" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8801459abe49508a914c591d0cf355a6aea9762058334ba6efe63bdf40e479" +checksum = "906f9308d15789d96a736881582181d710ae0937197119df459f3d2b46ef6776" dependencies = [ "bitflags", "cairo-rs", @@ -1039,9 +1050,9 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca4260cbbdad77f91c57b4836ff63c6c51dc79b2feadc83c0869e4d379dcbee5" +checksum = "4d0d008cdf23214c697482415dd20f666bdf3cc9f5e803b017223c17c5b59a6e" dependencies = [ "anyhow", "heck", @@ -1055,9 +1066,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "580a7215a4d681e068cb1ea93e7293ca0d84b738d9b0c82b630199f21d3c82ef" +checksum = "d06be0a6322aa77dd372f726e97efbcbb192d9a824a414a8874f238effd7747c" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1069,7 +1080,7 @@ dependencies = [ "gsk4-sys", "libc", "pango-sys", - "system-deps 3.1.1", + "system-deps 4.0.0", ] [[package]] @@ -1190,9 +1201,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libadwaita" -version = "0.1.0-alpha" +version = "0.1.0-alpha-6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d8221b476b16ee55b18bf4209e0fb5457c66375b9af8f8cef91ff930e82da6" +checksum = "d8d01ba5036df1c3e09be88b4b8e0906af977bb7ec28d5faec81a1de94bc775c" dependencies = [ "gdk-pixbuf", "gdk4", @@ -1201,14 +1212,15 @@ dependencies = [ "gtk4", "libadwaita-sys", "libc", + "once_cell", "pango", ] [[package]] name = "libadwaita-sys" -version = "0.1.0-alpha" +version = "0.1.0-alpha-6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80594e5894e4145639c75164ee33cf607f42c667318475cb1d5db8132b77eab4" +checksum = "3127d83c55f64c466925b9d1e27a964187f193e94c7c8820ad6b29d6e5f487d8" dependencies = [ "gdk-pixbuf-sys", "gdk4-sys", @@ -1218,7 +1230,7 @@ dependencies = [ "gtk4-sys", "libc", "pango-sys", - "system-deps 3.1.1", + "system-deps 4.0.0", ] [[package]] @@ -2151,7 +2163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c248107ad7bc1ac07066a4d003cae9e9a7bc2e27d3418f7a9cdcdc8699dbea70" dependencies = [ "anyhow", - "cfg-expr", + "cfg-expr 0.7.4", "heck", "itertools 0.10.1", "pkg-config", @@ -2162,6 +2174,19 @@ dependencies = [ "version-compare 0.0.11", ] +[[package]] +name = "system-deps" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c1889ab44c2a423ba9ba4d64cd04989b25c0280ca7ade813f05368418722a04" +dependencies = [ + "cfg-expr 0.9.0", + "heck", + "pkg-config", + "toml", + "version-compare 0.0.11", +] + [[package]] name = "thiserror" version = "1.0.25" diff --git a/musicus/Cargo.toml b/musicus/Cargo.toml index 8b09281..f1a3bc0 100644 --- a/musicus/Cargo.toml +++ b/musicus/Cargo.toml @@ -5,15 +5,15 @@ edition = "2018" [dependencies] anyhow = "1.0.33" -adw = { package = "libadwaita", version = "0.1.0-alpha" } +adw = { package = "libadwaita", version = "0.1.0-alpha-6" } async-trait = "0.1.42" futures-channel = "0.3.5" -gdk = { package = "gdk4", version = "0.1.0" } +gdk = { package = "gdk4", version = "0.3.0" } gettext-rs = { version = "0.5.0", features = ["gettext-system"] } gio = "0.14.0" glib = "0.14.0" gstreamer = "0.17.0" -gtk = { package = "gtk4", version = "0.1.0" } +gtk = { package = "gtk4", version = "0.3.0" } gtk-macros = "0.3.0" log = "0.4.14" musicus_backend = { version = "0.1.0", path = "../backend" } diff --git a/musicus/src/editors/performance.rs b/musicus/src/editors/performance.rs index b500985..55154ec 100644 --- a/musicus/src/editors/performance.rs +++ b/musicus/src/editors/performance.rs @@ -4,7 +4,6 @@ use crate::widgets::{ButtonRow, Editor, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use log::error; use musicus_backend::db::{Ensemble, Instrument, Performance, Person, PersonOrEnsemble}; use std::cell::RefCell; @@ -165,30 +164,30 @@ impl PerformanceEditor { /// Update the UI according to person. fn show_person(&self, person: Option<&Person>) { if let Some(person) = person { - self.person_row.set_subtitle(Some(&person.name_fl())); + self.person_row.set_subtitle(&person.name_fl()); self.editor.set_may_save(true); } else { - self.person_row.set_subtitle(None); + self.person_row.set_subtitle(""); } } /// Update the UI according to ensemble. fn show_ensemble(&self, ensemble: Option<&Ensemble>) { if let Some(ensemble) = ensemble { - self.ensemble_row.set_subtitle(Some(&ensemble.name)); + self.ensemble_row.set_subtitle(&ensemble.name); self.editor.set_may_save(true); } else { - self.ensemble_row.set_subtitle(None); + self.ensemble_row.set_subtitle(""); } } /// Update the UI according to role. fn show_role(&self, role: Option<&Instrument>) { if let Some(role) = role { - self.role_row.set_subtitle(Some(&role.name)); + self.role_row.set_subtitle(&role.name); self.reset_role_button.show(); } else { - self.role_row.set_subtitle(None); + self.role_row.set_subtitle(""); self.reset_role_button.hide(); } } diff --git a/musicus/src/editors/recording.rs b/musicus/src/editors/recording.rs index 421c6a9..8a893e3 100644 --- a/musicus/src/editors/recording.rs +++ b/musicus/src/editors/recording.rs @@ -6,7 +6,6 @@ use adw::prelude::*; use anyhow::Result; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::{generate_id, Performance, Recording, Work}; use std::cell::RefCell; @@ -139,7 +138,7 @@ impl Screen, Recording> for RecordingEditor { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&performance.get_title())); + row.set_title(&performance.get_title()); row.add_suffix(&delete_button); row.add_suffix(&edit_button); row.set_activatable_widget(Some(&edit_button)); @@ -177,8 +176,8 @@ impl Screen, Recording> for RecordingEditor { impl RecordingEditor { /// Update the UI according to work. fn work_selected(&self, work: &Work) { - self.work_row.set_title(Some(&gettext("Work"))); - self.work_row.set_subtitle(Some(&work.get_title())); + self.work_row.set_title(&gettext("Work")); + self.work_row.set_subtitle(&work.get_title()); self.save_button.set_sensitive(true); } diff --git a/musicus/src/editors/work.rs b/musicus/src/editors/work.rs index c13a256..a053d92 100644 --- a/musicus/src/editors/work.rs +++ b/musicus/src/editors/work.rs @@ -7,7 +7,6 @@ use adw::prelude::*; use anyhow::Result; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::{generate_id, Instrument, Person, Work, WorkPart, WorkSection}; use std::cell::RefCell; @@ -163,7 +162,7 @@ impl Screen, Work> for WorkEditor { })); let row = adw::ActionRow::new(); - row.set_title(Some(&instrument.name)); + row.set_title(&instrument.name); row.add_suffix(&delete_button); row.upcast() @@ -235,7 +234,7 @@ impl Screen, Work> for WorkEditor { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&pos.get_title())); + row.set_title(&pos.get_title()); row.add_suffix(&delete_button); row.add_suffix(&edit_button); row.set_activatable_widget(Some(&edit_button)); @@ -303,8 +302,8 @@ impl Screen, Work> for WorkEditor { impl WorkEditor { /// Update the UI according to person. fn show_composer(&self, person: &Person) { - self.composer_row.set_title(Some(&gettext("Composer"))); - self.composer_row.set_subtitle(Some(&person.name_fl())); + self.composer_row.set_title(&gettext("Composer")); + self.composer_row.set_subtitle(&person.name_fl()); self.validate(); } diff --git a/musicus/src/import/import_screen.rs b/musicus/src/import/import_screen.rs index 98d2223..54292fa 100644 --- a/musicus/src/import/import_screen.rs +++ b/musicus/src/import/import_screen.rs @@ -5,7 +5,6 @@ use crate::selectors::MediumSelector; use crate::widgets::Widget; use adw::prelude::*; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::Medium; use musicus_backend::import::ImportSession; @@ -47,7 +46,7 @@ impl ImportScreen { } } Err(err) => { - this.error_row.set_subtitle(Some(&err.to_string())); + this.error_row.set_subtitle(&err.to_string()); this.matching_stack.set_visible_child_name("error"); } } diff --git a/musicus/src/import/medium_editor.rs b/musicus/src/import/medium_editor.rs index 7699d7c..5159fc6 100644 --- a/musicus/src/import/medium_editor.rs +++ b/musicus/src/import/medium_editor.rs @@ -4,8 +4,6 @@ use crate::widgets::{List, Widget}; use adw::prelude::*; use anyhow::Result; use glib::clone; -use glib::prelude::*; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::{generate_id, Medium, Track}; use musicus_backend::import::ImportSession; @@ -122,8 +120,8 @@ impl Screen<(Arc, Option), Medium> for MediumEditor { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&title)); - row.set_subtitle(Some(&subtitle)); + row.set_title(&title); + row.set_subtitle(&subtitle); row.add_suffix(&edit_button); row.set_activatable_widget(Some(&edit_button)); diff --git a/musicus/src/import/track_editor.rs b/musicus/src/import/track_editor.rs index 8fe9d50..993204a 100644 --- a/musicus/src/import/track_editor.rs +++ b/musicus/src/import/track_editor.rs @@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use adw::prelude::*; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::Recording; use std::cell::RefCell; @@ -69,7 +68,7 @@ impl Screen<(Recording, Vec), Vec> for TrackEditor { let row = adw::ActionRow::new(); row.add_prefix(&check); row.set_activatable_widget(Some(&check)); - row.set_title(Some(&part.title)); + row.set_title(&part.title); parts_list.append(&row); } diff --git a/musicus/src/import/track_selector.rs b/musicus/src/import/track_selector.rs index 0812ce1..47ec2f4 100644 --- a/musicus/src/import/track_selector.rs +++ b/musicus/src/import/track_selector.rs @@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use adw::prelude::*; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::import::ImportSession; use std::cell::RefCell; @@ -80,7 +79,7 @@ impl Screen, Vec> for TrackSelector { row.add_prefix(&check); row.set_activatable_widget(Some(&check)); row.set_activatable(true); - row.set_title(Some(&track.name)); + row.set_title(&track.name); track_list.append(&row); } diff --git a/musicus/src/import/track_set_editor.rs b/musicus/src/import/track_set_editor.rs index 9f4c815..94e1a05 100644 --- a/musicus/src/import/track_set_editor.rs +++ b/musicus/src/import/track_set_editor.rs @@ -6,7 +6,6 @@ use crate::widgets::{List, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::Recording; use musicus_backend::import::ImportSession; @@ -147,8 +146,8 @@ impl Screen, TrackSetData> for TrackSetEditor { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&title)); - row.set_subtitle(Some(track_name)); + row.set_title(&title); + row.set_subtitle(track_name); row.add_suffix(&edit_button); row.set_activatable_widget(Some(&edit_button)); @@ -183,10 +182,8 @@ impl TrackSetEditor { /// Set everything up after selecting a recording. fn recording_selected(&self) { if let Some(recording) = &*self.recording.borrow() { - self.recording_row - .set_title(Some(&recording.work.get_title())); - self.recording_row - .set_subtitle(Some(&recording.get_performers())); + self.recording_row.set_title(&recording.work.get_title()); + self.recording_row.set_subtitle(&recording.get_performers()); self.save_button.set_sensitive(true); } diff --git a/musicus/src/navigator/window.rs b/musicus/src/navigator/window.rs index 2022847..39a2cfa 100644 --- a/musicus/src/navigator/window.rs +++ b/musicus/src/navigator/window.rs @@ -1,6 +1,6 @@ use super::Navigator; +use adw::prelude::*; use glib::clone; -use gtk::prelude::*; use musicus_backend::Backend; use std::rc::Rc; @@ -17,7 +17,7 @@ impl NavigatorWindow { window.set_default_size(600, 424); let placeholder = gtk::Label::new(None); let navigator = Navigator::new(backend, &window, &placeholder); - adw::prelude::WindowExt::set_child(&window, Some(&navigator.widget)); + window.set_content(Some(&navigator.widget)); let this = Rc::new(Self { navigator, window }); diff --git a/musicus/src/preferences/mod.rs b/musicus/src/preferences/mod.rs index d5b6d34..98524b4 100644 --- a/musicus/src/preferences/mod.rs +++ b/musicus/src/preferences/mod.rs @@ -2,7 +2,6 @@ use crate::navigator::NavigatorWindow; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::Backend; use std::rc::Rc; @@ -66,7 +65,7 @@ impl Preferences { if let gtk::ResponseType::Accept = response { if let Some(file) = dialog.file() { if let Some(path) = file.path() { - this.music_library_path_row.set_subtitle(Some(path.to_str().unwrap())); + this.music_library_path_row.set_subtitle(path.to_str().unwrap()); spawn!(@clone this, async move { this.backend.set_music_library_path(path).await.unwrap(); @@ -85,7 +84,7 @@ impl Preferences { let dialog = ServerDialog::new(this.backend.clone(), &this.window); dialog.set_selected_cb(clone!(@strong this => move |url| { - this.url_row.set_subtitle(Some(&url)); + this.url_row.set_subtitle(&url); })); dialog.show(); @@ -98,9 +97,9 @@ impl Preferences { spawn!(@clone this, async move { if let Some(data) = replace!(window.navigator, LoginDialog, this.backend.get_login_data()).await { if let Some(data) = data { - this.login_row.set_subtitle(Some(&data.username)); + this.login_row.set_subtitle(&data.username); } else { - this.login_row.set_subtitle(Some(&gettext("Not logged in"))); + this.login_row.set_subtitle(&gettext("Not logged in")); } } }); @@ -110,15 +109,15 @@ impl Preferences { if let Some(path) = this.backend.get_music_library_path() { this.music_library_path_row - .set_subtitle(Some(path.to_str().unwrap())); + .set_subtitle(path.to_str().unwrap()); } if let Some(url) = this.backend.get_server_url() { - this.url_row.set_subtitle(Some(&url)); + this.url_row.set_subtitle(&url); } if let Some(data) = this.backend.get_login_data() { - this.login_row.set_subtitle(Some(&data.username)); + this.login_row.set_subtitle(&data.username); } this diff --git a/musicus/src/preferences/register.rs b/musicus/src/preferences/register.rs index b48c85a..ef8fcdc 100644 --- a/musicus/src/preferences/register.rs +++ b/musicus/src/preferences/register.rs @@ -2,7 +2,6 @@ use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use adw::prelude::*; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::client::{LoginData, UserRegistration}; use std::cell::RefCell; @@ -103,7 +102,7 @@ impl Screen<(), LoginData> for RegisterDialog { spawn!(@clone this, async move { let captcha = this.handle.backend.cl().get_captcha().await.unwrap(); - this.captcha_row.set_title(Some(&captcha.question)); + this.captcha_row.set_title(&captcha.question); this.captcha_id.replace(Some(captcha.id)); this.widget.set_visible_child_name("content"); }); diff --git a/musicus/src/screens/ensemble.rs b/musicus/src/screens/ensemble.rs index 1d58481..6873e5a 100644 --- a/musicus/src/screens/ensemble.rs +++ b/musicus/src/screens/ensemble.rs @@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Ensemble, Medium, Recording}; use std::cell::RefCell; use std::rc::Rc; @@ -77,8 +76,8 @@ impl Screen for EnsembleScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&recording.work.get_title())); - row.set_subtitle(Some(&recording.get_performers())); + row.set_title(&recording.work.get_title()); + row.set_subtitle(&recording.get_performers()); let recording = recording.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -106,7 +105,7 @@ impl Screen for EnsembleScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&medium.name)); + row.set_title(&medium.name); let medium = medium.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/screens/main.rs b/musicus/src/screens/main.rs index 78f77f6..af4fa92 100644 --- a/musicus/src/screens/main.rs +++ b/musicus/src/screens/main.rs @@ -7,7 +7,6 @@ use crate::widgets::{List, PlayerBar, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::PersonOrEnsemble; use std::cell::RefCell; @@ -96,7 +95,7 @@ impl Screen<(), ()> for MainScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&poe.get_title())); + row.set_title(&poe.get_title()); let poe = poe.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/screens/medium.rs b/musicus/src/screens/medium.rs index 3075b5a..f3e4438 100644 --- a/musicus/src/screens/medium.rs +++ b/musicus/src/screens/medium.rs @@ -4,7 +4,6 @@ use crate::widgets::{List, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::Medium; use std::rc::Rc; @@ -80,7 +79,7 @@ impl Screen for MediumScreen { let row = adw::ActionRow::new(); row.set_selectable(false); row.set_activatable(false); - row.set_title(Some(&title)); + row.set_title(&title); row.set_margin_start(12); row.upcast() diff --git a/musicus/src/screens/person.rs b/musicus/src/screens/person.rs index 46d8912..ab99fbb 100644 --- a/musicus/src/screens/person.rs +++ b/musicus/src/screens/person.rs @@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Medium, Person, Recording, Work}; use std::cell::RefCell; use std::rc::Rc; @@ -83,7 +82,7 @@ impl Screen for PersonScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&work.title)); + row.set_title(&work.title); let work = work.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -110,8 +109,8 @@ impl Screen for PersonScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&recording.work.get_title())); - row.set_subtitle(Some(&recording.get_performers())); + row.set_title(&recording.work.get_title()); + row.set_subtitle(&recording.get_performers()); let recording = recording.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -139,7 +138,7 @@ impl Screen for PersonScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&medium.name)); + row.set_title(&medium.name); let medium = medium.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/screens/player.rs b/musicus/src/screens/player.rs index 8c7fbaa..d8b3a2e 100644 --- a/musicus/src/screens/player.rs +++ b/musicus/src/screens/player.rs @@ -3,7 +3,6 @@ use crate::widgets::{List, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use musicus_backend::db::Track; use std::cell::{Cell, RefCell}; @@ -227,7 +226,7 @@ impl Screen<(), ()> for PlayerScreen { let row = adw::ActionRow::new(); row.set_selectable(false); row.set_activatable(true); - row.set_title(Some(&title)); + row.set_title(&title); if first { let subtitle = if !parts.is_empty() { @@ -236,7 +235,7 @@ impl Screen<(), ()> for PlayerScreen { track.recording.get_performers() }; - row.set_subtitle(Some(&subtitle)); + row.set_subtitle(&subtitle); } row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/screens/recording.rs b/musicus/src/screens/recording.rs index 3ea63da..28b0468 100644 --- a/musicus/src/screens/recording.rs +++ b/musicus/src/screens/recording.rs @@ -5,7 +5,6 @@ use crate::widgets::{List, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Recording, Track}; use std::cell::RefCell; use std::rc::Rc; @@ -88,7 +87,7 @@ impl Screen for RecordingScreen { }; let row = adw::ActionRow::new(); - row.set_title(Some(&title)); + row.set_title(&title); row.upcast() })); diff --git a/musicus/src/screens/welcome.rs b/musicus/src/screens/welcome.rs index 3952ec6..b4a64fd 100644 --- a/musicus/src/screens/welcome.rs +++ b/musicus/src/screens/welcome.rs @@ -20,7 +20,7 @@ impl Screen<(), ()> for WelcomeScreen { .build(); let header = adw::HeaderBarBuilder::new() - .title_widget(&adw::WindowTitle::new(Some("Musicus"), None)) + .title_widget(&adw::WindowTitle::new("Musicus", "")) .build(); let button = gtk::ButtonBuilder::new() diff --git a/musicus/src/screens/work.rs b/musicus/src/screens/work.rs index 0ee7fe2..0a35bba 100644 --- a/musicus/src/screens/work.rs +++ b/musicus/src/screens/work.rs @@ -6,7 +6,6 @@ use crate::widgets::{List, Section, Widget}; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Recording, Work}; use std::cell::RefCell; use std::rc::Rc; @@ -72,8 +71,8 @@ impl Screen for WorkScreen { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&recording.work.get_title())); - row.set_subtitle(Some(&recording.get_performers())); + row.set_title(&recording.work.get_title()); + row.set_subtitle(&recording.get_performers()); let recording = recording.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/ensemble.rs b/musicus/src/selectors/ensemble.rs index 6483244..444e62f 100644 --- a/musicus/src/selectors/ensemble.rs +++ b/musicus/src/selectors/ensemble.rs @@ -5,7 +5,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::Ensemble; use std::rc::Rc; @@ -55,7 +54,7 @@ impl Screen<(), Ensemble> for EnsembleSelector { .set_make_widget(clone!(@weak this => @default-panic, move |ensemble| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&ensemble.name)); + row.set_title(&ensemble.name); let ensemble = ensemble.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/instrument.rs b/musicus/src/selectors/instrument.rs index 3d05b87..2ff2cb0 100644 --- a/musicus/src/selectors/instrument.rs +++ b/musicus/src/selectors/instrument.rs @@ -5,7 +5,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::Instrument; use std::rc::Rc; @@ -55,7 +54,7 @@ impl Screen<(), Instrument> for InstrumentSelector { .set_make_widget(clone!(@weak this => @default-panic, move |instrument| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&instrument.name)); + row.set_title(&instrument.name); let instrument = instrument.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/medium.rs b/musicus/src/selectors/medium.rs index 8235e25..d63f406 100644 --- a/musicus/src/selectors/medium.rs +++ b/musicus/src/selectors/medium.rs @@ -4,7 +4,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Medium, PersonOrEnsemble}; use std::rc::Rc; @@ -72,7 +71,7 @@ impl Screen<(), Medium> for MediumSelector { this.selector.set_make_widget(clone!(@weak this => @default-panic, move |poe| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&poe.get_title())); + row.set_title(&poe.get_title()); let poe = poe.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -146,7 +145,7 @@ impl Screen for MediumSelectorMediumScreen { .set_make_widget(clone!(@weak this => @default-panic, move |medium| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&medium.name)); + row.set_title(&medium.name); let medium = medium.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/person.rs b/musicus/src/selectors/person.rs index 7664fd8..4b702d4 100644 --- a/musicus/src/selectors/person.rs +++ b/musicus/src/selectors/person.rs @@ -5,7 +5,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::Person; use std::rc::Rc; @@ -55,7 +54,7 @@ impl Screen<(), Person> for PersonSelector { .set_make_widget(clone!(@weak this => @default-panic, move |person| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&person.name_lf())); + row.set_title(&person.name_lf()); let person = person.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/recording.rs b/musicus/src/selectors/recording.rs index 6b5fb19..5094c11 100644 --- a/musicus/src/selectors/recording.rs +++ b/musicus/src/selectors/recording.rs @@ -5,7 +5,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Person, Recording, Work}; use std::rc::Rc; @@ -64,7 +63,7 @@ impl Screen<(), Recording> for RecordingSelector { this.selector.set_make_widget(clone!(@weak this => @default-panic, move |person| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&person.name_lf())); + row.set_title(&person.name_lf()); let person = person.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -145,7 +144,7 @@ impl Screen for RecordingSelectorWorkScreen { .set_make_widget(clone!(@weak this => @default-panic, move |work| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&work.title)); + row.set_title(&work.title); let work = work.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -212,7 +211,7 @@ impl Screen for RecordingSelectorRecordingScreen { .set_make_widget(clone!(@weak this => @default-panic, move |recording| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&recording.get_performers())); + row.set_title(&recording.get_performers()); let recording = recording.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/selectors/selector.rs b/musicus/src/selectors/selector.rs index 07cb268..26089e0 100644 --- a/musicus/src/selectors/selector.rs +++ b/musicus/src/selectors/selector.rs @@ -137,12 +137,12 @@ impl Selector { /// Set the title to be shown in the header. pub fn set_title(&self, title: &str) { - self.title_label.set_label(&title); + self.title_label.set_label(title); } /// Set the subtitle to be shown in the header. pub fn set_subtitle(&self, subtitle: &str) { - self.subtitle_label.set_label(&subtitle); + self.subtitle_label.set_label(subtitle); self.subtitle_label.show(); } diff --git a/musicus/src/selectors/work.rs b/musicus/src/selectors/work.rs index ff4e12c..3ea1afd 100644 --- a/musicus/src/selectors/work.rs +++ b/musicus/src/selectors/work.rs @@ -5,7 +5,6 @@ use crate::widgets::Widget; use adw::prelude::*; use gettextrs::gettext; use glib::clone; -use gtk::prelude::*; use musicus_backend::db::{Person, Work}; use std::rc::Rc; @@ -58,7 +57,7 @@ impl Screen<(), Work> for WorkSelector { this.selector.set_make_widget(clone!(@weak this => @default-panic, move |person| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&person.name_lf())); + row.set_title(&person.name_lf()); let person = person.to_owned(); row.connect_activated(clone!(@weak this => move |_| { @@ -135,7 +134,7 @@ impl Screen for WorkSelectorWorkScreen { .set_make_widget(clone!(@weak this => @default-panic, move |work| { let row = adw::ActionRow::new(); row.set_activatable(true); - row.set_title(Some(&work.title)); + row.set_title(&work.title); let work = work.to_owned(); row.connect_activated(clone!(@weak this => move |_| { diff --git a/musicus/src/widgets/button_row.rs b/musicus/src/widgets/button_row.rs index aee26e8..4741d6b 100644 --- a/musicus/src/widgets/button_row.rs +++ b/musicus/src/widgets/button_row.rs @@ -1,6 +1,5 @@ use super::Widget; use adw::prelude::*; -use gtk::prelude::*; /// A list box row with a single button. pub struct ButtonRow { @@ -31,7 +30,7 @@ impl ButtonRow { } /// Set the subtitle of the row. - pub fn set_subtitle(&self, subtitle: Option<&str>) { + pub fn set_subtitle(&self, subtitle: &str) { self.widget.set_subtitle(subtitle); } diff --git a/musicus/src/widgets/editor.rs b/musicus/src/widgets/editor.rs index ee0a10f..914013e 100644 --- a/musicus/src/widgets/editor.rs +++ b/musicus/src/widgets/editor.rs @@ -58,7 +58,7 @@ impl Editor { /// Show a title in the header bar. pub fn set_title(&self, title: &str) { - self.window_title.set_title(Some(title)); + self.window_title.set_title(title); } /// Set whether the user should be able to click the save button. @@ -78,7 +78,7 @@ impl Editor { /// Show an error page. The page contains a button to get back to the /// actual editor. pub fn error(&self, title: &str, description: &str) { - self.status_page.set_title(Some(title)); + self.status_page.set_title(title); self.status_page.set_description(Some(description)); self.widget.set_visible_child_name("error"); } diff --git a/musicus/src/widgets/entry_row.rs b/musicus/src/widgets/entry_row.rs index d455e51..493fe5c 100644 --- a/musicus/src/widgets/entry_row.rs +++ b/musicus/src/widgets/entry_row.rs @@ -1,5 +1,4 @@ use adw::prelude::*; -use gtk::prelude::*; /// A list box row with an entry. pub struct EntryRow { diff --git a/musicus/src/widgets/screen.rs b/musicus/src/widgets/screen.rs index 1ff0abd..5bea5ab 100644 --- a/musicus/src/widgets/screen.rs +++ b/musicus/src/widgets/screen.rs @@ -73,12 +73,12 @@ impl Screen { /// Show a title in the header bar. pub fn set_title(&self, title: &str) { - self.window_title.set_title(Some(title)); + self.window_title.set_title(title); } /// Show a subtitle in the header bar. pub fn set_subtitle(&self, subtitle: &str) { - self.window_title.set_subtitle(Some(subtitle)); + self.window_title.set_subtitle(subtitle); } /// Add a new item to the action menu and register a callback for it. diff --git a/musicus/src/widgets/track_list.rs b/musicus/src/widgets/track_list.rs new file mode 100644 index 0000000..468f833 --- /dev/null +++ b/musicus/src/widgets/track_list.rs @@ -0,0 +1,143 @@ +use super::{List, Widget}; +use gtk::prelude::*; +use glib::clone; +use itertools::Itertools; +use musicus_backend::db::{Recording, Track, Work}; +use std::{cell::RefCell, rc::Rc}; + +/// A widget for displaying a list of tracks. +pub struct TrackList { + tracks: RefCell>, + list: Rc, +} + +impl TrackList { + pub fn new() -> Rc { + let list = List::new(); + + let this = Rc::new(Self { + tracks: RefCell::new(Vec::new()), + list, + }); + + this.list.set_make_widget_cb(clone!(@weak this => move |index| { + this.track_row(index) + })); + + this + } + + fn track_row(&self, index: usize) -> gtk::Widget { + let tracks = self.tracks.borrow(); + let track = &tracks[index]; + + if index > 0 { + let previous_track = &tracks[index - 1]; + if previous_track.recording.id != track.recording.id { + return TrackRow::new + } + } + + + } +} + +impl Widget for TrackList { + fn get_widget(&self) -> gtk::Widget { + self.list.get_widget() + } +} + +/// Create a new separator row. +fn separator() -> gtk::ListBoxRow { + gtk::ListBoxRowBuilder::new() + .selectable(false) + .activatable(false) + .child(>k::Separator::new(gtk::Orientation::Horizontal)) + .build() +} + +/// Return an unfinished builder for a recording row. +fn recording_row(recording: &Recording) -> adw::ActionRowBuilder { + adw::ActionRowBuilder::new() + .title(&recording.work.get_title()) + .subtitle(&recording.get_performers()) +} + +/// Get a string representing the given list of work parts. +fn parts_string(work: &Work, part_indices: &[usize]) -> String { + part_indices + .iter() + .map(|index| work.parts[*index].title.clone()) + .collect::>() + .join(", ") +} + +/// A widget for displaying a single track within a list box. +struct TrackRow { + pub widget: gtk::ListBoxRow, + status_image: gtk::Image, +} + +impl TrackRow { + /// Create a new track row. + /// + /// Depending on the value of `header`, the row will display additional + /// information on the recording. + pub fn new(track: &Track, header: bool) -> Self { + let widget = gtk::ListBoxRow::new(); + let content = gtk::Box::new(gtk::Orientation::Horizontal, 6); + + let status_image = gtk::Image::from_icon_name(None); + content.append(&status_image); + + if header { + let work_label = gtk::LabelBuilder::new() + .label(&track.recording.work.get_title()) + .css_classes(vec![String::from("heading")]) + .build(); + + let performers_label = gtk::LabelBuilder::new() + .label(&track.recording.get_performers()) + .css_classes(vec![String::from("heading")]) + .margin_bottom(6) + .build(); + + let labels = gtk::Box::new(gtk::Orientation::Vertical, 0); + labels.append(&work_label); + labels.append(&performers_label); + + let title = track.title(); + if !title.is_empty() { + let title_label = gtk::Label::new(Some(&track.title())); + labels.append(&title_label); + } + + content.append(&labels); + } else { + content.append(&title_label); + } + + widget.set_child(Some(&content)); + + Self { + widget, + status_image, + } + } + + pub fn set_playing(&self, playing: bool) { + if playing { + self.status_image + .set_from_icon_name(Some("media-playback-start-symbolic")); + } else { + self.status_image.set_from_icon_name(None); + } + } +} + +struct ListItem { + playing: bool, + header: Option<(String, String)>, + title: Option, +} diff --git a/musicus/src/window.rs b/musicus/src/window.rs index 0afe258..af041be 100644 --- a/musicus/src/window.rs +++ b/musicus/src/window.rs @@ -25,7 +25,7 @@ impl Window { .build(); let header = adw::HeaderBarBuilder::new() - .title_widget(&adw::WindowTitle::new(Some("Musicus"), None)) + .title_widget(&adw::WindowTitle::new("Musicus", "")) .build(); let spinner = gtk::SpinnerBuilder::new() @@ -42,7 +42,7 @@ impl Window { loading_screen.append(&spinner); let navigator = Navigator::new(Rc::clone(&backend), &window, &loading_screen); - adw::prelude::ApplicationWindowExt::set_child(&window, Some(&navigator.widget)); + adw::traits::ApplicationWindowExt::set_content(&window, Some(&navigator.widget)); let this = Rc::new(Self { backend,