PlayerWidget: Wire the widget to the GUI.

This commit also removes the majority of the playback widget,
though most of it's code will make it to the PlayerWidget once
it starts to get wired to the gtreamer_plaer::Player.
This commit is contained in:
Jordan Petridis 2018-06-13 22:38:28 +03:00
parent 47f297c495
commit 5f92df97e6
6 changed files with 221 additions and 345 deletions

View File

@ -31,241 +31,219 @@
<property name="icon_name">media-seek-backward-symbolic</property>
<property name="icon_size">1</property>
</object>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<object class="GtkActionBar" id="action_bar">
<property name="can_focus">False</property>
<property name="transition_type">slide-up</property>
<property name="no_show_all">True</property>
<property name="valign">end</property>
<child>
<object class="GtkFrame" id="frame">
<object class="GtkBox" id="buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0.5</property>
<property name="label_yalign">0</property>
<property name="shadow_type">in</property>
<property name="halign">center</property>
<child>
<object class="GtkActionBar" id="action_bar">
<object class="GtkButton" id="rewind_button">
<property name="width_request">42</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Previous</property>
<property name="image">previous_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="play_button">
<property name="width_request">60</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="image">play_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="pause_button">
<property name="width_request">60</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="image">pause_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ff_button">
<property name="width_request">42</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Next</property>
<property name="image">ff_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<style>
<class name="linked"/>
</style>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="show_cover">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">end</property>
<property name="pixel_size">42</property>
<property name="icon_name">image-x-generic-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="buttons">
<object class="GtkLabel" id="show_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<child>
<object class="GtkButton" id="rewind_button">
<property name="width_request">42</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Previous</property>
<property name="image">previous_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="play_button">
<property name="width_request">60</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="image">play_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="pause_button">
<property name="width_request">60</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="image">pause_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ff_button">
<property name="width_request">42</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Next</property>
<property name="image">ff_image</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<style>
<class name="linked"/>
</style>
<property name="label" translatable="yes">Show Title</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="info">
<object class="GtkLabel" id="episode_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="show_cover">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">42</property>
<property name="icon_name">image-x-generic-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="show_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Show Title</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="episode_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Episode Title</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<property name="label" translatable="yes">Episode Title</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScale" id="seek">
<property name="height_request">0</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">end</property>
<property name="hexpand">True</property>
<property name="show_fill_level">True</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">-1</property>
<property name="digits">0</property>
<property name="draw_value">False</property>
<property name="has_origin">False</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="timer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="progress_time_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">0:00</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">/</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="total_duration_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">0:00</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScale" id="seek">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="show_fill_level">True</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">-1</property>
<property name="digits">0</property>
<property name="draw_value">False</property>
<property name="has_origin">False</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="timer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="progress_time_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">0:00</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">/</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="total_duration_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="label">0:00</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">4</property>
</packing>
</child>
</object>
</interface>

View File

@ -13,7 +13,7 @@
<file compressed="true" preprocess="xml-stripblanks">gtk/inapp_notif.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/menus.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/playback.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/player_toolbar.ui</file>
<file compressed="true">gtk/style.css</file>
</gresource>
</gresources>

View File

