Accept an overlay widget that the revealer will be attached to into the show method. Thus revealer field no longer need to be public.
96 lines
2.8 KiB
Rust
96 lines
2.8 KiB
Rust
use glib;
|
|
use gtk;
|
|
use gtk::prelude::*;
|
|
|
|
use app::Action;
|
|
|
|
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
use std::sync::mpsc::Sender;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct InAppNotification {
|
|
revealer: gtk::Revealer,
|
|
text: gtk::Label,
|
|
undo: gtk::Button,
|
|
close: gtk::Button,
|
|
}
|
|
|
|
impl Default for InAppNotification {
|
|
fn default() -> Self {
|
|
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/inapp_notif.ui");
|
|
|
|
let revealer: gtk::Revealer = builder.get_object("revealer").unwrap();
|
|
let text: gtk::Label = builder.get_object("text").unwrap();
|
|
let undo: gtk::Button = builder.get_object("undo").unwrap();
|
|
let close: gtk::Button = builder.get_object("close").unwrap();
|
|
|
|
InAppNotification {
|
|
revealer,
|
|
text,
|
|
undo,
|
|
close,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl InAppNotification {
|
|
pub fn new<F, U>(
|
|
text: String,
|
|
mut callback: F,
|
|
undo_callback: U,
|
|
sender: Sender<Action>,
|
|
) -> Self
|
|
where
|
|
F: FnMut() -> glib::Continue + 'static,
|
|
U: Fn() + 'static,
|
|
{
|
|
let notif = InAppNotification::default();
|
|
notif.text.set_text(&text);
|
|
|
|
let revealer = notif.revealer.clone();
|
|
let id = timeout_add_seconds(6, move || {
|
|
revealer.set_reveal_child(false);
|
|
callback()
|
|
});
|
|
let id = Rc::new(RefCell::new(Some(id)));
|
|
|
|
// Cancel the callback
|
|
let revealer = notif.revealer.clone();
|
|
notif.undo.connect_clicked(move |_| {
|
|
let foo = id.borrow_mut().take();
|
|
if let Some(id) = foo {
|
|
glib::source::source_remove(id);
|
|
}
|
|
|
|
undo_callback();
|
|
|
|
// Hide the notification
|
|
revealer.set_reveal_child(false);
|
|
// Refresh the widget if visible
|
|
if let Err(err) = sender.send(Action::RefreshWidgetIfVis) {
|
|
error!("Action channel blew up: {}", err)
|
|
}
|
|
});
|
|
|
|
// Hide the revealer when the close button is clicked
|
|
let revealer = notif.revealer.clone();
|
|
notif.close.connect_clicked(move |_| {
|
|
revealer.set_reveal_child(false);
|
|
});
|
|
|
|
notif
|
|
}
|
|
|
|
// This is a seperate method cause in order to get a nice animation
|
|
// the revealer should be attached to something that displays it.
|
|
// Previously we where doing it in the constructor, which had the result
|
|
// of the animation being skipped cause there was no parent widget to display it.
|
|
pub fn show(&self, overlay: >k::Overlay) {
|
|
overlay.add_overlay(&self.revealer);
|
|
// We need to display the notification after the widget is added to the overlay
|
|
// so there will be a nice animation.
|
|
self.revealer.set_reveal_child(true);
|
|
}
|
|
}
|