Probably the worst state machine implementation that was ever written.
This commit is contained in:
parent
45522b86df
commit
a96f4c57c9
@ -40,13 +40,100 @@ lazy_static! {
|
|||||||
static ref NOW: DateTime<Utc> = Utc::now();
|
static ref NOW: DateTime<Utc> = Utc::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Normal;
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct GreyedOut;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Title<S> {
|
||||||
|
title: gtk::Label,
|
||||||
|
state: S,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Title<Normal> {
|
||||||
|
fn new(title: gtk::Label) -> Self {
|
||||||
|
Title {
|
||||||
|
title,
|
||||||
|
state: Normal {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_title(&self, s: &str) {
|
||||||
|
self.title.set_text(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Title<GreyedOut> {
|
||||||
|
fn set_title(&self, s: &str) {
|
||||||
|
self.title.set_text(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Title<Normal>> for Title<GreyedOut> {
|
||||||
|
fn from(machine: Title<Normal>) -> Self {
|
||||||
|
machine
|
||||||
|
.title
|
||||||
|
.get_style_context()
|
||||||
|
.map(|c| c.add_class("dim-label"));
|
||||||
|
|
||||||
|
Title {
|
||||||
|
title: machine.title,
|
||||||
|
state: GreyedOut {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Title<GreyedOut>> for Title<Normal> {
|
||||||
|
fn from(machine: Title<GreyedOut>) -> Self {
|
||||||
|
machine
|
||||||
|
.title
|
||||||
|
.get_style_context()
|
||||||
|
.map(|c| c.remove_class("dim-label"));
|
||||||
|
|
||||||
|
Title {
|
||||||
|
title: machine.title,
|
||||||
|
state: Normal {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum TitleMachine {
|
||||||
|
Normal(Title<Normal>),
|
||||||
|
GreyedOut(Title<GreyedOut>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TitleMachine {
|
||||||
|
fn new(label: gtk::Label, is_played: bool) -> Self {
|
||||||
|
let m = TitleMachine::Normal(Title::<Normal>::new(label));
|
||||||
|
m.determine_state(is_played)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn determine_state(self, is_played: bool) -> Self {
|
||||||
|
match (self, is_played) {
|
||||||
|
(title @ TitleMachine::Normal(_), false) => title,
|
||||||
|
(title @ TitleMachine::GreyedOut(_), true) => title,
|
||||||
|
(TitleMachine::Normal(val), true) => TitleMachine::GreyedOut(val.into()),
|
||||||
|
(TitleMachine::GreyedOut(val), false) => TitleMachine::Normal(val.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_title(&self, s: &str) {
|
||||||
|
match *self {
|
||||||
|
TitleMachine::Normal(ref val) => val.set_title(s),
|
||||||
|
TitleMachine::GreyedOut(ref val) => val.set_title(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EpisodeWidget {
|
pub struct EpisodeWidget {
|
||||||
pub container: gtk::Box,
|
pub container: gtk::Box,
|
||||||
play: gtk::Button,
|
play: gtk::Button,
|
||||||
download: gtk::Button,
|
download: gtk::Button,
|
||||||
cancel: gtk::Button,
|
cancel: gtk::Button,
|
||||||
title: gtk::Label,
|
title: TitleMachine,
|
||||||
date: gtk::Label,
|
date: gtk::Label,
|
||||||
duration: gtk::Label,
|
duration: gtk::Label,
|
||||||
progress: gtk::ProgressBar,
|
progress: gtk::ProgressBar,
|
||||||
@ -78,13 +165,15 @@ impl Default for EpisodeWidget {
|
|||||||
let separator2: gtk::Label = builder.get_object("separator2").unwrap();
|
let separator2: gtk::Label = builder.get_object("separator2").unwrap();
|
||||||
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);
|
||||||
|
|
||||||
EpisodeWidget {
|
EpisodeWidget {
|
||||||
container,
|
container,
|
||||||
progress,
|
progress,
|
||||||
download,
|
download,
|
||||||
play,
|
play,
|
||||||
cancel,
|
cancel,
|
||||||
title,
|
title: title_machine,
|
||||||
duration,
|
duration,
|
||||||
date,
|
date,
|
||||||
total_size,
|
total_size,
|
||||||
@ -98,16 +187,15 @@ impl Default for EpisodeWidget {
|
|||||||
|
|
||||||
impl EpisodeWidget {
|
impl EpisodeWidget {
|
||||||
pub fn new(episode: EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodeWidget {
|
pub fn new(episode: EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodeWidget {
|
||||||
let widget = EpisodeWidget::default();
|
let mut widget = EpisodeWidget::default();
|
||||||
widget.init(episode, sender);
|
widget.init(episode, sender)
|
||||||
widget
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, episode: EpisodeWidgetQuery, sender: Sender<Action>) {
|
fn init(mut self, episode: EpisodeWidgetQuery, sender: Sender<Action>) -> Self {
|
||||||
WidgetExt::set_name(&self.container, &episode.rowid().to_string());
|
WidgetExt::set_name(&self.container, &episode.rowid().to_string());
|
||||||
|
|
||||||
// Set the title label state.
|
// Set the title label state.
|
||||||
self.set_title(&episode);
|
self = self.set_title(&episode);
|
||||||
|
|
||||||
// Set the duaration label.
|
// Set the duaration label.
|
||||||
self.set_duration(episode.duration());
|
self.set_duration(episode.duration());
|
||||||
@ -135,15 +223,15 @@ impl EpisodeWidget {
|
|||||||
|
|
||||||
let episode = Arc::new(Mutex::new(episode));
|
let episode = Arc::new(Mutex::new(episode));
|
||||||
|
|
||||||
let title = self.title.clone();
|
// let title = self.title.clone();
|
||||||
self.play
|
// self.play
|
||||||
.connect_clicked(clone!(episode, sender => move |_| {
|
// .connect_clicked(clone!(episode, sender => move |_| {
|
||||||
if let Ok(mut ep) = episode.lock() {
|
// if let Ok(mut ep) = episode.lock() {
|
||||||
if let Err(err) = on_play_bttn_clicked(&mut ep, &title, sender.clone()){
|
// if let Err(err) = on_play_bttn_clicked(&mut ep, &title, sender.clone()){
|
||||||
error!("Error: {}", err);
|
// error!("Error: {}", err);
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}));
|
// }));
|
||||||
|
|
||||||
self.download
|
self.download
|
||||||
.connect_clicked(clone!(episode, sender => move |dl| {
|
.connect_clicked(clone!(episode, sender => move |dl| {
|
||||||
@ -157,6 +245,8 @@ impl EpisodeWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show or hide the play/delete/download buttons upon widget initialization.
|
/// Show or hide the play/delete/download buttons upon widget initialization.
|
||||||
@ -170,15 +260,10 @@ impl EpisodeWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the title state.
|
/// Determine the title state.
|
||||||
fn set_title(&self, episode: &EpisodeWidgetQuery) {
|
fn set_title(mut self, episode: &EpisodeWidgetQuery) -> Self {
|
||||||
self.title.set_text(episode.title());
|
self.title.set_title(episode.title());
|
||||||
|
self.title = self.title.determine_state(episode.played().is_some());
|
||||||
// Grey out the title if the episode is played.
|
self
|
||||||
if episode.played().is_some() {
|
|
||||||
self.title
|
|
||||||
.get_style_context()
|
|
||||||
.map(|c| c.add_class("dim-label"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the date label depending on the current time.
|
/// Set the date label depending on the current time.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user