fractal/session/view/content/room_details/members_page/members_list_view/
item_row.rs1use adw::{prelude::*, subclass::prelude::*};
2use gtk::glib;
3
4use super::MembershipSubpageRow;
5use crate::{
6 prelude::*,
7 session::{
8 model::Member,
9 view::content::room_details::{MemberRow, MembershipSubpageItem},
10 },
11};
12
13mod imp {
14 use std::cell::{Cell, RefCell};
15
16 use super::*;
17
18 #[derive(Debug, Default, glib::Properties)]
19 #[properties(wrapper_type = super::ItemRow)]
20 pub struct ItemRow {
21 #[property(get, set = Self::set_item, explicit_notify, nullable)]
25 item: RefCell<Option<glib::Object>>,
26 #[property(get)]
28 activatable: Cell<bool>,
29 }
30
31 #[glib::object_subclass]
32 impl ObjectSubclass for ItemRow {
33 const NAME: &'static str = "ContentMemberItemRow";
34 type Type = super::ItemRow;
35 type ParentType = adw::Bin;
36 }
37
38 #[glib::derived_properties]
39 impl ObjectImpl for ItemRow {}
40
41 impl WidgetImpl for ItemRow {}
42 impl BinImpl for ItemRow {}
43
44 impl ItemRow {
45 fn set_item(&self, item: Option<glib::Object>) {
49 if *self.item.borrow() == item {
50 return;
51 }
52 let obj = self.obj();
53
54 if let Some(item) = &item {
55 if let Some(member) = item.downcast_ref::<Member>() {
56 let child = obj.child_or_else::<MemberRow>(|| MemberRow::new(true));
57 child.set_member(Some(member.clone()));
58 self.set_activatable(true);
59 } else if let Some(item) = item.downcast_ref::<MembershipSubpageItem>() {
60 let child = obj.child_or_else::<MembershipSubpageRow>(|| {
61 let child = MembershipSubpageRow::new();
62 child.set_activatable(false);
63 child
64 });
65
66 child.set_item(Some(item.clone()));
67 self.set_activatable(true);
68 } else if let Some(child) = item.downcast_ref::<gtk::Widget>() {
69 obj.set_child(Some(child));
70 self.set_activatable(false);
71 } else {
72 unimplemented!("The object {item:?} doesn't have a widget implementation");
73 }
74 }
75
76 self.item.replace(item);
77 obj.notify_item();
78 }
79
80 fn set_activatable(&self, activatable: bool) {
82 if self.activatable.get() == activatable {
83 return;
84 }
85
86 self.activatable.set(activatable);
87 self.obj().notify_activatable();
88 }
89 }
90}
91
92glib::wrapper! {
93 pub struct ItemRow(ObjectSubclass<imp::ItemRow>)
95 @extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
96}
97
98impl ItemRow {
99 pub fn new() -> Self {
100 glib::Object::new()
101 }
102}
103
104impl IsABin for ItemRow {}