diff --git a/data/res/home_page.blp b/data/res/home_page.blp new file mode 100644 index 0000000..ae202c9 --- /dev/null +++ b/data/res/home_page.blp @@ -0,0 +1,107 @@ +using Gtk 4.0; +using Adw 1; + +template $MusicusHomePage : Adw.NavigationPage { + title: _("Musicus"); + tag: "home"; + + Adw.ToolbarView { + [top] + Adw.HeaderBar header_bar { + [end] + MenuButton { + icon-name: "open-menu-symbolic"; + menu-model: primary_menu; + } + } + + [top] + Adw.Clamp { + maximum-size: 1000; + tightening-threshold: 600; + + Adw.Bin { + styles ["searchbar"] + + Gtk.SearchEntry search_entry { + placeholder-text: _("Enter composers, performers, works…"); + } + } + } + + Gtk.ScrolledWindow { + hscrollbar-policy: never; + + Adw.Clamp { + maximum-size: 1000; + tightening-threshold: 600; + + Gtk.Box { + orientation: vertical; + margin-start: 12; + margin-end: 12; + margin-top: 24; + + Gtk.Label { + styles ["heading"] + visible: bind persons_flow_box.visible; + halign: start; + label: _("Composers and performers"); + } + + Gtk.FlowBox persons_flow_box { + margin-top: 12; + margin-bottom: 24; + column-spacing: 14; + row-spacing: 14; + homogeneous: true; + selection-mode: none; + } + + Gtk.Label { + styles ["heading"] + visible: bind works_flow_box.visible; + halign: start; + label: _("Works"); + } + + Gtk.FlowBox works_flow_box { + margin-top: 12; + margin-bottom: 24; + column-spacing: 14; + row-spacing: 14; + homogeneous: true; + selection-mode: none; + } + + Gtk.Label { + styles ["heading"] + visible: bind recordings_flow_box.visible; + halign: start; + label: _("Recordings"); + } + + Gtk.FlowBox recordings_flow_box { + margin-top: 12; + margin-bottom: 24; + column-spacing: 14; + row-spacing: 14; + homogeneous: true; + selection-mode: none; + } + } + } + } + } +} + +menu primary_menu { + item { + label: _("_Preferences"); + action: "app.preferences"; + } + item { + label: _("_About Musicus"); + action: "app.about"; + } +} \ No newline at end of file diff --git a/data/res/meson.build b/data/res/meson.build index 8c497f2..910b91b 100644 --- a/data/res/meson.build +++ b/data/res/meson.build @@ -3,6 +3,8 @@ gnome = import('gnome') blueprints = custom_target('blueprints', input: files( + 'home_page.blp', + 'tile.blp', 'welcome_page.blp', 'window.blp' ), diff --git a/data/res/musicus.gresource.xml b/data/res/musicus.gresource.xml index fbd2760..2417a98 100644 --- a/data/res/musicus.gresource.xml +++ b/data/res/musicus.gresource.xml @@ -1,7 +1,10 @@ + home_page.ui + tile.ui welcome_page.ui window.ui + style.css diff --git a/data/res/style.css b/data/res/style.css new file mode 100644 index 0000000..82485bf --- /dev/null +++ b/data/res/style.css @@ -0,0 +1,3 @@ +.searchbar { + padding: 6px 6px 7px 6px; +} \ No newline at end of file diff --git a/data/res/tile.blp b/data/res/tile.blp new file mode 100644 index 0000000..531490c --- /dev/null +++ b/data/res/tile.blp @@ -0,0 +1,39 @@ +using Gtk 4.0; +using Adw 1; + +template $MusicusTile : Gtk.FlowBoxChild { + styles ["card", "activatable"] + width-request: 200; + + Gtk.Box { + orientation: vertical; + margin-start: 6; + margin-end: 6; + margin-top: 6; + margin-bottom: 6; + + Gtk.Label title_label { + styles ["caption-heading"] + halign: start; + label: _("Title"); + } + + Gtk.Label subtitle_label { + styles ["caption"] + halign: start; + label: _("Subtitle"); + } + } +} + +menu item_menu { + item { + label: _("_Play"); + } + item { + label: _("_Edit"); + } + item { + label: _("_Delete"); + } +} \ No newline at end of file diff --git a/data/res/window.blp b/data/res/window.blp index 274a1d3..47e97e2 100644 --- a/data/res/window.blp +++ b/data/res/window.blp @@ -10,5 +10,7 @@ template $MusicusWindow : Adw.ApplicationWindow { $MusicusWelcomePage { folder-selected => $set_library_folder() swapped; } + + $MusicusHomePage {} } } \ No newline at end of file diff --git a/po/POTFILES b/po/POTFILES index bf7baed..e4d06c8 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,3 +1,5 @@ +data/res/home_page.blp +data/res/tile.blp data/res/welcome_page.blp data/res/window.blp data/de.johrpan.musicus.desktop.in diff --git a/src/home_page.rs b/src/home_page.rs new file mode 100644 index 0000000..66ceece --- /dev/null +++ b/src/home_page.rs @@ -0,0 +1,64 @@ +use adw::subclass::{navigation_page::NavigationPageImpl, prelude::*}; +use gtk::glib; + +mod imp { + use crate::tile::MusicusTile; + + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate)] + #[template(resource = "/de/johrpan/musicus/home_page.ui")] + pub struct MusicusHomePage { + #[template_child] + pub search_entry: TemplateChild, + #[template_child] + pub persons_flow_box: TemplateChild, + #[template_child] + pub works_flow_box: TemplateChild, + #[template_child] + pub recordings_flow_box: TemplateChild, + } + + #[glib::object_subclass] + impl ObjectSubclass for MusicusHomePage { + const NAME: &'static str = "MusicusHomePage"; + type Type = super::MusicusHomePage; + type ParentType = adw::NavigationPage; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for MusicusHomePage { + fn constructed(&self) { + self.parent_constructed(); + self.search_entry + .set_key_capture_widget(Some(self.obj().as_ref())); + + for _ in 0..9 { + self.persons_flow_box.append(&MusicusTile::new()); + self.works_flow_box.append(&MusicusTile::new()); + self.recordings_flow_box.append(&MusicusTile::new()); + } + } + } + + impl WidgetImpl for MusicusHomePage {} + impl NavigationPageImpl for MusicusHomePage {} +} + +glib::wrapper! { + pub struct MusicusHomePage(ObjectSubclass) + @extends gtk::Widget, adw::NavigationPage; +} + +impl MusicusHomePage { + pub fn new() -> Self { + glib::Object::new() + } +} diff --git a/src/main.rs b/src/main.rs index d2afe79..58cf09f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ mod application; mod config; +mod home_page; +mod tile; mod welcome_page; mod window; diff --git a/src/tile.rs b/src/tile.rs new file mode 100644 index 0000000..399a117 --- /dev/null +++ b/src/tile.rs @@ -0,0 +1,39 @@ +use gtk::{glib, subclass::prelude::*}; + +mod imp { + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate)] + #[template(resource = "/de/johrpan/musicus/tile.ui")] + pub struct MusicusTile {} + + #[glib::object_subclass] + impl ObjectSubclass for MusicusTile { + const NAME: &'static str = "MusicusTile"; + type Type = super::MusicusTile; + type ParentType = gtk::FlowBoxChild; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for MusicusTile {} + impl WidgetImpl for MusicusTile {} + impl FlowBoxChildImpl for MusicusTile {} +} + +glib::wrapper! { + pub struct MusicusTile(ObjectSubclass) + @extends gtk::Widget, gtk::FlowBoxChild; +} + +impl MusicusTile { + pub fn new() -> Self { + glib::Object::new() + } +} diff --git a/src/window.rs b/src/window.rs index c00fa4c..31bca63 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,4 +1,4 @@ -use crate::welcome_page::MusicusWelcomePage; +use crate::{welcome_page::MusicusWelcomePage, home_page::MusicusHomePage}; use adw::subclass::prelude::*; use gtk::{gio, glib, prelude::*}; @@ -20,6 +20,7 @@ mod imp { type ParentType = adw::ApplicationWindow; fn class_init(klass: &mut Self::Class) { + MusicusHomePage::static_type(); MusicusWelcomePage::static_type(); klass.bind_template(); klass.bind_template_instance_callbacks(); @@ -60,5 +61,6 @@ impl MusicusWindow { async fn set_library_folder(&self, folder: &gio::File) { let path = folder.path(); log::info!("{path:?}"); + self.imp().navigation_view.replace_with_tags(&["home"]); } }