Start switching to the new stack architecture.

This commit is contained in:
Jordan Petridis 2017-12-11 11:53:29 +02:00
parent ad7f5013f3
commit fa33138d66
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
4 changed files with 97 additions and 126 deletions

View File

@ -8,78 +8,60 @@ use widgets::podcast::PodcastWidget;
use views::podcasts::PopulatedView; use views::podcasts::PopulatedView;
use views::empty::EmptyView; use views::empty::EmptyView;
#[derive(Debug)]
pub struct Content { pub struct Content {
pub stack: gtk::Stack, pub stack: gtk::Stack,
pub widget: PodcastWidget, shows: ShowStateWrapper,
pub podcasts: PopulatedView, episodes: EpisodeStateWrapper,
pub empty: EmptyView,
} }
impl Content { impl Content {
pub fn new() -> Content { pub fn new() -> Content {
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
let shows = ShowStateWrapper::new();
let episodes = EpisodeStateWrapper::new();
let widget = PodcastWidget::new(); let shows_stack = shows.get_stack();
let podcasts = PopulatedView::new(); let ep_stack = episodes.get_stack();
let empty = EmptyView::new();
stack.add_titled(&widget.container, "widget", "Episodes"); stack.add_titled(&ep_stack, "episodes", "Episodes");
stack.add_titled(&podcasts.container, "podcasts", "Shows"); stack.add_titled(&shows_stack, "shows", "Shows");
stack.add_named(&empty.container, "empty");
Content { Content {
stack, stack,
widget, shows,
empty, episodes,
podcasts,
} }
} }
pub fn new_initialized() -> Content { // pub fn new_initialized() -> Content {
let ct = Content::new(); // let ct = Content::new();
ct.init(); // ct.init();
ct // ct
} // }
pub fn init(&self) { // pub fn init(&self) {
self.podcasts.init(&self.stack); // self.podcasts.init();
if self.podcasts.flowbox.get_children().is_empty() { // if self.podcasts.flowbox.get_children().is_empty() {
self.stack.set_visible_child_name("empty"); // self.stack.set_visible_child_name("empty");
return; // return;
} // }
self.stack.set_visible_child_name("podcasts"); // self.stack.set_visible_child_name("podcasts");
} // }
fn replace_widget(&mut self, pdw: PodcastWidget) { // fn replace_widget(&mut self, pdw: PodcastWidget) {
let vis = self.stack.get_visible_child_name().unwrap(); // let vis = self.stack.get_visible_child_name().unwrap();
let old = self.stack.get_child_by_name("widget").unwrap(); // let old = self.stack.get_child_by_name("widget").unwrap();
self.stack.remove(&old); // self.stack.remove(&old);
self.widget = pdw; // self.widget = pdw;
self.stack // self.stack
.add_titled(&self.widget.container, "widget", "Episodes"); // .add_titled(&self.widget.container, "widget", "Episodes");
self.stack.set_visible_child_name(&vis); // self.stack.set_visible_child_name(&vis);
old.destroy(); // old.destroy();
} // }
fn replace_podcasts(&mut self, pop: PopulatedView) {
let vis = self.stack.get_visible_child_name().unwrap();
let old = self.stack.get_child_by_name("podcasts").unwrap();
self.stack.remove(&old);
self.podcasts = pop;
self.stack
.add_titled(&self.podcasts.container, "podcasts", "Shows");
self.stack.set_visible_child_name(&vis);
old.destroy();
}
} }
#[derive(Debug)]
// Experiementing with Wrapping gtk::Stack into a State machine.
// Gonna revist it when TryInto trais is stabilized.
pub struct ContentState<S> { pub struct ContentState<S> {
content: Content, content: Content,
state: S, state: S,
@ -89,8 +71,6 @@ pub trait UpdateView {
fn update(&mut self); fn update(&mut self);
} }
pub struct Empty;
#[derive(Debug)] #[derive(Debug)]
pub struct PodcastsView {} pub struct PodcastsView {}
@ -104,34 +84,7 @@ impl UpdateView for ContentState<WidgetsView> {
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap(); let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap();
let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd); let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd);
self.content.replace_widget(pdw); // self.content.replace_widget(pdw);
}
}
impl ContentState<PodcastsView> {
#[allow(dead_code)]
pub fn new() -> Result<ContentState<PodcastsView>, ContentState<Empty>> {
let content = Content::new();
content.podcasts.init(&content.stack);
if content.podcasts.flowbox.get_children().is_empty() {
content.stack.set_visible_child_name("empty");
return Err(ContentState {
content,
state: Empty {},
});
}
content.stack.set_visible_child_name("podcasts");
Ok(ContentState {
content,
state: PodcastsView {},
})
}
#[allow(dead_code)]
pub fn get_stack(&self) -> gtk::Stack {
self.content.stack.clone()
} }
} }
@ -149,25 +102,8 @@ fn replace_podcasts(stack: &gtk::Stack, pop: &PopulatedView) {
old.destroy(); old.destroy();
} }
#[allow(dead_code)]
pub fn show_widget(stack: &gtk::Stack) {
stack.set_visible_child_name("widget")
}
pub fn show_podcasts(stack: &gtk::Stack) {
stack.set_visible_child_name("podcasts")
}
pub fn show_empty(stack: &gtk::Stack) {
stack.set_visible_child_name("empty")
}
pub fn update_podcasts(stack: &gtk::Stack) { pub fn update_podcasts(stack: &gtk::Stack) {
let pods = PopulatedView::new_initialized(stack); let pods = PopulatedView::new_initialized();
if pods.flowbox.get_children().is_empty() {
show_empty(stack)
}
replace_podcasts(stack, &pods); replace_podcasts(stack, &pods);
} }
@ -191,10 +127,10 @@ pub fn update_widget_preserve_vis(stack: &gtk::Stack, pd: &Podcast) {
stack.set_visible_child_name(&vis) stack.set_visible_child_name(&vis)
} }
pub fn on_podcasts_child_activate(stack: &gtk::Stack, pd: &Podcast) { // pub fn on_podcasts_child_activate(stack: &gtk::Stack, pd: &Podcast) {
update_widget(stack, pd); // update_widget(stack, pd);
stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); // stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft);
} // }
// FIXME: Rename and remove aliases // FIXME: Rename and remove aliases
type ShowsPopulated = PopulatedView; type ShowsPopulated = PopulatedView;
@ -203,7 +139,7 @@ type EpisodesPopulated = PodcastWidget;
type EpisodesEmpty = EmptyView; type EpisodesEmpty = EmptyView;
struct Populated; struct Populated;
// struct Empty; struct Empty;
// struct Shows; // struct Shows;
// struct Episodes; // struct Episodes;
@ -229,7 +165,7 @@ impl<S> ShowsMachine<S> {
let old = self.stack.get_child_by_name("shows").unwrap(); let old = self.stack.get_child_by_name("shows").unwrap();
self.stack.remove(&old); self.stack.remove(&old);
let pop = ShowsPopulated::new_initialized(&self.stack); let pop = ShowsPopulated::new_initialized();
self.populated = pop; self.populated = pop;
self.stack self.stack
.add_titled(&self.populated.container, "shows", "Shows"); .add_titled(&self.populated.container, "shows", "Shows");
@ -351,8 +287,10 @@ enum EpisodeStateWrapper {
impl ShowStateWrapper { impl ShowStateWrapper {
fn new() -> Self { fn new() -> Self {
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
let pop = ShowsPopulated::new_initialized(&stack); let pop = ShowsPopulated::new_initialized();
let empty = EmptyView::new(); let empty = EmptyView::new();
stack.add_named(&pop.container, "populated");
stack.add_named(&empty.container, "empty");
if pop.flowbox.get_children().is_empty() { if pop.flowbox.get_children().is_empty() {
stack.set_visible_child_name("empty"); stack.set_visible_child_name("empty");
@ -363,7 +301,7 @@ impl ShowStateWrapper {
state: Empty {}, state: Empty {},
}) })
} else { } else {
stack.set_visible_child_name("shows"); stack.set_visible_child_name("populated");
ShowStateWrapper::Populated(ShowsMachine { ShowStateWrapper::Populated(ShowsMachine {
empty, empty,
@ -387,13 +325,45 @@ impl ShowStateWrapper {
ShowStateWrapper::Empty(ref mut val) => val.update(), ShowStateWrapper::Empty(ref mut val) => val.update(),
} }
} }
fn get_stack(&self) -> gtk::Stack {
match *self {
ShowStateWrapper::Populated(ref val) => val.stack.clone(),
ShowStateWrapper::Empty(ref val) => val.stack.clone(),
}
}
} }
impl EpisodeStateWrapper { impl EpisodeStateWrapper {
// FIXME:
fn new() -> Self {
let pop = PodcastWidget::new();
let empty = EmptyView::new();
let stack = gtk::Stack::new();
stack.add_named(&pop.container, "populated");
stack.add_named(&empty.container, "empty");
stack.set_visible_child_name("empty");
EpisodeStateWrapper::Empty(EpisodesMachine {
empty,
populated: pop,
stack,
state: Empty {},
})
}
fn switch(self) -> Self { fn switch(self) -> Self {
match self { match self {
EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()), EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()),
EpisodeStateWrapper::Empty(val) => EpisodeStateWrapper::Populated(val.into()), EpisodeStateWrapper::Empty(val) => EpisodeStateWrapper::Populated(val.into()),
} }
} }
fn get_stack(&self) -> gtk::Stack {
match *self {
EpisodeStateWrapper::Populated(ref val) => val.stack.clone(),
EpisodeStateWrapper::Empty(ref val) => val.stack.clone(),
}
}
} }

View File

@ -67,7 +67,8 @@ fn build_ui(app: &gtk::Application) {
// let ct = content::ContentState::new().unwrap(); // let ct = content::ContentState::new().unwrap();
// let stack = ct.get_stack(); // let stack = ct.get_stack();
let ct = content::Content::new_initialized(); // let ct = content::Content::new_initialized();
let ct = content::Content::new();
let stack = ct.stack; let stack = ct.stack;
window.add(&stack); window.add(&stack);

View File

@ -8,7 +8,7 @@ use hammond_data::Podcast;
use utils::get_pixbuf_from_path; use utils::get_pixbuf_from_path;
use content; // use content;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PopulatedView { pub struct PopulatedView {
@ -42,24 +42,25 @@ impl PopulatedView {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn new_initialized(stack: &gtk::Stack) -> PopulatedView { pub fn new_initialized() -> PopulatedView {
let pop = PopulatedView::new(); let pop = PopulatedView::new();
pop.init(stack); pop.init();
pop pop
} }
pub fn init(&self, stack: &gtk::Stack) { pub fn init(&self) {
use gtk::WidgetExt; // pub fn init(&self, stack: &gtk::Stack) {
// use gtk::WidgetExt;
// TODO: handle unwraps. // // TODO: handle unwraps.
self.flowbox // self.flowbox
.connect_child_activated(clone!(stack => move |_, child| { // .connect_child_activated(clone!(stack => move |_, child| {
// This is such an ugly hack... // // This is such an ugly hack...
// let id = child.get_name().unwrap().parse::<i32>().unwrap(); // // let id = child.get_name().unwrap().parse::<i32>().unwrap();
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap(); // let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
let parent = dbqueries::get_podcast_from_id(id).unwrap(); // let parent = dbqueries::get_podcast_from_id(id).unwrap();
on_flowbox_child_activate(&stack, &parent); // on_flowbox_child_activate(&stack, &parent);
})); // }));
// Populate the flowbox with the Podcasts. // Populate the flowbox with the Podcasts.
self.populate_flowbox(); self.populate_flowbox();
} }
@ -139,6 +140,6 @@ impl PodcastChild {
} }
} }
fn on_flowbox_child_activate(stack: &gtk::Stack, parent: &Podcast) { // fn on_flowbox_child_activate(stack: &gtk::Stack, parent: &Podcast) {
content::on_podcasts_child_activate(stack, parent) // content::on_podcasts_child_activate(stack, parent)
} // }

View File

@ -112,7 +112,6 @@ fn on_unsub_button_clicked(stack: &gtk::Stack, pd: &Podcast, unsub_button: &gtk:
}; };
} }
content::update_podcasts(stack); content::update_podcasts(stack);
content::show_podcasts(stack);
} }
fn on_played_button_clicked(stack: &gtk::Stack, pd: &Podcast) { fn on_played_button_clicked(stack: &gtk::Stack, pd: &Podcast) {