Add button to close notification

This commit is contained in:
Ian Douglas Scott 2021-09-13 13:48:17 -07:00
parent e0d1224173
commit a82c0a5577
4 changed files with 67 additions and 15 deletions

View file

@ -64,6 +64,9 @@ impl NotificationList {
notifications.connect_notification_recieved(clone!(@weak obj => move |notification| {
obj.handle_notification(&notification);
}));
notifications.connect_notification_closed(clone!(@weak obj => move |id| {
obj.remove_notification(id);
}));
obj
}
@ -74,7 +77,7 @@ impl NotificationList {
fn handle_notification(&self, notification: &Notification) {
let notification_widget = cascade! {
NotificationWidget::new();
NotificationWidget::new(&*self.inner().notifications);
..set_notification(notification);
};
@ -88,6 +91,12 @@ impl NotificationList {
self.inner().rows.borrow_mut().insert(notification.id, row);
}
fn remove_notification(&self, id: NotificationId) {
if let Some(row) = self.inner().rows.borrow_mut().remove(&id) {
self.inner().listbox.remove(&row);
}
}
fn id_for_row(&self, row: &gtk4::ListBoxRow) -> Option<NotificationId> {
let rows = self.inner().rows.borrow();
Some(*rows.iter().find(|(_, i)| i == &row)?.0)

View file

@ -31,19 +31,12 @@ impl ObjectImpl for NotificationPopoverInner {
}));
});
let notification_widget = cascade! {
NotificationWidget::new();
};
cascade! {
obj;
..set_autohide(false);
..set_has_arrow(false);
..set_offset(0, 12);
..set_child(Some(&notification_widget));
};
self.notification_widget.set(notification_widget);
}
}
@ -59,6 +52,12 @@ impl NotificationPopover {
pub fn new(notifications: &Notifications) -> Self {
let obj = glib::Object::new::<Self>(&[]).unwrap();
let notification_widget = cascade! {
NotificationWidget::new(notifications);
};
obj.set_child(Some(&notification_widget));
obj.inner().notification_widget.set(notification_widget);
// XXX disconnect?
obj.inner().notifications.set(notifications.clone());
notifications.connect_notification_recieved(clone!(@weak obj => move |notification| {

View file

@ -1,14 +1,22 @@
use cascade::cascade;
use gtk4::{glib, pango, prelude::*, subclass::prelude::*};
use gtk4::{
glib::{self, clone},
pango,
prelude::*,
subclass::prelude::*,
};
use std::cell::Cell;
use crate::deref_cell::DerefCell;
use crate::notifications::Notification;
use crate::notifications::{Notification, NotificationId, Notifications};
#[derive(Default)]
pub struct NotificationWidgetInner {
box_: DerefCell<gtk4::Box>,
summary_label: DerefCell<gtk4::Label>,
body_label: DerefCell<gtk4::Label>,
notifications: DerefCell<Notifications>,
id: Cell<Option<NotificationId>>,
}
#[glib::object_subclass]
@ -37,10 +45,25 @@ impl ObjectImpl for NotificationWidgetInner {
};
let box_ = cascade! {
gtk4::Box::new(gtk4::Orientation::Vertical, 0);
gtk4::Box::new(gtk4::Orientation::Horizontal, 0);
..set_parent(obj);
..append(&summary_label);
..append(&body_label);
..append(&cascade! {
gtk4::Box::new(gtk4::Orientation::Vertical, 0);
..append(&summary_label);
..append(&body_label);
});
..append(&cascade! {
gtk4::Button::new();
..set_valign(gtk4::Align::Start);
..set_child(Some(&cascade! {
gtk4::Image::from_icon_name(Some("window-close-symbolic"));
}));
..connect_clicked(clone!(@weak obj => move |_| {
if let Some(id) = obj.inner().id.get() {
obj.inner().notifications.dismiss(id);
}
}));
});
};
self.box_.set(box_);
@ -61,8 +84,10 @@ glib::wrapper! {
}
impl NotificationWidget {
pub fn new() -> Self {
glib::Object::new(&[]).unwrap()
pub fn new(notifications: &Notifications) -> Self {
let obj = glib::Object::new::<Self>(&[]).unwrap();
obj.inner().notifications.set(notifications.clone());
obj
}
fn inner(&self) -> &NotificationWidgetInner {
@ -72,5 +97,6 @@ impl NotificationWidget {
pub fn set_notification(&self, notification: &Notification) {
self.inner().summary_label.set_label(&notification.summary);
self.inner().body_label.set_label(&notification.body);
self.inner().id.set(Some(notification.id));
}
}

View file

@ -297,6 +297,8 @@ impl Notifications {
}
fn close_notification(&self, id: NotificationId, reason: CloseReason) {
self.inner().notifications.borrow_mut().remove(&id);
self.emit_by_name("notification-closed", &[&id]).unwrap();
if let Some(connection) = self.inner().connection.borrow().as_ref() {
@ -312,6 +314,10 @@ impl Notifications {
}
}
pub fn dismiss(&self, id: NotificationId) {
self.close_notification(id, CloseReason::Dismiss);
}
fn bus_acquired(&self, connection: gio::DBusConnection, _name: &str) {
*self.inner().connection.borrow_mut() = Some(connection);
}
@ -396,4 +402,16 @@ impl Notifications {
})
.unwrap()
}
pub fn connect_notification_closed<F: Fn(NotificationId) + 'static>(
&self,
cb: F,
) -> SignalHandlerId {
self.connect_local("notification-closed", false, move |values| {
let id = values[1].get().unwrap();
cb(id);
None
})
.unwrap()
}
}