EpisodeWidget: Implement a state machine for duration label.

This commit is contained in:
Jordan Petridis 2018-02-09 10:12:37 +02:00
parent 23979b8f22
commit f0ce0eb653
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
2 changed files with 105 additions and 16 deletions

View File

@ -4,7 +4,6 @@ use gtk;
use chrono::prelude::*; use chrono::prelude::*;
use gtk::prelude::*; use gtk::prelude::*;
use chrono::Duration;
use failure::Error; use failure::Error;
use humansize::{file_size_opts as size_opts, FileSize}; use humansize::{file_size_opts as size_opts, FileSize};
use open; use open;
@ -49,11 +48,10 @@ pub struct EpisodeWidget {
cancel: gtk::Button, cancel: gtk::Button,
title: TitleMachine, title: TitleMachine,
date: gtk::Label, date: gtk::Label,
duration: gtk::Label, duration: DurationMachine,
progress: gtk::ProgressBar, progress: gtk::ProgressBar,
total_size: gtk::Label, total_size: gtk::Label,
local_size: gtk::Label, local_size: gtk::Label,
separator1: gtk::Label,
separator2: gtk::Label, separator2: gtk::Label,
prog_separator: gtk::Label, prog_separator: gtk::Label,
} }
@ -80,6 +78,7 @@ impl Default for EpisodeWidget {
let prog_separator: gtk::Label = builder.get_object("prog_separator").unwrap(); let prog_separator: gtk::Label = builder.get_object("prog_separator").unwrap();
let title_machine = TitleMachine::new(title, false); let title_machine = TitleMachine::new(title, false);
let duration_machine = DurationMachine::new(duration, separator1, None);
EpisodeWidget { EpisodeWidget {
container, container,
@ -88,11 +87,10 @@ impl Default for EpisodeWidget {
play, play,
cancel, cancel,
title: title_machine, title: title_machine,
duration, duration: duration_machine,
date, date,
total_size, total_size,
local_size, local_size,
separator1,
separator2, separator2,
prog_separator, prog_separator,
} }
@ -112,7 +110,7 @@ impl EpisodeWidget {
self = self.set_title(&episode); self = self.set_title(&episode);
// Set the duaration label. // Set the duaration label.
self.set_duration(episode.duration()); self = self.set_duration(episode.duration());
// Set the date label. // Set the date label.
self.set_date(episode.epoch()); self.set_date(episode.epoch());
@ -191,16 +189,9 @@ impl EpisodeWidget {
} }
/// Set the duration label. /// Set the duration label.
fn set_duration(&self, seconds: Option<i32>) -> Option<()> { fn set_duration(mut self, seconds: Option<i32>) -> Self {
let minutes = Duration::seconds(seconds?.into()).num_minutes(); self.duration = self.duration.determine_state(seconds);
if minutes == 0 { self
return None;
}
self.duration.set_text(&format!("{} min", minutes));
self.duration.show();
self.separator1.show();
Some(())
} }
/// Set the Episode label dependings on its size /// Set the Episode label dependings on its size

View File

@ -1,3 +1,4 @@
use chrono;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@ -83,3 +84,100 @@ impl TitleMachine {
} }
} }
} }
#[derive(Debug, Clone)]
pub struct Shown;
#[derive(Debug, Clone)]
pub struct Hidden;
#[derive(Debug, Clone)]
pub struct Duration<S> {
// TODO: make duration and separator diff types
duration: gtk::Label,
separator: gtk::Label,
state: S,
}
impl<S> Duration<S> {
// This needs a better name.
fn set_duration(&self, minutes: i64) {
self.duration.set_text(&format!("{} min", minutes));
}
}
impl Duration<Hidden> {
fn new(duration: gtk::Label, separator: gtk::Label) -> Self {
duration.hide();
separator.hide();
Duration {
duration,
separator,
state: Hidden {},
}
}
}
impl From<Duration<Hidden>> for Duration<Shown> {
fn from(d: Duration<Hidden>) -> Self {
d.duration.show();
d.separator.show();
Duration {
duration: d.duration,
separator: d.separator,
state: Shown {},
}
}
}
impl From<Duration<Shown>> for Duration<Hidden> {
fn from(d: Duration<Shown>) -> Self {
d.duration.hide();
d.separator.hide();
Duration {
duration: d.duration,
separator: d.separator,
state: Hidden {},
}
}
}
#[derive(Debug, Clone)]
pub enum DurationMachine {
Hidden(Duration<Hidden>),
Shown(Duration<Shown>),
}
impl DurationMachine {
pub fn new(duration: gtk::Label, separator: gtk::Label, seconds: Option<i32>) -> Self {
let m = DurationMachine::Hidden(Duration::<Hidden>::new(duration, separator));
m.determine_state(seconds)
}
pub fn determine_state(self, seconds: Option<i32>) -> Self {
match (self, seconds) {
(DurationMachine::Hidden(val), None) => DurationMachine::Hidden(val.into()),
(DurationMachine::Shown(val), None) => DurationMachine::Hidden(val.into()),
(DurationMachine::Hidden(val), Some(s)) => {
let minutes = chrono::Duration::seconds(s.into()).num_minutes();
if minutes == 0 {
DurationMachine::Hidden(val.into())
} else {
val.set_duration(minutes);
DurationMachine::Shown(val.into())
}
}
(DurationMachine::Shown(val), Some(s)) => {
let minutes = chrono::Duration::seconds(s.into()).num_minutes();
if minutes == 0 {
DurationMachine::Hidden(val.into())
} else {
val.set_duration(minutes);
DurationMachine::Shown(val.into())
}
}
}
}
}