From 9489aaf2ee6e19f39b91f9cd56e26f134ef6455d Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Fri, 3 Nov 2023 16:22:58 +0100 Subject: [PATCH] player bar: hook up controls --- data/ui/player_bar.blp | 2 ++ src/player.rs | 25 +++++++++++++++ src/player_bar.rs | 73 +++++++++++++++++++++++++++++++----------- 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/data/ui/player_bar.blp b/data/ui/player_bar.blp index a7d89d5..bd9aaea 100644 --- a/data/ui/player_bar.blp +++ b/data/ui/player_bar.blp @@ -36,6 +36,7 @@ template $MusicusPlayerBar : Gtk.Box { styles ["circular", "flat"] valign: center; icon-name: "media-skip-backward-symbolic"; + clicked => $previous() swapped; } Gtk.ToggleButton playlist_button { @@ -49,6 +50,7 @@ template $MusicusPlayerBar : Gtk.Box { styles ["circular", "flat"] valign: center; icon-name: "media-skip-forward-symbolic"; + clicked => $next() swapped; } } diff --git a/src/player.rs b/src/player.rs index ce52ee7..8cb12ab 100644 --- a/src/player.rs +++ b/src/player.rs @@ -16,6 +16,12 @@ mod imp { pub playlist: OnceCell, #[property(get, set = Self::set_current_index)] pub current_index: Cell, + #[property(get, set)] + pub current_time: Cell, + #[property(get, set)] + pub remaining_time: Cell, + #[property(get, set = Self::set_position)] + pub position: Cell, } impl MusicusPlayer { @@ -36,6 +42,10 @@ mod imp { .set_is_playing(true); } } + + pub fn set_position(&self, position: f64) { + self.position.set(position); + } } #[glib::object_subclass] @@ -59,6 +69,9 @@ impl MusicusPlayer { .property("playing", false) .property("playlist", gio::ListStore::new::()) .property("current-index", 0u32) + .property("current-time", 0u32) + .property("remaining-time", 10000u32) + .property("position", 0.0) .build() } @@ -88,6 +101,18 @@ impl MusicusPlayer { .item(imp.current_index.get()) .and_downcast::() } + + pub fn next(&self) { + if self.current_index() < self.playlist().n_items() - 1 { + self.set_current_index(self.current_index() + 1); + } + } + + pub fn previous(&self) { + if self.current_index() > 0 { + self.set_current_index(self.current_index() - 1); + } + } } impl Default for MusicusPlayer { diff --git a/src/player_bar.rs b/src/player_bar.rs index b788089..fa0b4bc 100644 --- a/src/player_bar.rs +++ b/src/player_bar.rs @@ -1,6 +1,6 @@ use crate::player::MusicusPlayer; use gtk::{ - glib::{self, subclass::Signal, Properties}, + glib::{self, clone, subclass::Signal, Properties}, prelude::*, subclass::prelude::*, }; @@ -37,6 +37,28 @@ mod imp { pub remaining_time_label: TemplateChild, } + impl PlayerBar { + fn update(&self) { + if let Some(item) = self.player.borrow().current_item() { + let mut title = item.title(); + + if let Some(part_title) = item.part_title() { + title.push_str(": "); + title.push_str(&part_title); + } + + self.title_label.set_label(&title); + + if let Some(performances) = item.performers() { + self.subtitle_label.set_label(&performances); + self.subtitle_label.set_visible(true); + } else { + self.subtitle_label.set_visible(false); + } + } + } + } + #[glib::object_subclass] impl ObjectSubclass for PlayerBar { const NAME: &'static str = "MusicusPlayerBar"; @@ -82,27 +104,30 @@ mod imp { .sync_create() .build(); - let title_label = self.title_label.get(); - let subtitle_label = self.subtitle_label.get(); - player.connect_current_index_notify(move |player| { - if let Some(item) = player.current_item() { - let mut title = item.title(); + let obj = self.obj().clone(); - if let Some(part_title) = item.part_title() { - title.push_str(": "); - title.push_str(&part_title); - } + player.connect_current_index_notify(clone!(@weak obj => move |_| obj.imp().update())); + player + .playlist() + .connect_items_changed(clone!(@weak obj => move |_, _, _, _| obj.imp().update())); - title_label.set_label(&title); + player + .bind_property("current-time", &self.current_time_label.get(), "label") + .transform_to(|_, t: u32| Some(format!("{:0>2}:{:0>2}", t / 60, t % 60))) + .sync_create() + .build(); - if let Some(performances) = item.performers() { - subtitle_label.set_label(&performances); - subtitle_label.set_visible(true); - } else { - subtitle_label.set_visible(false); - } - } - }); + player + .bind_property("remaining-time", &self.remaining_time_label.get(), "label") + .transform_to(|_, t: u32| Some(format!("{:0>2}:{:0>2}", t / 60, t % 60))) + .sync_create() + .build(); + + player + .bind_property("position", &self.slider.adjustment(), "value") + .sync_create() + .bidirectional() + .build(); } } @@ -137,11 +162,21 @@ impl PlayerBar { self.imp().playlist_button.set_active(false); } + #[template_callback] + fn previous(&self, _: >k::Button) { + self.player().previous(); + } + #[template_callback] fn show_playlist(&self, button: >k::ToggleButton) { self.emit_by_name::<()>("show-playlist", &[&button.is_active()]); } + #[template_callback] + fn next(&self, _: >k::Button) { + self.player().next(); + } + #[template_callback] fn play_pause(&self, _: >k::Button) { let player = self.player();