diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index bfd16c8..9e7d593 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -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) -> 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) -> Self { + self.duration = self.duration.determine_state(seconds); + self } /// Set the Episode label dependings on its size diff --git a/hammond-gtk/src/widgets/episode_states.rs b/hammond-gtk/src/widgets/episode_states.rs index c4a85ee..b208fcb 100644 --- a/hammond-gtk/src/widgets/episode_states.rs +++ b/hammond-gtk/src/widgets/episode_states.rs @@ -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 { + // TODO: make duration and separator diff types + duration: gtk::Label, + separator: gtk::Label, + state: S, +} + +impl Duration { + // This needs a better name. + fn set_duration(&self, minutes: i64) { + self.duration.set_text(&format!("{} min", minutes)); + } +} + +impl Duration { + fn new(duration: gtk::Label, separator: gtk::Label) -> Self { + duration.hide(); + separator.hide(); + + Duration { + duration, + separator, + state: Hidden {}, + } + } +} + +impl From> for Duration { + fn from(d: Duration) -> Self { + d.duration.show(); + d.separator.show(); + + Duration { + duration: d.duration, + separator: d.separator, + state: Shown {}, + } + } +} + +impl From> for Duration { + fn from(d: Duration) -> Self { + d.duration.hide(); + d.separator.hide(); + + Duration { + duration: d.duration, + separator: d.separator, + state: Hidden {}, + } + } +} + +#[derive(Debug, Clone)] +pub enum DurationMachine { + Hidden(Duration), + Shown(Duration), +} + +impl DurationMachine { + pub fn new(duration: gtk::Label, separator: gtk::Label, seconds: Option) -> Self { + let m = DurationMachine::Hidden(Duration::::new(duration, separator)); + m.determine_state(seconds) + } + + pub fn determine_state(self, seconds: Option) -> 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()) + } + } + } + } +}