From dc9315cbe3e425945cc75f050680ec8d51ba2af5 Mon Sep 17 00:00:00 2001 From: "Jakob L. Kreuze" Date: Fri, 5 Aug 2022 21:47:00 -0400 Subject: Add TunesSongObject --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ee6dd60..1fe4e4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -897,6 +897,7 @@ dependencies = [ "gtk", "libhandy", "mpd", + "once_cell", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cdf2a5a..e05015c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ futures = "0.3" gtk = "0.15" libhandy = "0.9" mpd = { path = "../mpd" } +once_cell = "1.13" diff --git a/src/main.rs b/src/main.rs index 98a13f9..f4e30f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -131,6 +131,114 @@ impl AsRef for SongInfo { } } +glib::wrapper! { + pub struct SongObject(ObjectSubclass); +} + +impl SongObject { + pub fn new(song: &mpd::song::Song) -> Self { + glib::Object::new(&[ + ( + "title", + &song + .name + .as_ref() + .map(|x| x.clone()) + .unwrap_or_else(|| "[Untitled]".into()), + ), + ( + "artist", + &song + .artist + .as_ref() + .map(|x| x.clone()) + .unwrap_or_else(|| "[No Artist]".into()), + ), + ( + "album", + &song + .tags + .get("Album") + .map(|x| x.clone()) + .unwrap_or_else(|| "[Untitled]".into()), + ), + ]) + .expect("Failed to create `SongObject`.") + } +} + +mod imp { + use std::cell::RefCell; + + use glib::{ParamSpec, ParamSpecString, Value}; + use gtk::glib; + use gtk::prelude::*; + use gtk::subclass::prelude::*; + use once_cell::sync::Lazy; + + // Object holding the state + #[derive(Default)] + pub struct SongObject { + title: RefCell, + artist: RefCell, + album: RefCell, + } + + // The central trait for subclassing a GObject + #[glib::object_subclass] + impl ObjectSubclass for SongObject { + const NAME: &'static str = "TunesSongObject"; + type Type = super::SongObject; + } + + // Trait shared by all GObjects + impl ObjectImpl for SongObject { + fn properties() -> &'static [ParamSpec] { + static PROPERTIES: Lazy> = Lazy::new(|| { + vec![ + ParamSpecString::builder("title").build(), + ParamSpecString::builder("artist").build(), + ParamSpecString::builder("album").build(), + ] + }); + PROPERTIES.as_ref() + } + + fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) { + match pspec.name() { + "title" => { + let input_number = value + .get() + .expect("The value needs to be of type `String`."); + self.title.replace(input_number); + } + "artist" => { + let input_number = value + .get() + .expect("The value needs to be of type `String`."); + self.title.replace(input_number); + } + "album" => { + let input_number = value + .get() + .expect("The value needs to be of type `String`."); + self.title.replace(input_number); + } + _ => unimplemented!(), + } + } + + fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { + match pspec.name() { + "title" => self.title.borrow().to_value(), + "artist" => self.artist.borrow().to_value(), + "album" => self.album.borrow().to_value(), + _ => unimplemented!(), + } + } + } +} + fn main() { let application = gtk::Application::builder() .application_id("space.jakob.Tunes") -- cgit v1.3