fractal/account_switcher/
avatar_with_selection.rs1use adw::{prelude::*, subclass::prelude::*};
2use gtk::{glib, CompositeTemplate};
3
4use crate::components::{Avatar, AvatarData};
5
6mod imp {
7 use std::marker::PhantomData;
8
9 use glib::subclass::InitializingObject;
10
11 use super::*;
12
13 #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
14 #[template(resource = "/org/gnome/Fractal/ui/account_switcher/avatar_with_selection.ui")]
15 #[properties(wrapper_type = super::AvatarWithSelection)]
16 pub struct AvatarWithSelection {
17 #[template_child]
18 child_avatar: TemplateChild<Avatar>,
19 #[template_child]
20 checkmark: TemplateChild<gtk::Image>,
21 #[property(get = Self::data, set = Self::set_data, explicit_notify, nullable)]
23 data: PhantomData<Option<AvatarData>>,
24 #[property(get = Self::size, set = Self::set_size, minimum = -1, default = -1)]
26 size: PhantomData<i32>,
27 #[property(get = Self::is_selected, set = Self::set_selected, explicit_notify)]
29 selected: PhantomData<bool>,
30 }
31
32 #[glib::object_subclass]
33 impl ObjectSubclass for AvatarWithSelection {
34 const NAME: &'static str = "AvatarWithSelection";
35 type Type = super::AvatarWithSelection;
36 type ParentType = adw::Bin;
37
38 fn class_init(klass: &mut Self::Class) {
39 Self::bind_template(klass);
40 }
41
42 fn instance_init(obj: &InitializingObject<Self>) {
43 obj.init_template();
44 }
45 }
46
47 #[glib::derived_properties]
48 impl ObjectImpl for AvatarWithSelection {}
49
50 impl WidgetImpl for AvatarWithSelection {}
51 impl BinImpl for AvatarWithSelection {}
52
53 impl AccessibleImpl for AvatarWithSelection {
54 fn first_accessible_child(&self) -> Option<gtk::Accessible> {
55 None
57 }
58 }
59
60 impl AvatarWithSelection {
61 fn is_selected(&self) -> bool {
63 self.checkmark.get_visible()
64 }
65
66 fn set_selected(&self, selected: bool) {
68 if self.is_selected() == selected {
69 return;
70 }
71
72 self.checkmark.set_visible(selected);
73
74 if selected {
75 self.child_avatar.add_css_class("selected-avatar");
76 } else {
77 self.child_avatar.remove_css_class("selected-avatar");
78 }
79
80 self.obj().notify_selected();
81 }
82
83 fn data(&self) -> Option<AvatarData> {
85 self.child_avatar.data()
86 }
87
88 fn set_data(&self, data: Option<AvatarData>) {
90 self.child_avatar.set_data(data);
91 }
92
93 fn size(&self) -> i32 {
95 self.child_avatar.size()
96 }
97
98 fn set_size(&self, size: i32) {
100 self.child_avatar.set_size(size);
101 }
102 }
103}
104
105glib::wrapper! {
106 pub struct AvatarWithSelection(ObjectSubclass<imp::AvatarWithSelection>)
108 @extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
109}
110
111impl AvatarWithSelection {
112 pub fn new() -> Self {
113 glib::Object::new()
114 }
115}