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

View File

@ -1,3 +1,4 @@
use chrono;
use gtk;
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())
}
}
}
}
}