GtkApplication: Start to refactor to into a App-channel structure.

This commit is contained in:
Jordan Petridis 2018-01-03 05:58:50 +02:00
parent a0476fedec
commit c8537e9474
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
2 changed files with 45 additions and 18 deletions

View File

@ -5,19 +5,28 @@ use gtk::prelude::*;
use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt};
use hammond_data::utils::checkup; use hammond_data::utils::checkup;
use hammond_data::Source;
use headerbar::Header; use headerbar::Header;
use content::Content; use content::Content;
use utils; use utils;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::{channel, Receiver};
use std::time::Duration;
#[derive(Debug, Clone)] #[derive(Clone, Debug)]
pub enum Action {
UpdateSources(Option<Source>),
}
#[derive(Debug)]
pub struct App { pub struct App {
app_instance: gtk::Application, app_instance: gtk::Application,
window: gtk::Window, window: gtk::Window,
header: Rc<Header>, header: Rc<Header>,
content: Rc<Content>, content: Rc<Content>,
receiver: Receiver<Action>,
} }
impl App { impl App {
@ -34,11 +43,14 @@ impl App {
let window = gtk::Window::new(gtk::WindowType::Toplevel); let window = gtk::Window::new(gtk::WindowType::Toplevel);
window.set_default_size(860, 640); window.set_default_size(860, 640);
window.set_title("Hammond"); window.set_title("Hammond");
window.connect_delete_event(|w, _| { let app_clone = application.clone();
w.destroy(); window.connect_delete_event(move |_, _| {
app_clone.quit();
Inhibit(false) Inhibit(false)
}); });
let (sender, receiver) = channel();
// TODO: Refactor the initialization order. // TODO: Refactor the initialization order.
// Create the headerbar // Create the headerbar
@ -48,7 +60,7 @@ impl App {
let content = Content::new(header.clone()); let content = Content::new(header.clone());
// Initialize the headerbar // Initialize the headerbar
header.init(content.clone()); 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);
@ -60,6 +72,7 @@ impl App {
window, window,
header, header,
content, content,
receiver,
} }
} }
@ -132,7 +145,7 @@ impl App {
}); });
} }
pub fn run(&self) { pub fn run(self) {
let window = self.window.clone(); let window = self.window.clone();
let app = self.app_instance.clone(); let app = self.app_instance.clone();
self.app_instance.connect_startup(move |_| { self.app_instance.connect_startup(move |_| {
@ -141,6 +154,22 @@ impl App {
self.setup_timed_callbacks(); self.setup_timed_callbacks();
self.setup_actions(); self.setup_actions();
let receiver = self.receiver;
let content = self.content.clone();
let headerbar = self.header.clone();
gtk::idle_add(clone!(content, headerbar => move || {
match receiver.recv_timeout(Duration::from_millis(5)) {
Ok(Action::UpdateSources(source)) => {
if let Some(s) = source {
utils::refresh_feed(content.clone(), headerbar.clone(), Some(vec!(s)))
}
}
_ => (),
}
Continue(true)
}));
ApplicationExtManual::run(&self.app_instance, &[]); ApplicationExtManual::run(&self.app_instance, &[]);
} }
} }

View File

@ -4,8 +4,9 @@ use gtk::prelude::*;
use hammond_data::Source; use hammond_data::Source;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::Sender;
use app::Action;
use utils;
use content::Content; use content::Content;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -48,13 +49,13 @@ impl Default for Header {
impl Header { impl Header {
#[allow(dead_code)] #[allow(dead_code)]
pub fn new(content: Rc<Content>) -> Rc<Header> { pub fn new(content: Rc<Content>, sender: Sender<Action>) -> Rc<Header> {
let h = Header::default(); let h = Header::default();
h.init(content); h.init(content, sender);
Rc::new(h) Rc::new(h)
} }
pub fn init(&self, content: Rc<Content>) { pub fn init(&self, content: Rc<Content>, sender: Sender<Action>) {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); 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 add_popover: gtk::Popover = builder.get_object("add_popover").unwrap();
@ -66,9 +67,8 @@ impl Header {
println!("{:?}", url.get_text()); println!("{:?}", url.get_text());
}); });
let header = Rc::new(self.clone()); add_button.connect_clicked(clone!(add_popover, new_url, sender => move |_| {
add_button.connect_clicked(clone!(content, header, add_popover, new_url => move |_| { on_add_bttn_clicked(&new_url, sender.clone());
on_add_bttn_clicked(content.clone(), header.clone(), &new_url);
add_popover.hide(); add_popover.hide();
})); }));
@ -122,16 +122,14 @@ impl Header {
} }
} }
fn on_add_bttn_clicked(content: Rc<Content>, headerbar: Rc<Header>, entry: &gtk::Entry) { fn on_add_bttn_clicked(entry: &gtk::Entry, sender: Sender<Action>) {
let url = entry.get_text().unwrap_or_default(); let url = entry.get_text().unwrap_or_default();
let source = Source::from_url(&url); let source = Source::from_url(&url);
if let Ok(s) = source { if source.is_ok() {
info!("{:?} feed added", url); sender.send(Action::UpdateSources(source.ok())).unwrap();
// update the db
utils::refresh_feed(content, headerbar, Some(vec![s]));
} else { } else {
error!("Feed probably already exists."); error!("Something went wrong.");
error!("Error: {:?}", source.unwrap_err()); error!("Error: {:?}", source.unwrap_err());
} }
} }