@ -5,8 +5,6 @@ use gio::{
SimpleAction, SimpleActionExt,
};
use glib;
use gstreamer_player as gst;
use gstreamer::ClockTime;
use gtk;
use gtk::prelude::*;
use gtk::SettingsExt as GtkSettingsExt;
@ -19,7 +17,7 @@ use settings::{self, WindowGeometry};
use stacks::{Content, PopulatedState};
use utils;
use widgets::appnotif::{InAppNotification, UndoState};
use widgets::{about_dialog, mark_all_notif, remove_show_notif, Playback};
use widgets::{about_dialog, mark_all_notif, remove_show_notif, PlayerWidget};
use std::rc::Rc;
use std::sync::Arc;
@ -56,9 +54,6 @@ pub enum Action {
RemoveShow(Arc<Podcast>),
ErrorNotification(String),
PlayEpisode(String),
PlayerStateChanged(gst::PlayerState),
PlayerMediaChanged(Option<String>, ClockTime),
PlayerPositionChanged(ClockTime),
}
#[derive(Debug)]
@ -103,8 +98,6 @@ impl App {
Inhibit(false)
}));
let wrap = gtk::Box::new(gtk::Orientation::Vertical, 0);
window.add(&wrap);
// Create a content instance
let content =
@ -122,11 +115,17 @@ impl App {
let overlay = gtk::Overlay::new();
overlay.add(&content.get_stack());
// Add the overlay to the main window
let wrap = gtk::Box::new(gtk::Orientation::Vertical, 0);
// Add the overlay to the main Box
wrap.add(&overlay);
let playback = Rc::new(Playback::new());
wrap.add(playback.get_widget());
// FIXME: this should have a ::new() method instead.
let player = PlayerWidget::default();
// Add the player to the main Box
wrap.add(&player.action_bar);
// player.reveal();
window.add(&wrap);
WindowGeometry::from_settings(&settings).apply(&window);
@ -135,23 +134,22 @@ impl App {
window.show_all();
window.activate();
let player = gst::Player::new(None, None);
player.connect_error(clone!(sender => move |_,err| {
// player.connect_error(clone!(sender => move |_,err| {
// Not the most user friendly...
sender.send(Action::ErrorNotification(format!("Playback: {}", err))).ok();
}));
// sender.send(Action::ErrorNotification(format!("Playback: {}", err))).ok();
// }));
player.connect_state_changed(clone!(sender => move |_,state| {
sender.send(Action::PlayerStateChanged(state)).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_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();
}));
// 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, playback
@ -210,14 +208,7 @@ impl App {
|| {}, UndoState::Hidden);
notif.show(&overlay);
},
Ok(Action::PlayEpisode(uri)) => {
// This must be a 'real' (file://) uri not a path
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),
Ok(Action::PlayEpisode(_uri)) => (),
Err(_) => (),
}

View File

@ -5,7 +5,6 @@ mod episode;
mod home_view;
mod show;
mod shows_view;
mod playback;
mod player;
pub use self::aboutdialog::about_dialog;
@ -15,4 +14,4 @@ pub use self::home_view::HomeView;
pub use self::show::ShowWidget;
pub use self::show::{mark_all_notif, remove_show_notif};
pub use self::shows_view::ShowsView;
pub use self::playback::Playback;
pub use self::player::PlayerWidget;

View File

@ -1,94 +0,0 @@
use gstreamer::ClockTime;
use gstreamer_player as gst;
use gtk;
use gtk::prelude::*;
#[derive(Debug, Clone)]
pub struct Playback {
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();
let reveal = gtk::Revealer::new();
reveal.set_no_show_all(true);
reveal.add(&container);
Playback { reveal, container, play, seek, title, time }
}
}
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) -> &gtk::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<String>, 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!");
}
}

View File

@ -25,6 +25,12 @@ struct PlayerInfo {
cover: gtk::Image,
}
impl PlayerInfo {
fn init(&self) -> Result<(), Error> {
unimplemented!()
}
}
#[derive(Debug, Clone)]
struct PlayerTimes {
container: gtk::Box,
@ -54,9 +60,8 @@ struct PlayerControls {
#[derive(Debug, Clone)]
pub struct PlayerWidget {
pub action_bar: gtk::ActionBar,
player: gst::Player,
revealer: gtk::Revealer,
action_bar: gtk::ActionBar,
controls: PlayerControls,
timer: PlayerTimes,
info: PlayerInfo,
@ -66,7 +71,6 @@ impl Default for PlayerWidget {
fn default() -> Self {
let builder = gtk::Builder::new_from_resource("/org/gnome/Hammond/gtk/player_toolbar.ui");
let player = gst::Player::new(None, None);
let revealer = builder.get_object("revealer").unwrap();
let action_bar = builder.get_object("action_bar").unwrap();
let buttons = builder.get_object("buttons").unwrap();
@ -86,7 +90,7 @@ impl Default for PlayerWidget {
let timer_container = builder.get_object("timer").unwrap();
let progressed = builder.get_object("progress_time_label").unwrap();
let duration = builder.get_object("total_duration").unwrap();
let duration = builder.get_object("total_duration_label").unwrap();
let separator = builder.get_object("separator").unwrap();
let scalebar = builder.get_object("seek").unwrap();
let timer = PlayerTimes {
@ -110,7 +114,6 @@ impl Default for PlayerWidget {
PlayerWidget {
player,
revealer,
action_bar,
controls,
timer,
@ -121,8 +124,7 @@ impl Default for PlayerWidget {
impl PlayerWidget {
fn reveal(&self) {
self.revealer.show();
self.revealer.set_reveal_child(true);
self.action_bar.show();
}
}