diff --git a/Cargo.lock b/Cargo.lock index 184700e..6101988 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,12 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "field-offset" version = "0.3.6" @@ -512,6 +518,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "malloc_buf" version = "0.0.6" @@ -543,6 +555,19 @@ dependencies = [ "gettext-rs", "gtk4", "libadwaita", + "log", + "once_cell", + "tracing-subscriber", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", ] [[package]] @@ -580,6 +605,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "pango" version = "0.17.10" @@ -723,6 +754,15 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "slab" version = "0.4.8" @@ -805,6 +845,16 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "toml" version = "0.7.4" @@ -839,12 +889,53 @@ dependencies = [ "winnow", ] +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + [[package]] name = "unicode-ident" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version-compare" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index a9a4ae7..8786865 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +adw = { package = "libadwaita", version = "0.4", features = ["v1_4"]} gettext-rs = { version = "0.7", features = ["gettext-system"] } -gtk = { version = "0.6", package = "gtk4" } - -[dependencies.adw] -package = "libadwaita" -version = "0.4" -features = ["v1_4"] +gtk = { package = "gtk4", version = "0.6", features = ["v4_10"]} +log = "0.4" +once_cell = "1" +tracing-subscriber = "0.3" \ No newline at end of file diff --git a/data/res/welcome_page.blp b/data/res/welcome_page.blp index 72db0ca..dffc4f9 100644 --- a/data/res/welcome_page.blp +++ b/data/res/welcome_page.blp @@ -3,6 +3,7 @@ using Adw 1; template $MusicusWelcomePage : Adw.NavigationPage { title: _("Welcome to Musicus"); + tag: "welcome"; Adw.ToolbarView { [top] @@ -18,10 +19,11 @@ template $MusicusWelcomePage : Adw.NavigationPage { icon-name: "de.johrpan.musicus"; title: _("Welcome to Musicus"); description: _("Get started by choosing where to store your music library. Is this your first time using Musicus? If so, create a new empty folder for your library. Musicus will use this location to manage your recordings. You can also select a folder that already contains a music library created by Musicus."); - child: Gtk.Button choose_library_button { + child: Gtk.Button { styles ["suggested-action", "pill"] halign: center; label: _("Choose library folder"); + clicked => $choose_library_folder() swapped; }; } } diff --git a/data/res/window.blp b/data/res/window.blp index 208ad21..274a1d3 100644 --- a/data/res/window.blp +++ b/data/res/window.blp @@ -6,5 +6,9 @@ template $MusicusWindow : Adw.ApplicationWindow { default-width: 800; default-height: 600; - Adw.NavigationView navigation_view {} + Adw.NavigationView navigation_view { + $MusicusWelcomePage { + folder-selected => $set_library_folder() swapped; + } + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4316e90..d2afe79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,8 @@ use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain}; use gtk::{gio, glib, prelude::*}; fn main() -> glib::ExitCode { + tracing_subscriber::fmt::init(); + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8") .expect("Unable to set the text domain encoding"); diff --git a/src/welcome_page.rs b/src/welcome_page.rs index 4086d84..65090fa 100644 --- a/src/welcome_page.rs +++ b/src/welcome_page.rs @@ -1,15 +1,14 @@ use adw::subclass::{navigation_page::NavigationPageImpl, prelude::*}; -use gtk::glib; +use gettextrs::gettext; +use gtk::{gio, glib, glib::subclass::Signal, prelude::*}; +use once_cell::sync::Lazy; mod imp { use super::*; #[derive(Debug, Default, gtk::CompositeTemplate)] #[template(resource = "/de/johrpan/musicus/welcome_page.ui")] - pub struct MusicusWelcomePage { - #[template_child] - pub choose_library_button: TemplateChild, - } + pub struct MusicusWelcomePage {} #[glib::object_subclass] impl ObjectSubclass for MusicusWelcomePage { @@ -19,6 +18,7 @@ mod imp { fn class_init(klass: &mut Self::Class) { klass.bind_template(); + klass.bind_template_instance_callbacks(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -26,7 +26,18 @@ mod imp { } } - impl ObjectImpl for MusicusWelcomePage {} + impl ObjectImpl for MusicusWelcomePage { + fn signals() -> &'static [Signal] { + static SIGNALS: Lazy> = Lazy::new(|| { + vec![Signal::builder("folder-selected") + .param_types([gio::File::static_type()]) + .build()] + }); + + SIGNALS.as_ref() + } + } + impl WidgetImpl for MusicusWelcomePage {} impl NavigationPageImpl for MusicusWelcomePage {} } @@ -36,8 +47,35 @@ glib::wrapper! { @extends gtk::Widget, adw::NavigationPage; } +#[gtk::template_callbacks] impl MusicusWelcomePage { pub fn new() -> Self { glib::Object::new() } + + #[template_callback] + async fn choose_library_folder(&self, _: >k::Button) { + let dialog = gtk::FileDialog::builder() + .title(gettext("Select music library folder")) + .modal(true) + .build(); + + match dialog + .select_folder_future( + self.root() + .as_ref() + .and_then(|r| r.downcast_ref::()), + ) + .await + { + Err(err) => { + if !err.matches(gtk::DialogError::Dismissed) { + log::error!("Folder selection failed: {err}"); + } + } + Ok(folder) => { + self.emit_by_name::<()>("folder-selected", &[&folder]); + } + } + } } diff --git a/src/window.rs b/src/window.rs index 44affd9..c00fa4c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,7 +1,7 @@ use crate::welcome_page::MusicusWelcomePage; use adw::subclass::prelude::*; -use gtk::{gio, glib}; +use gtk::{gio, glib, prelude::*}; mod imp { use super::*; @@ -20,7 +20,9 @@ mod imp { type ParentType = adw::ApplicationWindow; fn class_init(klass: &mut Self::Class) { + MusicusWelcomePage::static_type(); klass.bind_template(); + klass.bind_template_instance_callbacks(); } fn instance_init(obj: &glib::subclass::InitializingObject) { @@ -31,8 +33,6 @@ mod imp { impl ObjectImpl for MusicusWindow { fn constructed(&self) { self.parent_constructed(); - - self.navigation_view.add(&MusicusWelcomePage::new()); } } @@ -48,10 +48,17 @@ glib::wrapper! { @implements gio::ActionGroup, gio::ActionMap; } +#[gtk::template_callbacks] impl MusicusWindow { pub fn new>(application: &P) -> Self { glib::Object::builder() .property("application", application) .build() } + + #[template_callback] + async fn set_library_folder(&self, folder: &gio::File) { + let path = folder.path(); + log::info!("{path:?}"); + } }