MediaMachine: Expose an interface to update the ProgressBar and local_size.

This commit is contained in:
Jordan Petridis 2018-02-17 19:49:43 +02:00
parent 0cd678cc1d
commit a88a1c5f1f
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
2 changed files with 43 additions and 27 deletions

View File

@ -48,8 +48,6 @@ pub struct EpisodeWidget {
date: gtk::Label,
title: Arc<Mutex<TitleMachine>>,
duration: Arc<Mutex<DurationMachine>>,
progress: gtk::ProgressBar,
local_size: gtk::Label,
media: Arc<Mutex<MediaMachine>>,
}
@ -80,10 +78,10 @@ impl Default for EpisodeWidget {
let _media = MediaMachine::new(
play,
download,
progress.clone(),
progress,
cancel,
total_size,
local_size.clone(),
local_size,
separator2,
prog_separator,
);
@ -91,8 +89,6 @@ impl Default for EpisodeWidget {
EpisodeWidget {
container,
progress,
local_size,
title: title_machine,
duration: duration_machine,
date,
@ -189,8 +185,6 @@ impl EpisodeWidget {
Ok(())
}
// FIXME: REFACTOR ME
// Something Something State-Machine?
fn determine_media_state(&self, episode: &EpisodeWidgetQuery) -> Result<(), Error> {
let id = WidgetExt::get_name(&self.container)
.ok_or_else(|| format_err!("Failed to get widget Name"))?
@ -216,11 +210,8 @@ impl EpisodeWidget {
// Show or hide the play/delete/download buttons upon widget initialization.
// FIXME: There might be a deadlock introduced here, but I am too tired to test it.
if let Some(prog) = active_dl {
let progress_bar = self.progress.clone();
let local_size = self.local_size.clone();
// Setup a callback that will update the progress bar.
update_progressbar_callback(prog.clone(), id, &progress_bar, &local_size);
update_progressbar_callback(prog.clone(), self.media.clone(), id);
// Setup a callback that will update the total_size label
// with the http ContentLength header number rather than
@ -286,14 +277,13 @@ fn open_uri(rowid: i32) -> Result<(), Error> {
#[cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))]
fn update_progressbar_callback(
prog: Arc<Mutex<manager::Progress>>,
media: Arc<Mutex<MediaMachine>>,
episode_rowid: i32,
progress_bar: &gtk::ProgressBar,
local_size: &gtk::Label,
) {
timeout_add(
400,
clone!(prog, progress_bar, progress_bar, local_size=> move || {
progress_bar_helper(prog.clone(), episode_rowid, &progress_bar, &local_size)
clone!(prog, media => move || {
progress_bar_helper(prog.clone(), media.clone(), episode_rowid)
.unwrap_or(glib::Continue(false))
}),
);
@ -302,9 +292,8 @@ fn update_progressbar_callback(
#[inline]
fn progress_bar_helper(
prog: Arc<Mutex<manager::Progress>>,
media: Arc<Mutex<MediaMachine>>,
episode_rowid: i32,
progress_bar: &gtk::ProgressBar,
local_size: &gtk::Label,
) -> Result<glib::Continue, Error> {
let (fraction, downloaded) = {
let m = prog.lock()
@ -312,16 +301,16 @@ fn progress_bar_helper(
(m.get_fraction(), m.get_downloaded())
};
// Update local_size label
downloaded
.file_size(SIZE_OPTS.clone())
.map_err(|err| format_err!("{}", err))
.map(|x| local_size.set_text(&x))?;
// I hate floating points.
// Update the progress_bar.
if (fraction >= 0.0) && (fraction <= 1.0) && (!fraction.is_nan()) {
progress_bar.set_fraction(fraction);
// Update local_size label
let size = downloaded
.file_size(SIZE_OPTS.clone())
.map_err(|err| format_err!("{}", err))?;
let mut m = media.lock().unwrap();
m.update_progress(&size, fraction);
}
// info!("Fraction: {}", progress_bar.get_fraction());

View File

@ -79,7 +79,7 @@ pub struct Title<S> {
impl<S> Title<S> {
#[allow(unused_must_use)]
// This does not need to be &mut since gtk-rs does not model ownership
// But I think it wouldn't heart if we treat it as a Rust api.
// But I think it wouldn't hurt if we treat it as a Rust api.
fn set_title(&mut self, s: &str) {
self.title.set_text(s);
}
@ -426,6 +426,14 @@ impl<S> Progress<S> {
}
}
#[allow(unused_must_use)]
// This does not need to be &mut since gtk-rs does not model ownership
// But I think it wouldn't hurt if we treat it as a Rust api.
fn update_progress(&mut self, local_size: &str, fraction: f64) {
self.local_size.set_text(local_size);
self.bar.set_fraction(fraction);
}
fn cancel_connect_clicked(&self, prog: Arc<Mutex<OtherProgress>>) -> glib::SignalHandlerId {
self.cancel.connect_clicked(move |cancel| {
if let Ok(mut m) = prog.lock() {
@ -606,6 +614,15 @@ impl<X, Z> Media<X, UnInitialized, Z> {
}
}
impl InProgress {
#[allow(unused_must_use)]
// This does not need to be &mut since gtk-rs does not model ownership
// But I think it wouldn't hurt if we treat it as a Rust api.
fn update_progress(&mut self, local_size: &str, fraction: f64) {
self.progress.update_progress(local_size, fraction)
}
}
#[derive(Debug, Clone)]
pub enum ButtonsState {
New(Media<Download, Shown, Hidden>),
@ -642,7 +659,7 @@ impl ButtonsState {
// From whatever to PlayableWithoutSize
(New(m), None, true) => PlayableWithoutSize(Media::from(m).hide_size()),
(Playable(m), None, true) => PlayableWithoutSize(Media::from(m).hide_size()),
(Playable(m), None, true) => PlayableWithoutSize(m.hide_size()),
(NewWithoutSize(val), None, true) => PlayableWithoutSize(val.into()),
(b @ PlayableWithoutSize(_), None, true) => b,
@ -809,6 +826,16 @@ impl MediaMachine {
(n @ UnInitialized(_), _) => n,
}
}
pub fn update_progress(&mut self, local_size: &str, fraction: f64) {
use self::MediaMachine::*;
match *self {
Initialized(_) => (),
UnInitialized(_) => (),
InProgress(ref mut val) => val.update_progress(local_size, fraction),
}
}
}
#[inline]