Skip to main content

fractal/components/pill/
source_row.rs

1use gtk::{glib, prelude::*, subclass::prelude::*};
2
3use super::{AtRoom, Avatar, AvatarImageSafetySetting, PillSource};
4use crate::session::Room;
5
6mod imp {
7    use std::cell::RefCell;
8
9    use glib::subclass::InitializingObject;
10
11    use super::*;
12
13    #[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)]
14    #[template(resource = "/org/gnome/Fractal/ui/components/pill/source_row.ui")]
15    #[properties(wrapper_type = super::PillSourceRow)]
16    pub struct PillSourceRow {
17        #[template_child]
18        avatar: TemplateChild<Avatar>,
19        #[template_child]
20        display_name: TemplateChild<gtk::Label>,
21        #[template_child]
22        id: TemplateChild<gtk::Label>,
23        /// The source of the data displayed by this row.
24        #[property(get, set = Self::set_source, explicit_notify, nullable)]
25        source: RefCell<Option<PillSource>>,
26    }
27
28    #[glib::object_subclass]
29    impl ObjectSubclass for PillSourceRow {
30        const NAME: &'static str = "PillSourceRow";
31        type Type = super::PillSourceRow;
32        type ParentType = gtk::ListBoxRow;
33
34        fn class_init(klass: &mut Self::Class) {
35            Self::bind_template(klass);
36        }
37
38        fn instance_init(obj: &InitializingObject<Self>) {
39            obj.init_template();
40        }
41    }
42
43    #[glib::derived_properties]
44    impl ObjectImpl for PillSourceRow {}
45
46    impl WidgetImpl for PillSourceRow {}
47    impl ListBoxRowImpl for PillSourceRow {}
48
49    impl PillSourceRow {
50        /// Set the source of the data displayed by this row.
51        fn set_source(&self, source: Option<PillSource>) {
52            if *self.source.borrow() == source {
53                return;
54            }
55
56            let (watched_safety_setting, watched_room) = if let Some(room) = source
57                .and_downcast_ref::<Room>()
58                .cloned()
59                .or_else(|| source.and_downcast_ref::<AtRoom>().map(AtRoom::room))
60            {
61                // We must always watch the invite avatars setting for local rooms.
62                (AvatarImageSafetySetting::InviteAvatars, Some(room))
63            } else {
64                (AvatarImageSafetySetting::None, None)
65            };
66            self.avatar
67                .set_watched_safety_setting(watched_safety_setting);
68            self.avatar.set_watched_room(watched_room);
69
70            self.source.replace(source);
71            self.obj().notify_source();
72        }
73    }
74}
75
76glib::wrapper! {
77    /// A list row to display a [`PillSource`].
78    pub struct PillSourceRow(ObjectSubclass<imp::PillSourceRow>)
79        @extends gtk::Widget, gtk::ListBoxRow,
80        @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable;
81}
82
83impl PillSourceRow {
84    pub fn new() -> Self {
85        glib::Object::new()
86    }
87}
88
89impl Default for PillSourceRow {
90    fn default() -> Self {
91        Self::new()
92    }
93}