Working non-state machine stack implementation.
Removed the stack state-machines. It was confusing trying to both implement statemachines and re-design the stack architecture at the same time.
This commit is contained in:
parent
211b36dfa3
commit
01310ee7fa
@ -1,318 +1,167 @@
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
|
||||
// use hammond_data::Podcast;
|
||||
use hammond_data::Podcast;
|
||||
use hammond_data::dbqueries;
|
||||
|
||||
use widgets::podcast::PodcastWidget;
|
||||
use views::podcasts::PopulatedView;
|
||||
use views::empty::EmptyView;
|
||||
use widgets::podcast::PodcastWidget;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Content {
|
||||
pub stack: gtk::Stack,
|
||||
shows: ShowStateWrapper,
|
||||
episodes: EpisodeStateWrapper,
|
||||
shows: Rc<ShowStack>,
|
||||
episodes: Rc<EpisodeStack>,
|
||||
}
|
||||
|
||||
impl Content {
|
||||
pub fn new() -> Content {
|
||||
pub fn new() -> Rc<Content> {
|
||||
let stack = gtk::Stack::new();
|
||||
let shows = ShowStateWrapper::new();
|
||||
let episodes = EpisodeStateWrapper::new();
|
||||
let shows = ShowStack::new();
|
||||
let episodes = EpisodeStack::new();
|
||||
|
||||
let shows_stack = shows.get_stack();
|
||||
let ep_stack = episodes.get_stack();
|
||||
stack.add_titled(&episodes.stack, "episodes", "Episodes");
|
||||
stack.add_titled(&shows.stack, "shows", "Shows");
|
||||
|
||||
stack.add_titled(&ep_stack, "episodes", "Episodes");
|
||||
stack.add_titled(&shows_stack, "shows", "Shows");
|
||||
|
||||
Content {
|
||||
Rc::new(Content {
|
||||
stack,
|
||||
shows,
|
||||
episodes,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
self.shows = self.shows.clone().update();
|
||||
// FIXME: like above
|
||||
pub fn update(&self) {
|
||||
self.shows.update();
|
||||
self.episodes.update();
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) {
|
||||
// update_widget(stack, pd);
|
||||
// stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft);
|
||||
// }
|
||||
|
||||
// FIXME: Rename and remove aliases
|
||||
type ShowsPopulated = PopulatedView;
|
||||
type ShowsEmpty = EmptyView;
|
||||
type EpisodesPopulated = PodcastWidget;
|
||||
type EpisodesEmpty = EmptyView;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Populated;
|
||||
#[derive(Debug, Clone)]
|
||||
struct Empty;
|
||||
// struct Shows;
|
||||
// struct Episodes;
|
||||
|
||||
// Thats probably too overengineered
|
||||
// struct StackStateMachine<S, T> {
|
||||
// shows: ShowsMachine<S>,
|
||||
// episodes: EpisodesMachine<S>,
|
||||
// stack: gtk::Stack,
|
||||
// state: T,
|
||||
// }
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ShowsMachine<S> {
|
||||
populated: ShowsPopulated,
|
||||
empty: ShowsEmpty,
|
||||
stack: gtk::Stack,
|
||||
state: S,
|
||||
pub struct ShowStack {
|
||||
pub stack: gtk::Stack,
|
||||
}
|
||||
|
||||
impl<S> ShowsMachine<S> {
|
||||
fn new(state: S) -> ShowsMachine<S> {
|
||||
impl ShowStack {
|
||||
fn new() -> Rc<ShowStack> {
|
||||
let stack = gtk::Stack::new();
|
||||
let pop = ShowsPopulated::new_initialized();
|
||||
|
||||
let show = Rc::new(ShowStack { stack });
|
||||
|
||||
let pop = PopulatedView::new_initialized(show.clone());
|
||||
let widget = PodcastWidget::new();
|
||||
let empty = EmptyView::new();
|
||||
stack.add_named(&pop.container, "populated");
|
||||
stack.add_named(&empty.container, "empty");
|
||||
|
||||
ShowsMachine {
|
||||
empty,
|
||||
populated: pop,
|
||||
stack,
|
||||
state,
|
||||
show.stack.add_named(&pop.container, "podcasts");
|
||||
show.stack.add_named(&widget.container, "widget");
|
||||
show.stack.add_named(&empty.container, "empty");
|
||||
|
||||
if pop.is_empty() {
|
||||
show.stack.set_visible_child_name("empty")
|
||||
} else {
|
||||
show.stack.set_visible_child_name("podcasts")
|
||||
}
|
||||
|
||||
show
|
||||
}
|
||||
|
||||
fn update(&mut self) {
|
||||
// fn is_empty(&self) -> bool {
|
||||
// self.podcasts.is_empty()
|
||||
// }
|
||||
|
||||
pub fn update(&self) {
|
||||
self.update_podcasts();
|
||||
self.update_widget();
|
||||
}
|
||||
|
||||
pub fn update_podcasts(&self) {
|
||||
let vis = self.stack.get_visible_child_name().unwrap();
|
||||
let old = self.stack.get_child_by_name("populated").unwrap();
|
||||
let old = self.stack.get_child_by_name("podcasts").unwrap();
|
||||
|
||||
let pop = PopulatedView::new();
|
||||
pop.init(Rc::new(self.clone()));
|
||||
|
||||
self.stack.remove(&old);
|
||||
self.stack.add_named(&pop.container, "podcasts");
|
||||
|
||||
let pop = ShowsPopulated::new_initialized();
|
||||
self.populated = pop;
|
||||
self.stack.add_named(&self.populated.container, "populated");
|
||||
self.stack.set_visible_child_name(&vis);
|
||||
if pop.is_empty() {
|
||||
self.stack.set_visible_child_name("empty");
|
||||
} else if vis != "empty" {
|
||||
self.stack.set_visible_child_name(&vis);
|
||||
} else {
|
||||
self.stack.set_visible_child_name("podcasts");
|
||||
}
|
||||
|
||||
old.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct EpisodesMachine<S> {
|
||||
populated: EpisodesPopulated,
|
||||
empty: EpisodesEmpty,
|
||||
stack: gtk::Stack,
|
||||
state: S,
|
||||
}
|
||||
pub fn replace_widget(&self, pd: &Podcast) {
|
||||
let old = self.stack.get_child_by_name("widget").unwrap();
|
||||
let new = PodcastWidget::new_initialized(Rc::new(self.clone()), pd);
|
||||
|
||||
impl<S> EpisodesMachine<S> {
|
||||
// FIXME:
|
||||
fn update(&mut self) {
|
||||
self.stack.remove(&old);
|
||||
self.stack.add_named(&new.container, "widget");
|
||||
}
|
||||
|
||||
pub fn update_widget(&self) {
|
||||
let vis = self.stack.get_visible_child_name().unwrap();
|
||||
let old = self.stack.get_child_by_name("populated").unwrap();
|
||||
let old = self.stack.get_child_by_name("widget").unwrap();
|
||||
|
||||
let id = WidgetExt::get_name(&old).unwrap();
|
||||
if id == "GtkBox" {
|
||||
return;
|
||||
}
|
||||
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap()).unwrap();
|
||||
let pdw = EpisodesPopulated::new_initialized(&self.stack, &pd);
|
||||
|
||||
self.populated = pdw;
|
||||
self.stack.remove(&old);
|
||||
self.stack.add_named(&self.populated.container, "populated");
|
||||
self.stack.set_visible_child_name(&vis);
|
||||
}
|
||||
}
|
||||
|
||||
// impl Into<StackStateMachine<Populated, Shows>> for StackStateMachine<Populated, Episodes> {
|
||||
// fn into(self) -> StackStateMachine<Populated, Shows> {
|
||||
// self.stack.set_visible_child_name("shows");
|
||||
|
||||
// StackStateMachine {
|
||||
// shows: self.shows,
|
||||
// episodes: self.episodes,
|
||||
// stack: self.stack,
|
||||
// state: Shows {},
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl Into<StackStateMachine<Populated, Episodes>> for StackStateMachine<Populated, Shows> {
|
||||
// fn into(self) -> StackStateMachine<Populated, Episodes> {
|
||||
// self.stack.set_visible_child_name("episodes");
|
||||
|
||||
// StackStateMachine {
|
||||
// shows: self.shows,
|
||||
// episodes: self.episodes,
|
||||
// stack: self.stack,
|
||||
// state: Episodes {},
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO: Impl <From> instead of <Into>
|
||||
impl Into<ShowsMachine<Populated>> for ShowsMachine<Empty> {
|
||||
fn into(self) -> ShowsMachine<Populated> {
|
||||
self.stack.set_visible_child_name("populated");
|
||||
|
||||
ShowsMachine {
|
||||
populated: self.populated,
|
||||
empty: self.empty,
|
||||
stack: self.stack,
|
||||
state: Populated {},
|
||||
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>().unwrap());
|
||||
if let Ok(pd) = pd {
|
||||
self.replace_widget(&pd);
|
||||
self.stack.set_visible_child_name(&vis);
|
||||
old.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ShowsMachine<Empty>> for ShowsMachine<Populated> {
|
||||
fn into(self) -> ShowsMachine<Empty> {
|
||||
self.stack.set_visible_child_name("empty");
|
||||
|
||||
ShowsMachine {
|
||||
populated: self.populated,
|
||||
empty: self.empty,
|
||||
stack: self.stack,
|
||||
state: Empty {},
|
||||
}
|
||||
pub fn switch_podcasts_animated(&self) {
|
||||
self.stack
|
||||
.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight);
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<EpisodesMachine<Populated>> for EpisodesMachine<Empty> {
|
||||
fn into(self) -> EpisodesMachine<Populated> {
|
||||
self.stack.set_visible_child_name("populated");
|
||||
|
||||
EpisodesMachine {
|
||||
populated: self.populated,
|
||||
empty: self.empty,
|
||||
stack: self.stack,
|
||||
state: Populated {},
|
||||
}
|
||||
pub fn switch_widget_animated(&self) {
|
||||
self.stack
|
||||
.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<EpisodesMachine<Empty>> for EpisodesMachine<Populated> {
|
||||
fn into(self) -> EpisodesMachine<Empty> {
|
||||
self.stack.set_visible_child_name("empty");
|
||||
|
||||
EpisodesMachine {
|
||||
populated: self.populated,
|
||||
empty: self.empty,
|
||||
stack: self.stack,
|
||||
state: Empty {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enum StackStateWrapper<S> {
|
||||
// Shows(StackStateMachine<S, Shows>),
|
||||
// Episodes(StackStateMachine<S, Episodes>),
|
||||
// }
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ShowStateWrapper {
|
||||
Populated(ShowsMachine<Populated>),
|
||||
Empty(ShowsMachine<Empty>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum EpisodeStateWrapper {
|
||||
Populated(EpisodesMachine<Populated>),
|
||||
Empty(EpisodesMachine<Empty>),
|
||||
struct RecentEpisodes;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct EpisodeStack {
|
||||
// populated: RecentEpisodes,
|
||||
// empty: EmptyView,
|
||||
stack: gtk::Stack,
|
||||
}
|
||||
|
||||
// impl <S>StackStateWrapper<S> {
|
||||
// fn switch(mut self) -> Self {
|
||||
// match self {
|
||||
// StackStateWrapper::Shows(val) => StackStateWrapper::Episodes(val.into()),
|
||||
// StackStateWrapper::Episodes(val) => StackStateWrapper::Shows(val.into())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl ShowStateWrapper {
|
||||
fn new() -> Self {
|
||||
let machine = ShowsMachine::new(Populated {});
|
||||
|
||||
if machine.populated.flowbox.get_children().is_empty() {
|
||||
machine.stack.set_visible_child_name("empty");
|
||||
ShowStateWrapper::Empty(machine.into())
|
||||
} else {
|
||||
machine.stack.set_visible_child_name("populated");
|
||||
ShowStateWrapper::Populated(machine)
|
||||
}
|
||||
}
|
||||
|
||||
fn update(mut self) -> Self {
|
||||
match self {
|
||||
ShowStateWrapper::Populated(ref mut val) => val.update(),
|
||||
ShowStateWrapper::Empty(ref mut val) => val.update(),
|
||||
}
|
||||
|
||||
if self.is_empty() {
|
||||
match self {
|
||||
ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()),
|
||||
_ => self,
|
||||
}
|
||||
} else {
|
||||
match self {
|
||||
ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()),
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_stack(&self) -> gtk::Stack {
|
||||
match *self {
|
||||
ShowStateWrapper::Populated(ref val) => val.stack.clone(),
|
||||
ShowStateWrapper::Empty(ref val) => val.stack.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
match *self {
|
||||
ShowStateWrapper::Populated(ref val) => val.populated.flowbox.get_children().is_empty(),
|
||||
ShowStateWrapper::Empty(ref val) => val.populated.flowbox.get_children().is_empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EpisodeStateWrapper {
|
||||
// FIXME:
|
||||
fn new() -> Self {
|
||||
let pop = PodcastWidget::new();
|
||||
impl EpisodeStack {
|
||||
fn new() -> Rc<EpisodeStack> {
|
||||
let _pop = RecentEpisodes {};
|
||||
let empty = EmptyView::new();
|
||||
let stack = gtk::Stack::new();
|
||||
|
||||
stack.add_named(&pop.container, "populated");
|
||||
// stack.add_named(&pop.container, "populated");
|
||||
stack.add_named(&empty.container, "empty");
|
||||
// FIXME:
|
||||
stack.set_visible_child_name("empty");
|
||||
|
||||
EpisodeStateWrapper::Empty(EpisodesMachine {
|
||||
empty,
|
||||
populated: pop,
|
||||
Rc::new(EpisodeStack {
|
||||
// empty,
|
||||
// populated: pop,
|
||||
stack,
|
||||
state: Empty {},
|
||||
})
|
||||
}
|
||||
|
||||
fn update(&mut self) {
|
||||
match *self {
|
||||
EpisodeStateWrapper::Populated(ref mut val) => val.update(),
|
||||
EpisodeStateWrapper::Empty(ref mut val) => val.update(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_stack(&self) -> gtk::Stack {
|
||||
match *self {
|
||||
EpisodeStateWrapper::Populated(ref val) => val.stack.clone(),
|
||||
EpisodeStateWrapper::Empty(ref val) => val.stack.clone(),
|
||||
}
|
||||
fn update(&self) {
|
||||
// unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ use gtk::prelude::*;
|
||||
use hammond_data::Source;
|
||||
use hammond_data::utils::url_cleaner;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::rc::Rc;
|
||||
|
||||
use utils;
|
||||
use content::Content;
|
||||
@ -36,23 +36,19 @@ impl Header {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_initialized(content: Arc<Mutex<Content>>) -> Header {
|
||||
pub fn new_initialized(content: Rc<Content>) -> Header {
|
||||
let header = Header::new();
|
||||
header.init(content);
|
||||
header
|
||||
}
|
||||
|
||||
fn init(&self, content: Arc<Mutex<Content>>) {
|
||||
fn init(&self, content: Rc<Content>) {
|
||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui");
|
||||
|
||||
let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap();
|
||||
let new_url: gtk::Entry = builder.get_object("new-url").unwrap();
|
||||
let add_button: gtk::Button = builder.get_object("add-button").unwrap();
|
||||
|
||||
{
|
||||
let cont = content.lock().unwrap();
|
||||
self.switch.set_stack(&cont.stack);
|
||||
}
|
||||
self.switch.set_stack(&content.stack);
|
||||
|
||||
new_url.connect_changed(move |url| {
|
||||
println!("{:?}", url.get_text());
|
||||
@ -68,14 +64,13 @@ impl Header {
|
||||
self.add_toggle.set_popover(&add_popover);
|
||||
|
||||
// FIXME: There appears to be a memmory leak here.
|
||||
let cont = content.clone();
|
||||
self.refresh.connect_clicked(move |_| {
|
||||
utils::refresh_feed(cont.clone(), None, None);
|
||||
utils::refresh_feed(content.clone(), None, None);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn on_add_bttn_clicked(content: Arc<Mutex<Content>>, entry: >k::Entry) {
|
||||
fn on_add_bttn_clicked(content: Rc<Content>, entry: >k::Entry) {
|
||||
let url = entry.get_text().unwrap_or_default();
|
||||
let url = url_cleaner(&url);
|
||||
let source = Source::from_url(&url);
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clone_on_ref_ptr))]
|
||||
|
||||
extern crate gdk;
|
||||
extern crate gdk_pixbuf;
|
||||
extern crate gio;
|
||||
@ -22,8 +24,6 @@ use hammond_data::utils::checkup;
|
||||
use gtk::prelude::*;
|
||||
use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt};
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
// http://gtk-rs.org/tuto/closures
|
||||
#[macro_export]
|
||||
macro_rules! clone {
|
||||
@ -72,7 +72,6 @@ fn build_ui(app: >k::Application) {
|
||||
// let ct = content::Content::new_initialized();
|
||||
let ct = content::Content::new();
|
||||
let stack = ct.stack.clone();
|
||||
let ct = Arc::new(Mutex::new(ct));
|
||||
window.add(&stack);
|
||||
|
||||
window.connect_delete_event(|w, _| {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use glib;
|
||||
use gtk;
|
||||
use gdk_pixbuf::Pixbuf;
|
||||
|
||||
use hammond_data::feed;
|
||||
@ -9,14 +8,12 @@ use hammond_downloader::downloader;
|
||||
use std::{thread, time};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use content::Content;
|
||||
use regex::Regex;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::rc::Rc;
|
||||
|
||||
type Foo = RefCell<Option<(Arc<Mutex<Content>>, Receiver<bool>)>>;
|
||||
type Foo = RefCell<Option<(Rc<Content>, Receiver<bool>)>>;
|
||||
|
||||
// Create a thread local storage that will store the arguments to be transfered.
|
||||
thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
||||
@ -25,13 +22,13 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None));
|
||||
/// If `source` is None, Fetches all the `Source` entries in the database and updates them.
|
||||
/// `delay` represents the desired time in seconds for the thread to sleep before executing.
|
||||
/// When It's done,it queues up a `podcast_view` refresh.
|
||||
pub fn refresh_feed(content: Arc<Mutex<Content>>, source: Option<Vec<Source>>, delay: Option<u64>) {
|
||||
pub fn refresh_feed(content: Rc<Content>, source: Option<Vec<Source>>, delay: Option<u64>) {
|
||||
// Create a async channel.
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
// Pass the desired arguments into the Local Thread Storage.
|
||||
GLOBAL.with(clone!(content => move |global| {
|
||||
*global.borrow_mut() = Some((content, receiver));
|
||||
*global.borrow_mut() = Some((content.clone(), receiver));
|
||||
}));
|
||||
|
||||
thread::spawn(move || {
|
||||
@ -61,7 +58,6 @@ fn refresh_podcasts_view() -> glib::Continue {
|
||||
GLOBAL.with(|global| {
|
||||
if let Some((ref content, ref reciever)) = *global.borrow() {
|
||||
if reciever.try_recv().is_ok() {
|
||||
let mut content = content.lock().unwrap();
|
||||
content.update();
|
||||
}
|
||||
}
|
||||
@ -74,18 +70,6 @@ pub fn get_pixbuf_from_path(pd: &Podcast) -> Option<Pixbuf> {
|
||||
Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// WIP: parse html to markup
|
||||
pub fn html_to_markup(s: &mut str) -> Cow<str> {
|
||||
s.trim();
|
||||
s.replace('&', "&");
|
||||
s.replace('<', "<");
|
||||
s.replace('>', ">");
|
||||
|
||||
let re = Regex::new("(?P<url>https?://[^\\s&,)(\"]+(&\\w=[\\w._-]?)*(#[\\w._-]+)?)").unwrap();
|
||||
re.replace_all(s, "<a href=\"$url\">$url</a>")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hammond_data::Source;
|
||||
|
||||
@ -7,8 +7,9 @@ use hammond_data::dbqueries;
|
||||
use hammond_data::Podcast;
|
||||
|
||||
use utils::get_pixbuf_from_path;
|
||||
use content::ShowStack;
|
||||
|
||||
// use content;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PopulatedView {
|
||||
@ -42,25 +43,29 @@ impl PopulatedView {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn new_initialized() -> PopulatedView {
|
||||
pub fn new_initialized(show: Rc<ShowStack>) -> PopulatedView {
|
||||
let pop = PopulatedView::new();
|
||||
pop.init();
|
||||
pop.init(show);
|
||||
pop
|
||||
}
|
||||
|
||||
pub fn init(&self) {
|
||||
// pub fn init(&self, stack: >k::Stack) {
|
||||
// use gtk::WidgetExt;
|
||||
pub fn init(&self, show: Rc<ShowStack>) {
|
||||
use gtk::WidgetExt;
|
||||
|
||||
// // TODO: handle unwraps.
|
||||
// self.flowbox
|
||||
// .connect_child_activated(clone!(stack => move |_, child| {
|
||||
// // This is such an ugly hack...
|
||||
// // let id = child.get_name().unwrap().parse::<i32>().unwrap();
|
||||
// let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
|
||||
// let parent = dbqueries::get_podcast_from_id(id).unwrap();
|
||||
// on_flowbox_child_activate(&stack, &parent);
|
||||
// }));
|
||||
// TODO: handle unwraps.
|
||||
// Note: flowbox_activation always adds "widnget" into the stack and switch to it,
|
||||
// TODO: implement back button.
|
||||
// so back button should always remove "widget" and destroy it.
|
||||
let show = show.clone();
|
||||
self.flowbox
|
||||
.connect_child_activated(clone!(show => move |_, child| {
|
||||
// This is such an ugly hack...
|
||||
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
|
||||
let pd = dbqueries::get_podcast_from_id(id).unwrap();
|
||||
|
||||
show.replace_widget(&pd);
|
||||
show.switch_widget_animated();
|
||||
}));
|
||||
// Populate the flowbox with the Podcasts.
|
||||
self.populate_flowbox();
|
||||
}
|
||||
@ -76,6 +81,10 @@ impl PopulatedView {
|
||||
self.flowbox.show_all();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.flowbox.get_children().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl PodcastChild {
|
||||
@ -139,7 +148,3 @@ impl PodcastChild {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn on_flowbox_child_activate(stack: >k::Stack, parent: &Podcast) {
|
||||
// content::on_podcasts_child_activate(stack, parent)
|
||||
// }
|
||||
|
||||
@ -10,7 +10,8 @@ use hammond_downloader::downloader;
|
||||
|
||||
use widgets::episode::episodes_listbox;
|
||||
use utils::get_pixbuf_from_path;
|
||||
// use content;
|
||||
use content::ShowStack;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PodcastWidget {
|
||||
@ -47,18 +48,18 @@ impl PodcastWidget {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_initialized(stack: >k::Stack, pd: &Podcast) -> PodcastWidget {
|
||||
pub fn new_initialized(shows: Rc<ShowStack>, pd: &Podcast) -> PodcastWidget {
|
||||
let pdw = PodcastWidget::new();
|
||||
pdw.init(stack, pd);
|
||||
pdw.init(shows, pd);
|
||||
pdw
|
||||
}
|
||||
|
||||
pub fn init(&self, stack: >k::Stack, pd: &Podcast) {
|
||||
pub fn init(&self, shows: Rc<ShowStack>, pd: &Podcast) {
|
||||
WidgetExt::set_name(&self.container, &pd.id().to_string());
|
||||
|
||||
// TODO: should spawn a thread to avoid locking the UI probably.
|
||||
self.unsub.connect_clicked(clone!(stack, pd => move |bttn| {
|
||||
on_unsub_button_clicked(&stack, &pd, bttn);
|
||||
self.unsub.connect_clicked(clone!(shows, pd => move |bttn| {
|
||||
on_unsub_button_clicked(shows.clone(), &pd, bttn);
|
||||
}));
|
||||
|
||||
self.title.set_text(pd.title());
|
||||
@ -77,8 +78,8 @@ impl PodcastWidget {
|
||||
self.cover.set_from_pixbuf(&i);
|
||||
}
|
||||
|
||||
self.played.connect_clicked(clone!(stack, pd => move |_| {
|
||||
on_played_button_clicked(&stack, &pd);
|
||||
self.played.connect_clicked(clone!(shows, pd => move |_| {
|
||||
on_played_button_clicked(shows.clone(), &pd);
|
||||
}));
|
||||
|
||||
self.show_played_button(pd);
|
||||
@ -95,7 +96,7 @@ impl PodcastWidget {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k::Button) {
|
||||
fn on_unsub_button_clicked(shows: Rc<ShowStack>, pd: &Podcast, unsub_button: >k::Button) {
|
||||
let res = dbqueries::remove_feed(pd);
|
||||
if res.is_ok() {
|
||||
info!("{} was removed succesfully.", pd.title());
|
||||
@ -111,11 +112,12 @@ fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k:
|
||||
}
|
||||
};
|
||||
}
|
||||
// content::update_podcasts(stack);
|
||||
shows.switch_podcasts_animated();
|
||||
shows.update_podcasts();
|
||||
}
|
||||
|
||||
fn on_played_button_clicked(stack: >k::Stack, pd: &Podcast) {
|
||||
fn on_played_button_clicked(shows: Rc<ShowStack>, pd: &Podcast) {
|
||||
let _ = dbqueries::update_none_to_played_now(pd);
|
||||
|
||||
// content::update_widget_preserve_vis(stack, pd);
|
||||
shows.update_widget();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user