use gtk::{gdk, glib, prelude::*, subclass::prelude::*};
use tracing::warn;
use super::AvatarImage;
use crate::{
application::Application,
utils::notifications::{paintable_as_notification_icon, string_as_notification_icon},
};
mod imp {
use std::cell::RefCell;
use super::*;
#[derive(Debug, Default, glib::Properties)]
#[properties(wrapper_type = super::AvatarData)]
pub struct AvatarData {
#[property(get, set = Self::set_image, explicit_notify, nullable)]
pub image: RefCell<Option<AvatarImage>>,
#[property(get, set = Self::set_display_name, explicit_notify)]
pub display_name: RefCell<String>,
}
#[glib::object_subclass]
impl ObjectSubclass for AvatarData {
const NAME: &'static str = "AvatarData";
type Type = super::AvatarData;
}
#[glib::derived_properties]
impl ObjectImpl for AvatarData {}
impl AvatarData {
fn set_image(&self, image: Option<AvatarImage>) {
if *self.image.borrow() == image {
return;
}
self.image.replace(image);
self.obj().notify_image();
}
fn set_display_name(&self, display_name: String) {
if *self.display_name.borrow() == display_name {
return;
}
self.display_name.replace(display_name);
self.obj().notify_display_name();
}
}
}
glib::wrapper! {
pub struct AvatarData(ObjectSubclass<imp::AvatarData>);
}
impl AvatarData {
pub fn new() -> Self {
glib::Object::new()
}
pub fn with_image(image: AvatarImage) -> Self {
glib::Object::builder().property("image", image).build()
}
pub fn as_notification_icon(&self) -> Option<gdk::Texture> {
let window = Application::default().active_window()?.upcast();
let icon = if let Some(paintable) = self.image().and_then(|i| i.paintable()) {
paintable_as_notification_icon(paintable.upcast_ref(), &window)
} else {
string_as_notification_icon(&self.display_name(), &window)
};
match icon {
Ok(icon) => Some(icon),
Err(error) => {
warn!("Could not generate icon for notification: {error}");
None
}
}
}
}
impl Default for AvatarData {
fn default() -> Self {
Self::new()
}
}