diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index b440a4e..1a75de1 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -66,7 +66,6 @@ macro_rules! clone { } mod stacks; -mod views; mod widgets; mod app; diff --git a/hammond-gtk/src/stacks/episode.rs b/hammond-gtk/src/stacks/episode.rs index ad014a9..d21774a 100644 --- a/hammond-gtk/src/stacks/episode.rs +++ b/hammond-gtk/src/stacks/episode.rs @@ -6,7 +6,7 @@ use hammond_data::dbqueries::is_episodes_populated; use hammond_data::errors::DataError; use app::Action; -use views::{EmptyView, EpisodesView}; +use widgets::{EmptyView, HomeView}; use std::rc::Rc; use std::sync::mpsc::Sender; @@ -15,13 +15,13 @@ use std::sync::mpsc::Sender; pub struct EpisodeStack { stack: gtk::Stack, empty: EmptyView, - episodes: Rc, + episodes: Rc, sender: Sender, } impl EpisodeStack { pub fn new(sender: Sender) -> Result { - let episodes = EpisodesView::new(sender.clone())?; + let episodes = HomeView::new(sender.clone())?; let empty = EmptyView::new(); let stack = gtk::Stack::new(); @@ -52,7 +52,7 @@ impl EpisodeStack { fn replace_view(&mut self) -> Result<(), Error> { // Get the container of the view let old = &self.episodes.container.clone(); - let eps = EpisodesView::new(self.sender.clone())?; + let eps = HomeView::new(self.sender.clone())?; // Remove the old widget and add the new one self.stack.remove(old); diff --git a/hammond-gtk/src/stacks/show.rs b/hammond-gtk/src/stacks/show.rs index 7af65dd..0d46344 100644 --- a/hammond-gtk/src/stacks/show.rs +++ b/hammond-gtk/src/stacks/show.rs @@ -7,10 +7,8 @@ use hammond_data::dbqueries; use hammond_data::errors::DataError; use hammond_data::Podcast; -use views::{EmptyView, ShowsPopulated}; - use app::Action; -use widgets::ShowWidget; +use widgets::{EmptyView, ShowWidget, ShowsPopulated}; use std::rc::Rc; use std::sync::mpsc::Sender; diff --git a/hammond-gtk/src/views/mod.rs b/hammond-gtk/src/views/mod.rs deleted file mode 100644 index d14ed86..0000000 --- a/hammond-gtk/src/views/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod empty; -mod episodes; -mod shows; - -pub use self::empty::EmptyView; -pub use self::episodes::EpisodesView; -pub use self::shows::ShowsPopulated; diff --git a/hammond-gtk/src/views/empty.rs b/hammond-gtk/src/widgets/empty.rs similarity index 100% rename from hammond-gtk/src/views/empty.rs rename to hammond-gtk/src/widgets/empty.rs diff --git a/hammond-gtk/src/widgets/episode_relm.rs b/hammond-gtk/src/widgets/episode_relm.rs new file mode 100644 index 0000000..c0abeef --- /dev/null +++ b/hammond-gtk/src/widgets/episode_relm.rs @@ -0,0 +1,280 @@ +use gtk; +use gtk::prelude::*; +use gtk::Orientation::Vertical; +use relm::{Relm, Update, Widget}; + +use chrono::prelude::*; + +#[derive(Msg)] +enum TitleMsg { + Normal, + GreyedOut, + SetText(String), +} + +// Create the structure that holds the widgets used in the view. +struct Title { + title: gtk::Label, +} + +impl Update for Title { + // Specify the model used for this widget. + type Model = (); + // Specify the model parameter used to init the model. + type ModelParam = (); + // Specify the type of the messages sent to the update function. + type Msg = TitleMsg; + + fn model(_: &Relm, _: ()) -> () {} + + fn update(&mut self, event: TitleMsg) { + match event { + TitleMsg::Normal => { + self.title + .get_style_context() + .map(|c| c.remove_class("dim-label")); + } + TitleMsg::GreyedOut => { + self.title + .get_style_context() + .map(|c| c.add_class("dim-label")); + } + TitleMsg::SetText(s) => { + self.title.set_text(&s); + // self.title.set_tooltip_text(s.as_str()); + } + } + } +} + +impl Widget for Title { + // Specify the type of the root widget. + type Root = gtk::Label; + + // Return the root widget. + fn root(&self) -> Self::Root { + self.title.clone() + } + + fn view(relm: &Relm, model: Self::Model) -> Self { + let title = gtk::Label::new("Unkown Title"); + + Title { title } + } +} + +#[derive(Msg)] +enum DateMsg { + Usual, + ShowYear, +} + +struct Date { + date: gtk::Label, + epoch: i64 +} + +impl Update for Date { + type Model = i64; + type ModelParam = i64; + type Msg = DateMsg; + + fn model(_: &Relm, epoch: i64) -> i64 { + epoch + } + + fn update(&mut self, event: DateMsg) { + match event { + DateMsg::Usual => { + let ts = Utc.timestamp(self.epoch, 0); + self.date.set_text(ts.format("%e %b").to_string().trim()); + } + DateMsg::ShowYear => { + let ts = Utc.timestamp(self.epoch, 0); + self.date.set_text(ts.format("%e %b %Y").to_string().trim()); + } + } + } +} + +impl Widget for Date { + type Root = gtk::Label; + + fn root(&self) -> Self::Root { + self.date.clone() + } + + fn view(relm: &Relm, model: Self::Model) -> Self { + let date = gtk::Label::new(""); + + Date { date, epoch: model } + } +} + +#[derive(Msg)] +enum DurationMsg { + Show, + Hide, + SetDuration, +} + +struct Duration { + duration: gtk::Label, + separator: gtk::Label, + seconds: Option, +} + +impl Update for Date { + type Model = Option; + type ModelParam = Option; + type Msg = DateMsg; + + fn model(_: &Relm, seconds: Option) -> Option { + seconds + } + + fn update(&mut self, event: DateMsg) { + match event { + DurationMsg::Show => { + self.duration.show(); + self.separator.show(); + } + DurationMsg::Hide => { + self.duration.hide(); + self.separator.hide(); + } + DurationMsg::SetDuration => { + let minutes = chrono::Duration::seconds(self.into()).num_minutes(); + if miutes == 0 { + // FIXME: emit DurationMsg::Hide + } else { + // FIXME: emit DurationMsg::Show + self.duration.set_text(&format!("{} min", minutes)); + } + } + } + } +} + +impl Widget for Date { + // FIXME: This is weird + type Root = gtk::Label; + + fn root(&self) -> Self::Root { + self.date.clone() + } + + fn view(relm: &Relm, model: Self::Model) -> Self { + let date = gtk::Label::new(""); + + Date { date, epoch: model } + } +} + + +// struct Model { +// counter: i32, +// } + +// #[derive(Msg)] +// enum Msg { +// Decrement, +// Increment, +// } + +// Create the structure that holds the widgets used in the view. +// struct EpisodeWidgetRelm { +// model: Model, + +// container: gtk::Box, +// progress: gtk::ProgressBar, + +// download: gtk::Button, +// play: gtk::Button, +// cancel: gtk::Button, + +// title: gtk::Label, +// date: gtk::Label, +// duration: gtk::Label, +// local_size: gtk::Label, +// total_size: gtk::Label, + +// separator1: gtk::Label, +// separator2: gtk::Label, +// prog_separator: gtk::Label, +// } + +// impl Update for EpisodeWidgetRelm { + // Specify the model used for this widget. +// type Model = Model; + // Specify the model parameter used to init the model. +// type ModelParam = (); + // Specify the type of the messages sent to the update function. +// type Msg = Msg; + +// fn model(_: &Relm, _: ()) -> Model { +// Model { counter: 0 } +// } + +// fn update(&mut self, event: Msg) { +// match event { +// Msg::Decrement => {} +// Msg::Increment => {} +// } +// } +// } + +// impl Widget for EpisodeWidgetRelm { + // Specify the type of the root widget. +// type Root = gtk::Box; + + // Return the root widget. +// fn root(&self) -> Self::Root { +// self.container.clone() +// } + +// fn view(relm: &Relm, model: Self::Model) -> Self { +// let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui"); + +// let container: gtk::Box = builder.get_object("episode_container").unwrap(); +// let progress: gtk::ProgressBar = builder.get_object("progress_bar").unwrap(); + +// let download: gtk::Button = builder.get_object("download_button").unwrap(); +// let play: gtk::Button = builder.get_object("play_button").unwrap(); +// let cancel: gtk::Button = builder.get_object("cancel_button").unwrap(); + +// let title: gtk::Label = builder.get_object("title_label").unwrap(); +// let date: gtk::Label = builder.get_object("date_label").unwrap(); +// let duration: gtk::Label = builder.get_object("duration_label").unwrap(); +// let local_size: gtk::Label = builder.get_object("local_size").unwrap(); +// let total_size: gtk::Label = builder.get_object("total_size").unwrap(); + +// let separator1: gtk::Label = builder.get_object("separator1").unwrap(); +// let separator2: gtk::Label = builder.get_object("separator2").unwrap(); +// let prog_separator: gtk::Label = builder.get_object("prog_separator").unwrap(); + + // Send the message Increment when the button is clicked. + // connect!(relm, plus_button, connect_clicked(_), Msg::Increment); + // connect!(relm, minus_button, connect_clicked(_), Msg::Decrement); + +// EpisodeWidgetRelm { +// model, +// container, +// progress, + +// download, +// play, +// cancel, + +// title, +// date, +// duration, +// local_size, +// total_size, + +// separator1, +// separator2, +// prog_separator, +// } +// } +// } \ No newline at end of file diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/widgets/home.rs similarity index 96% rename from hammond-gtk/src/views/episodes.rs rename to hammond-gtk/src/widgets/home.rs index 3e4986b..d60bcde 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/widgets/home.rs @@ -31,7 +31,7 @@ enum ListSplit { } #[derive(Debug, Clone)] -pub struct EpisodesView { +pub struct HomeView { pub container: gtk::Box, scrolled_window: gtk::ScrolledWindow, frame_parent: gtk::Box, @@ -47,7 +47,7 @@ pub struct EpisodesView { rest_list: gtk::ListBox, } -impl Default for EpisodesView { +impl Default for HomeView { #[inline] fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view.ui"); @@ -65,7 +65,7 @@ impl Default for EpisodesView { let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); - EpisodesView { + HomeView { container, scrolled_window, frame_parent, @@ -84,12 +84,12 @@ impl Default for EpisodesView { } // TODO: REFACTOR ME -impl EpisodesView { +impl HomeView { #[inline] - pub fn new(sender: Sender) -> Result, Error> { + pub fn new(sender: Sender) -> Result, Error> { use self::ListSplit::*; - let view = Rc::new(EpisodesView::default()); + let view = Rc::new(HomeView::default()); let ignore = get_ignored_shows()?; let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 100)?; let now_utc = Utc::now(); diff --git a/hammond-gtk/src/widgets/mod.rs b/hammond-gtk/src/widgets/mod.rs index 7d46f47..ce2557b 100644 --- a/hammond-gtk/src/widgets/mod.rs +++ b/hammond-gtk/src/widgets/mod.rs @@ -1,7 +1,13 @@ +mod empty; mod episode; mod episode_states; +mod home; mod show; +mod shows; +pub use self::empty::EmptyView; pub use self::episode::EpisodeWidget; +pub use self::home::HomeView; pub use self::show::ShowWidget; pub use self::show::{mark_all_notif, remove_show_notif}; +pub use self::shows::ShowsPopulated; diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/widgets/shows.rs similarity index 100% rename from hammond-gtk/src/views/shows.rs rename to hammond-gtk/src/widgets/shows.rs