From afa27dbb6ae397d2d3a9095aceebdebaed8b8294 Mon Sep 17 00:00:00 2001 From: Erica Z Date: Sun, 1 Dec 2024 00:24:38 +0100 Subject: [PATCH] split off album carousel album into its own class --- resources/album_carousel.blp | 56 +++--------------------------- resources/album_carousel_album.blp | 54 ++++++++++++++++++++++++++++ resources/audrey.gresource.xml | 1 + resources/meson.build | 2 ++ src/ui/album_carousel.rs | 23 ++++++++++++ src/ui/album_carousel/album.rs | 54 ++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 52 deletions(-) create mode 100644 resources/album_carousel_album.blp create mode 100644 src/ui/album_carousel/album.rs diff --git a/resources/album_carousel.blp b/resources/album_carousel.blp index 9089e4c..74fd5d4 100644 --- a/resources/album_carousel.blp +++ b/resources/album_carousel.blp @@ -80,58 +80,10 @@ template $AudreyUiAlbumCarousel: Adw.Bin { model: bind template.model; }; - factory: BuilderListItemFactory { - template ListItem { - child: Box { - styles [ - "album" - ] - - orientation: vertical; - margin-bottom: 6; - spacing: 6; - - Image { - icon-name: "media-optical-cd"; - pixel-size: 160; - halign: center; - hexpand: false; - } - - Box { - styles [ - "labels" - ] - - orientation: vertical; - homogeneous: true; - - Label { - single-line-mode: true; - label: bind template.item as <$AudreyModelAlbum>.name; - ellipsize: end; - xalign: 0; - margin-start: 6; - - styles [ - "heading" - ] - } - - Label { - single-line-mode: true; - label: bind template.item as <$AudreyModelAlbum>.artist; - ellipsize: end; - xalign: 0; - margin-start: 6; - - styles [ - "caption" - ] - } - } - }; - } + factory: SignalListItemFactory { + setup => $on_setup() swapped; + bind => $on_bind() swapped; + unbind => $on_unbind() swapped; }; }; } diff --git a/resources/album_carousel_album.blp b/resources/album_carousel_album.blp new file mode 100644 index 0000000..a2f511b --- /dev/null +++ b/resources/album_carousel_album.blp @@ -0,0 +1,54 @@ +using Gtk 4.0; +using Adw 1; + +template $AudreyUiAlbumCarouselAlbum: Adw.Bin { + child: Box { + styles [ + "album" + ] + + orientation: vertical; + margin-bottom: 6; + spacing: 6; + + Image { + icon-name: "media-optical-cd"; + pixel-size: 160; + halign: center; + hexpand: false; + } + + Box { + styles [ + "labels" + ] + + orientation: vertical; + homogeneous: true; + + Label { + single-line-mode: true; + label: bind template.item as <$AudreyModelAlbum>.name; + ellipsize: end; + xalign: 0; + margin-start: 6; + + styles [ + "heading" + ] + } + + Label { + single-line-mode: true; + label: bind template.item as <$AudreyModelAlbum>.artist; + ellipsize: end; + xalign: 0; + margin-start: 6; + + styles [ + "caption" + ] + } + } + }; +} diff --git a/resources/audrey.gresource.xml b/resources/audrey.gresource.xml index 99d581c..03253fa 100644 --- a/resources/audrey.gresource.xml +++ b/resources/audrey.gresource.xml @@ -8,6 +8,7 @@ style.css gtk/help-overlay.ui album_carousel.ui + album_carousel_album.ui play_queue.ui play_queue_song.ui playbar.ui diff --git a/resources/meson.build b/resources/meson.build index 763eb97..2019e86 100644 --- a/resources/meson.build +++ b/resources/meson.build @@ -2,6 +2,7 @@ blueprints = custom_target( 'blueprints', input: files( 'album_carousel.blp', + 'album_carousel_album.blp', 'play_queue.blp', 'play_queue_song.blp', 'playbar.blp', @@ -10,6 +11,7 @@ blueprints = custom_target( ), output: [ 'album_carousel.ui', + 'album_carousel_album.ui', 'play_queue.ui', 'play_queue_song.ui', 'playbar.ui', diff --git a/src/ui/album_carousel.rs b/src/ui/album_carousel.rs index 3f2cd05..360cea5 100644 --- a/src/ui/album_carousel.rs +++ b/src/ui/album_carousel.rs @@ -1,3 +1,7 @@ +mod album; +pub use album::Album; + +use crate::model; use crate::subsonic::AlbumListType; use adw::prelude::*; use adw::subclass::prelude::*; @@ -142,6 +146,25 @@ mod imp { } }); } + + #[template_callback] + pub fn on_setup(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) { + let child: super::Album = glib::Object::new(); + item.set_child(Some(&child)); + } + + #[template_callback] + pub fn on_bind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) { + let child: super::Album = item.child().and_downcast().unwrap(); + let album: model::Album = item.item().and_downcast().unwrap(); + child.bind(&album); + } + + #[template_callback] + pub fn on_unbind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) { + let child: super::Album = item.child().and_downcast().unwrap(); + child.unbind(); + } } } diff --git a/src/ui/album_carousel/album.rs b/src/ui/album_carousel/album.rs new file mode 100644 index 0000000..463ba93 --- /dev/null +++ b/src/ui/album_carousel/album.rs @@ -0,0 +1,54 @@ +use crate::model; +use adw::{prelude::*, subclass::prelude::*}; +use glib::subclass::InitializingObject; +use std::cell::RefCell; + +mod imp { + use super::*; + + #[derive(gtk::CompositeTemplate, glib::Properties, Default)] + #[template(resource = "/eu/callcc/audrey/album_carousel_album.ui")] + #[properties(wrapper_type = super::Album)] + pub struct Album { + #[property(get, set, nullable)] + item: RefCell>, + } + + #[glib::object_subclass] + impl ObjectSubclass for Album { + const NAME: &'static str = "AudreyUiAlbumCarouselAlbum"; + type Type = super::Album; + type ParentType = adw::Bin; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &InitializingObject) { + obj.init_template(); + } + } + + #[glib::derived_properties] + impl ObjectImpl for Album {} + + impl WidgetImpl for Album {} + + impl BinImpl for Album {} +} + +glib::wrapper! { + pub struct Album(ObjectSubclass) + @extends adw::Bin, gtk::Widget, + @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; +} + +impl Album { + pub fn bind(&self, album: &model::Album) { + self.set_item(Some(album)); + } + + pub fn unbind(&self) { + self.set_item(None::); + } +}