Migrate Headerbar transitions into Channel actions.
This commit is contained in:
parent
2633161c67
commit
c33b493dcd
@ -20,6 +20,8 @@ pub enum Action {
|
|||||||
UpdateSources(Option<Source>),
|
UpdateSources(Option<Source>),
|
||||||
RefreshViews,
|
RefreshViews,
|
||||||
RefreshEpisodesViewBGR,
|
RefreshEpisodesViewBGR,
|
||||||
|
HeaderBarShowTile(String),
|
||||||
|
HeaderBarNormal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -53,16 +55,11 @@ impl App {
|
|||||||
|
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
|
|
||||||
// TODO: Refactor the initialization order.
|
// Create a content instance
|
||||||
|
let content = Content::new(sender.clone());
|
||||||
|
|
||||||
// Create the headerbar
|
// Create the headerbar
|
||||||
let header = Rc::new(Header::default());
|
let header = Header::new(content.clone(), sender);
|
||||||
|
|
||||||
// Create a content instance
|
|
||||||
let content = Content::new(header.clone(), sender.clone());
|
|
||||||
|
|
||||||
// Initialize the headerbar
|
|
||||||
header.init(content.clone(), sender.clone());
|
|
||||||
|
|
||||||
// Add the Headerbar to the window.
|
// Add the Headerbar to the window.
|
||||||
window.set_titlebar(&header.container);
|
window.set_titlebar(&header.container);
|
||||||
@ -146,6 +143,12 @@ impl App {
|
|||||||
Ok(Action::RefreshEpisodesViewBGR) => {
|
Ok(Action::RefreshEpisodesViewBGR) => {
|
||||||
content.update_episode_view_if_baground();
|
content.update_episode_view_if_baground();
|
||||||
}
|
}
|
||||||
|
Ok(Action::HeaderBarShowTile(title)) => {
|
||||||
|
headerbar.switch_to_back(&title)
|
||||||
|
}
|
||||||
|
Ok(Action::HeaderBarNormal) => {
|
||||||
|
headerbar.switch_to_normal()
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use views::empty::EmptyView;
|
|||||||
use views::episodes::EpisodesView;
|
use views::episodes::EpisodesView;
|
||||||
|
|
||||||
use widgets::show::ShowWidget;
|
use widgets::show::ShowWidget;
|
||||||
use headerbar::Header;
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -24,10 +23,10 @@ pub struct Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Content {
|
impl Content {
|
||||||
pub fn new(header: Rc<Header>, sender: Sender<Action>) -> Rc<Content> {
|
pub fn new(sender: Sender<Action>) -> Rc<Content> {
|
||||||
let stack = gtk::Stack::new();
|
let stack = gtk::Stack::new();
|
||||||
let episodes = EpisodeStack::new(sender.clone());
|
let episodes = EpisodeStack::new(sender.clone());
|
||||||
let shows = ShowStack::new(header, episodes.clone(), sender.clone());
|
let shows = ShowStack::new(episodes.clone(), sender.clone());
|
||||||
|
|
||||||
stack.add_titled(&episodes.stack, "episodes", "Episodes");
|
stack.add_titled(&episodes.stack, "episodes", "Episodes");
|
||||||
stack.add_titled(&shows.stack, "shows", "Shows");
|
stack.add_titled(&shows.stack, "shows", "Shows");
|
||||||
@ -71,23 +70,21 @@ impl Content {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ShowStack {
|
pub struct ShowStack {
|
||||||
stack: gtk::Stack,
|
stack: gtk::Stack,
|
||||||
header: Rc<Header>,
|
|
||||||
epstack: Rc<EpisodeStack>,
|
epstack: Rc<EpisodeStack>,
|
||||||
sender: Sender<Action>,
|
sender: Sender<Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShowStack {
|
impl ShowStack {
|
||||||
fn new(header: Rc<Header>, epstack: Rc<EpisodeStack>, sender: Sender<Action>) -> Rc<ShowStack> {
|
fn new(epstack: Rc<EpisodeStack>, sender: Sender<Action>) -> Rc<ShowStack> {
|
||||||
let stack = gtk::Stack::new();
|
let stack = gtk::Stack::new();
|
||||||
|
|
||||||
let show = Rc::new(ShowStack {
|
let show = Rc::new(ShowStack {
|
||||||
stack,
|
stack,
|
||||||
header: header.clone(),
|
|
||||||
epstack,
|
epstack,
|
||||||
sender,
|
sender: sender.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let pop = ShowsPopulated::new(show.clone(), header);
|
let pop = ShowsPopulated::new(show.clone(), sender.clone());
|
||||||
let widget = ShowWidget::default();
|
let widget = ShowWidget::default();
|
||||||
let empty = EmptyView::new();
|
let empty = EmptyView::new();
|
||||||
|
|
||||||
@ -118,7 +115,7 @@ impl ShowStack {
|
|||||||
let old = self.stack.get_child_by_name("podcasts").unwrap();
|
let old = self.stack.get_child_by_name("podcasts").unwrap();
|
||||||
|
|
||||||
let pop = ShowsPopulated::default();
|
let pop = ShowsPopulated::default();
|
||||||
pop.init(Rc::new(self.clone()), self.header.clone());
|
pop.init(Rc::new(self.clone()), self.sender.clone());
|
||||||
|
|
||||||
self.stack.remove(&old);
|
self.stack.remove(&old);
|
||||||
self.stack.add_named(&pop.container, "podcasts");
|
self.stack.add_named(&pop.container, "podcasts");
|
||||||
@ -136,12 +133,7 @@ impl ShowStack {
|
|||||||
|
|
||||||
pub fn replace_widget(&self, pd: &Podcast) {
|
pub fn replace_widget(&self, pd: &Podcast) {
|
||||||
let old = self.stack.get_child_by_name("widget").unwrap();
|
let old = self.stack.get_child_by_name("widget").unwrap();
|
||||||
let new = ShowWidget::new(
|
let new = ShowWidget::new(Rc::new(self.clone()), pd, self.sender.clone());
|
||||||
Rc::new(self.clone()),
|
|
||||||
self.header.clone(),
|
|
||||||
pd,
|
|
||||||
self.sender.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.stack.remove(&old);
|
self.stack.remove(&old);
|
||||||
self.stack.add_named(&new.container, "widget");
|
self.stack.add_named(&new.container, "widget");
|
||||||
|
|||||||
@ -7,9 +7,10 @@ use hammond_data::Podcast;
|
|||||||
|
|
||||||
use utils::get_pixbuf_from_path;
|
use utils::get_pixbuf_from_path;
|
||||||
use content::ShowStack;
|
use content::ShowStack;
|
||||||
use headerbar::Header;
|
use app::Action;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ShowsPopulated {
|
pub struct ShowsPopulated {
|
||||||
@ -34,24 +35,24 @@ impl Default for ShowsPopulated {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ShowsPopulated {
|
impl ShowsPopulated {
|
||||||
pub fn new(show: Rc<ShowStack>, header: Rc<Header>) -> ShowsPopulated {
|
pub fn new(show: Rc<ShowStack>, sender: Sender<Action>) -> ShowsPopulated {
|
||||||
let pop = ShowsPopulated::default();
|
let pop = ShowsPopulated::default();
|
||||||
pop.init(show, header);
|
pop.init(show, sender);
|
||||||
pop
|
pop
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&self, show: Rc<ShowStack>, header: Rc<Header>) {
|
pub fn init(&self, show: Rc<ShowStack>, sender: Sender<Action>) {
|
||||||
use gtk::WidgetExt;
|
use gtk::WidgetExt;
|
||||||
|
|
||||||
// TODO: handle unwraps.
|
// TODO: handle unwraps.
|
||||||
self.flowbox
|
self.flowbox
|
||||||
.connect_child_activated(clone!(show => move |_, child| {
|
.connect_child_activated(clone!(show, sender => move |_, child| {
|
||||||
// This is such an ugly hack...
|
// This is such an ugly hack...
|
||||||
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
|
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
|
||||||
let pd = dbqueries::get_podcast_from_id(id).unwrap();
|
let pd = dbqueries::get_podcast_from_id(id).unwrap();
|
||||||
|
|
||||||
show.replace_widget(&pd);
|
show.replace_widget(&pd);
|
||||||
header.switch_to_back(pd.title());
|
sender.send(Action::HeaderBarShowTile(pd.title().into())).unwrap();
|
||||||
show.switch_widget_animated();
|
show.switch_widget_animated();
|
||||||
}));
|
}));
|
||||||
// Populate the flowbox with the Podcasts.
|
// Populate the flowbox with the Podcasts.
|
||||||
|
|||||||
@ -16,24 +16,9 @@ use hammond_downloader::downloader;
|
|||||||
use app::Action;
|
use app::Action;
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::cell::RefCell;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
type Foo = RefCell<
|
|
||||||
Option<
|
|
||||||
(
|
|
||||||
gtk::Button,
|
|
||||||
gtk::Button,
|
|
||||||
gtk::Button,
|
|
||||||
gtk::ProgressBar,
|
|
||||||
Receiver<bool>,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EpisodeWidget {
|
pub struct EpisodeWidget {
|
||||||
pub container: gtk::Box,
|
pub container: gtk::Box,
|
||||||
@ -126,21 +111,18 @@ impl EpisodeWidget {
|
|||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let play = &self.play;
|
|
||||||
let cancel = &self.cancel;
|
let cancel = &self.cancel;
|
||||||
let progress = self.progress.clone();
|
let progress = self.progress.clone();
|
||||||
self.download.connect_clicked(
|
self.download
|
||||||
clone!(play, episode, cancel, progress, sender => move |dl| {
|
.connect_clicked(clone!(episode, cancel, progress, sender => move |dl| {
|
||||||
on_download_clicked(
|
on_download_clicked(
|
||||||
&mut episode.clone(),
|
&mut episode.clone(),
|
||||||
dl,
|
dl,
|
||||||
&play,
|
|
||||||
&cancel,
|
&cancel,
|
||||||
progress.clone(),
|
progress.clone(),
|
||||||
sender.clone()
|
sender.clone()
|
||||||
);
|
);
|
||||||
}),
|
}));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show or hide the play/delete/download buttons upon widget initialization.
|
/// Show or hide the play/delete/download buttons upon widget initialization.
|
||||||
@ -216,7 +198,6 @@ impl EpisodeWidget {
|
|||||||
fn on_download_clicked(
|
fn on_download_clicked(
|
||||||
ep: &mut EpisodeWidgetQuery,
|
ep: &mut EpisodeWidgetQuery,
|
||||||
download_bttn: >k::Button,
|
download_bttn: >k::Button,
|
||||||
play_bttn: >k::Button,
|
|
||||||
cancel_bttn: >k::Button,
|
cancel_bttn: >k::Button,
|
||||||
progress_bar: gtk::ProgressBar,
|
progress_bar: gtk::ProgressBar,
|
||||||
sender: Sender<Action>,
|
sender: Sender<Action>,
|
||||||
@ -235,7 +216,7 @@ fn on_download_clicked(
|
|||||||
cancel_bttn.show();
|
cancel_bttn.show();
|
||||||
progress.show();
|
progress.show();
|
||||||
download_bttn.hide();
|
download_bttn.hide();
|
||||||
sender.send(Action::RefreshEpisodesViewBGR);
|
sender.send(Action::RefreshEpisodesViewBGR).unwrap();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let download_fold = downloader::get_download_folder(&pd_title).unwrap();
|
let download_fold = downloader::get_download_folder(&pd_title).unwrap();
|
||||||
let e = downloader::get_episode(&mut ep, download_fold.as_str());
|
let e = downloader::get_episode(&mut ep, download_fold.as_str());
|
||||||
@ -243,7 +224,7 @@ fn on_download_clicked(
|
|||||||
error!("Error while trying to download: {:?}", ep.uri());
|
error!("Error while trying to download: {:?}", ep.uri());
|
||||||
error!("Error: {}", err);
|
error!("Error: {}", err);
|
||||||
};
|
};
|
||||||
sender.send(Action::RefreshViews);
|
sender.send(Action::RefreshViews).unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,27 +260,6 @@ fn on_play_bttn_clicked(episode_id: i32) {
|
|||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fn receive() -> glib::Continue {
|
|
||||||
GLOBAL.with(|global| {
|
|
||||||
if let Some((
|
|
||||||
ref download_bttn,
|
|
||||||
ref play_bttn,
|
|
||||||
ref cancel_bttn,
|
|
||||||
ref progress_bar,
|
|
||||||
ref reciever,
|
|
||||||
)) = *global.borrow()
|
|
||||||
{
|
|
||||||
if reciever.try_recv().is_ok() {
|
|
||||||
download_bttn.hide();
|
|
||||||
play_bttn.show();
|
|
||||||
cancel_bttn.hide();
|
|
||||||
progress_bar.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
glib::Continue(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn episodes_listbox(pd: &Podcast, sender: Sender<Action>) -> Result<gtk::ListBox> {
|
pub fn episodes_listbox(pd: &Podcast, sender: Sender<Action>) -> Result<gtk::ListBox> {
|
||||||
let episodes = dbqueries::get_pd_episodeswidgets(pd)?;
|
let episodes = dbqueries::get_pd_episodeswidgets(pd)?;
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@ use hammond_downloader::downloader;
|
|||||||
use widgets::episode::episodes_listbox;
|
use widgets::episode::episodes_listbox;
|
||||||
use utils::get_pixbuf_from_path;
|
use utils::get_pixbuf_from_path;
|
||||||
use content::ShowStack;
|
use content::ShowStack;
|
||||||
use headerbar::Header;
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -55,31 +54,20 @@ impl Default for ShowWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ShowWidget {
|
impl ShowWidget {
|
||||||
pub fn new(
|
pub fn new(shows: Rc<ShowStack>, pd: &Podcast, sender: Sender<Action>) -> ShowWidget {
|
||||||
shows: Rc<ShowStack>,
|
|
||||||
header: Rc<Header>,
|
|
||||||
pd: &Podcast,
|
|
||||||
sender: Sender<Action>,
|
|
||||||
) -> ShowWidget {
|
|
||||||
let pdw = ShowWidget::default();
|
let pdw = ShowWidget::default();
|
||||||
pdw.init(shows, header, pd, sender);
|
pdw.init(shows, pd, sender);
|
||||||
pdw
|
pdw
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(&self, shows: Rc<ShowStack>, pd: &Podcast, sender: Sender<Action>) {
|
||||||
&self,
|
|
||||||
shows: Rc<ShowStack>,
|
|
||||||
header: Rc<Header>,
|
|
||||||
pd: &Podcast,
|
|
||||||
sender: Sender<Action>,
|
|
||||||
) {
|
|
||||||
// Hacky workaround so the pd.id() can be retrieved from the `ShowStack`.
|
// Hacky workaround so the pd.id() can be retrieved from the `ShowStack`.
|
||||||
WidgetExt::set_name(&self.container, &pd.id().to_string());
|
WidgetExt::set_name(&self.container, &pd.id().to_string());
|
||||||
|
|
||||||
self.unsub
|
self.unsub
|
||||||
.connect_clicked(clone!(shows, pd, sender => move |bttn| {
|
.connect_clicked(clone!(shows, pd, sender => move |bttn| {
|
||||||
on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone());
|
on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone());
|
||||||
header.switch_to_normal();
|
sender.send(Action::HeaderBarNormal).unwrap();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.setup_listbox(pd, sender.clone());
|
self.setup_listbox(pd, sender.clone());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user