95 lines
2.7 KiB
Rust
95 lines
2.7 KiB
Rust
use glib;
|
|
use gtk;
|
|
use gtk::prelude::*;
|
|
|
|
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum UndoState {
|
|
Shown,
|
|
Hidden,
|
|
}
|
|
|
|
#[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: &str, mut callback: F, undo_callback: U, show_undo: UndoState) -> 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);
|
|
});
|
|
|
|
// Hide the revealer when the close button is clicked
|
|
let revealer = notif.revealer.clone();
|
|
notif.close.connect_clicked(move |_| {
|
|
revealer.set_reveal_child(false);
|
|
});
|
|
|
|
match show_undo {
|
|
UndoState::Shown => (),
|
|
UndoState::Hidden => notif.undo.hide(),
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|