From 9528160b030acccd84947d621cc04698227fba68 Mon Sep 17 00:00:00 2001 From: Zander Brown Date: Tue, 29 May 2018 22:38:56 +0100 Subject: [PATCH] Start hooking things up Still doesn't accept input --- hammond-gtk/resources/gtk/playback.ui | 13 ++--- hammond-gtk/src/app.rs | 30 ++++++++--- hammond-gtk/src/widgets/playback.rs | 77 ++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 15 deletions(-) diff --git a/hammond-gtk/resources/gtk/playback.ui b/hammond-gtk/resources/gtk/playback.ui index 0457d68..8f32958 100644 --- a/hammond-gtk/resources/gtk/playback.ui +++ b/hammond-gtk/resources/gtk/playback.ui @@ -28,7 +28,7 @@ 6 - 3 + 1 0 2 @@ -46,13 +46,14 @@ right - 1 + 2 1 2 - + + 60 True True True @@ -79,7 +80,7 @@ label - 1 + 2 0 @@ -92,7 +93,7 @@ label - 2 + 3 0 @@ -100,4 +101,4 @@ - + \ No newline at end of file diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 3dd14cc..ada84ba 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -6,6 +6,7 @@ use gio::{ }; use glib; use gstreamer_player as gst; +use gstreamer::ClockTime; use gtk; use gtk::prelude::*; use gtk::SettingsExt as GtkSettingsExt; @@ -54,7 +55,10 @@ pub enum Action { MarkAllPlayerNotification(Arc), RemoveShow(Arc), ErrorNotification(String), - PlayEpisode(String) + PlayEpisode(String), + PlayerStateChanged(gst::PlayerState), + PlayerMediaChanged(Option, ClockTime), + PlayerPositionChanged(ClockTime), } #[derive(Debug)] @@ -121,11 +125,8 @@ impl App { // Add the overlay to the main window wrap.add(&overlay); - let playback = Playback::new(); - - let reveal = gtk::Revealer::new(); - reveal.add(&playback.container); - wrap.add(&reveal); + let playback = Rc::new(Playback::new()); + wrap.add(playback.get_widget()); WindowGeometry::from_settings(&settings).apply(&window); @@ -140,8 +141,20 @@ impl App { sender.send(Action::ErrorNotification(format!("Playback: {}", err))).ok(); })); + player.connect_state_changed(clone!(sender => move |_,state| { + sender.send(Action::PlayerStateChanged(state)).ok(); + })); + + player.connect_media_info_updated(clone!(sender => move |_,info| { + sender.send(Action::PlayerMediaChanged(info.get_title(), info.get_duration())).ok(); + })); + + player.connect_property_position_notify(clone!(sender => move |p| { + sender.send(Action::PlayerPositionChanged(p.get_position())).ok(); + })); + gtk::timeout_add(50, clone!(sender, receiver => move || { - // Uses receiver, content, header, sender, overlay + // Uses receiver, content, header, sender, overlay, playback match receiver.try_recv() { Ok(Action::RefreshAllViews) => content.update(), Ok(Action::RefreshShowsView) => content.update_shows_view(), @@ -202,6 +215,9 @@ impl App { player.set_uri(&uri); player.play(); }, + Ok(Action::PlayerStateChanged(state)) => playback.state_changed(state), + Ok(Action::PlayerMediaChanged(t, l)) => playback.media_changed(t, l), + Ok(Action::PlayerPositionChanged(t)) => playback.position_changed(t), Err(_) => (), } diff --git a/hammond-gtk/src/widgets/playback.rs b/hammond-gtk/src/widgets/playback.rs index 7ec6d4e..becef5b 100644 --- a/hammond-gtk/src/widgets/playback.rs +++ b/hammond-gtk/src/widgets/playback.rs @@ -1,16 +1,32 @@ +use gstreamer::ClockTime; +use gstreamer_player as gst; use gtk; +use gtk::prelude::*; #[derive(Debug, Clone)] pub struct Playback { - pub container: gtk::Grid, + reveal: gtk::Revealer, + container: gtk::Grid, + play: gtk::Button, + seek: gtk::Scale, + title: gtk::Label, + time: gtk::Label, } impl Default for Playback { fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/playback.ui"); let container = builder.get_object("wrapper").unwrap(); + let play = builder.get_object("play").unwrap(); + let seek = builder.get_object("seek").unwrap(); + let title = builder.get_object("title").unwrap(); + let time = builder.get_object("time").unwrap(); - Playback { container } + let reveal = gtk::Revealer::new(); + reveal.set_no_show_all(true); + reveal.add(&container); + + Playback { reveal, container, play, seek, title, time } } } @@ -18,4 +34,61 @@ impl Playback { pub fn new() -> Playback { Playback::default() } + + pub fn set_icon(&self, icon: &str) { + let image = gtk::Image::new_from_icon_name(icon, gtk::IconSize::Button.into()); + self.play.set_image(Some(&image)); + } + + pub fn get_widget(&self) -> >k::Revealer { + &self.reveal + } + + pub fn state_changed(&self, state: gst::PlayerState) { + // Once the playback controls are shown they don't go + // away again so show them unconditionally + self.reveal.show(); + self.reveal.set_reveal_child(true); + match state { + gst::PlayerState::Buffering => { + println!("Buffering!!!!!!!"); + }, + gst::PlayerState::Stopped | gst::PlayerState::Paused => { + println!("Stopped/Paused"); + self.set_icon("media-playback-start-symbolic"); + }, + gst::PlayerState::Playing => { + println!("Playing"); + self.set_icon("media-playback-pause-symbolic"); + }, + _ => { + println!("Weird stuff"); + } + } + } + + pub fn media_changed(&self, title: Option, length: ClockTime) { + self.reveal.show(); + self.reveal.set_reveal_child(true); + if let Some(title) = title { + self.title.set_label(&title); + } else { + self.title.set_label(""); + } + if let Some(s) = length.seconds() { + let hours = s / 3600; + let s = s - (hours * 3600); + let mins = s / 60; + let s = s - (mins * 60); + // This is a little nasty + let t = format!("{}:{}:{}", hours, mins, s); + self.time.set_label(&t); + } else { + self.time.set_label(""); + } + } + + pub fn position_changed(&self, _pos: ClockTime) { + println!("Tada!"); + } }