mod imp { use adw::prelude::*; use adw::subclass::prelude::*; use glib::subclass::InitializingObject; use glib::{gformat, GString, WeakRef}; use gtk::{gdk, glib}; use std::cell::{Cell, RefCell}; #[derive(glib::Properties, gtk::CompositeTemplate, Default)] #[properties(wrapper_type = super::Playbar)] #[template(resource = "/eu/callcc/audrey/playbar.ui")] pub struct Playbar { #[property(get, set)] song: RefCell>, #[property(get, set)] playing_cover_art: RefCell>, #[property(get, set, default = true)] show_cover_art: Cell, #[property(get, set)] volume: Cell, #[property(get, set)] mute: Cell, #[property(get, set)] position: Cell, #[property(get, set)] duration: Cell, } #[glib::object_subclass] impl ObjectSubclass for Playbar { const NAME: &'static str = "AudreyUiPlaybar"; type Type = super::Playbar; type ParentType = adw::Bin; fn class_init(klass: &mut Self::Class) { klass.bind_template(); klass.bind_template_callbacks(); } fn instance_init(obj: &InitializingObject) { obj.init_template(); } } #[glib::derived_properties] impl ObjectImpl for Playbar {} impl WidgetImpl for Playbar {} impl BinImpl for Playbar {} #[gtk::template_callbacks] impl Playbar { #[template_callback] fn song_title(&self, song: Option<&crate::playbin::Song>) -> Option { song.map(|song| song.title()) } #[template_callback] fn song_artist(&self, song: Option<&crate::playbin::Song>) -> Option { song.map(|song| song.artist()) } #[template_callback] fn song_album(&self, song: Option<&crate::playbin::Song>) -> Option { song.map(|song| song.album()) } #[template_callback] fn format_timestamp(&self, s: f64) -> GString { gformat!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60) } #[template_callback] fn playbin_active(&self, state: crate::playbin::State) -> bool { true // TODO } #[template_callback] fn can_press_play(&self, state: crate::playbin::State, n_items: u32) -> bool { true // TODO } #[template_callback] fn play_pause_icon_name(&self, state: crate::playbin::State) -> &'static str { /* match state { crate::playbin::State::Playing => "media-playback-pause", _ => "media-playback-start", }*/todo!() } #[template_callback] fn mute_button_icon_name(&self, mute: bool) -> &'static str { if mute { "audio-volume-muted" } else { "audio-volume-high" } } #[template_callback] fn on_play_position_seek( &self, _scroll_type: gtk::ScrollType, value: f64, range: >k::Range, ) -> bool { /* let playbin = self.playbin.upgrade().unwrap(); if range.adjustment().lower() < range.adjustment().upper() { playbin.seek(value); } false*/todo!() } #[template_callback] fn on_skip_forward_clicked(&self) { /* let playbin = self.playbin.upgrade().unwrap(); playbin.go_to_next_track();*/todo!() } #[template_callback] fn on_skip_backward_clicked(&self) { /* let playbin = self.playbin.upgrade().unwrap(); playbin.go_to_prev_track();*/todo!() } #[template_callback] fn seek_backward(&self) { /* let playbin = self.playbin.upgrade().unwrap(); // 10 seconds let mut new_position = playbin.position() - 10.0; if new_position < 0.0 { new_position = 0.0; } playbin.seek(new_position);*/todo!() } #[template_callback] fn seek_forward(&self) { /* let playbin = self.playbin.upgrade().unwrap(); // 10 seconds let mut new_position = playbin.position() + 10.0; if new_position > playbin.duration() { new_position = playbin.duration(); } playbin.seek(new_position);*/todo!() } #[template_callback] fn on_play_pause_clicked(&self, _button: >k::Button) { /* let playbin = self.playbin.upgrade().unwrap(); if playbin.state() == crate::playbin::State::Playing { playbin.pause(); } else { playbin.play(); }*/todo!() } #[template_callback] fn on_mute_toggle(&self) { self.obj().set_mute(!self.obj().mute()); } } impl Drop for Playbar { fn drop(&mut self) { println!("dropping AudreyUiPlaybar"); } } } use gtk::glib; glib::wrapper! { pub struct Playbar(ObjectSubclass) @extends adw::Bin, gtk::Widget, @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget; }