fractal/session/view/content/room_details/members_page/members_list_view/
membership_subpage_row.rsuse gettextrs::npgettext;
use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
use crate::session::{
model::Membership, view::content::room_details::membership_subpage_item::MembershipSubpageItem,
};
mod imp {
use std::{cell::RefCell, marker::PhantomData};
use glib::subclass::InitializingObject;
use super::*;
#[derive(Debug, Default, CompositeTemplate, glib::Properties)]
#[template(
resource = "/org/gnome/Fractal/ui/session/view/content/room_details/members_page/members_list_view/membership_subpage_row.ui"
)]
#[properties(wrapper_type = super::MembershipSubpageRow)]
pub struct MembershipSubpageRow {
#[property(get, set = Self::set_item, explicit_notify, nullable)]
item: RefCell<Option<MembershipSubpageItem>>,
items_changed_handler: RefCell<Option<glib::SignalHandlerId>>,
#[property(get = Self::icon_name)]
icon_name: PhantomData<Option<String>>,
#[property(get = Self::label)]
label: PhantomData<Option<String>>,
#[template_child]
members_count: TemplateChild<gtk::Label>,
}
#[glib::object_subclass]
impl ObjectSubclass for MembershipSubpageRow {
const NAME: &'static str = "MembersPageMembershipSubpageRow";
type Type = super::MembershipSubpageRow;
type ParentType = gtk::ListBoxRow;
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
fn instance_init(obj: &InitializingObject<Self>) {
obj.init_template();
}
}
#[glib::derived_properties]
impl ObjectImpl for MembershipSubpageRow {
fn dispose(&self) {
if let Some(item) = &*self.item.borrow() {
if let Some(handler) = self.items_changed_handler.take() {
item.model().disconnect(handler);
}
}
}
}
impl WidgetImpl for MembershipSubpageRow {}
impl ListBoxRowImpl for MembershipSubpageRow {}
impl MembershipSubpageRow {
fn set_item(&self, item: Option<MembershipSubpageItem>) {
if *self.item.borrow() == item {
return;
}
let obj = self.obj();
if let Some(item) = &*self.item.borrow() {
if let Some(handler) = self.items_changed_handler.take() {
item.model().disconnect(handler);
}
}
if let Some(item) = &item {
let model = item.model();
let items_changed_handler = model.connect_items_changed(clone!(
#[weak(rename_to = imp)]
self,
move |model, _, _, _| {
imp.member_count_changed(model.n_items());
imp.obj().notify_label();
}
));
self.items_changed_handler
.replace(Some(items_changed_handler));
self.member_count_changed(model.n_items());
}
self.item.replace(item);
obj.notify_item();
obj.notify_icon_name();
obj.notify_label();
}
fn icon_name(&self) -> Option<String> {
Some(
self.item
.borrow()
.as_ref()?
.membership()
.icon_name()
.to_owned(),
)
}
fn label(&self) -> Option<String> {
let item = self.item.borrow().clone()?;
let count = item.model().n_items();
match item.membership() {
Membership::Invite => Some(npgettext("members", "Invited", "Invited", count)),
Membership::Ban => Some(npgettext("members", "Banned", "Banned", count)),
_ => None,
}
}
fn member_count_changed(&self, n: u32) {
self.members_count.set_text(&format!("{n}"));
}
}
}
glib::wrapper! {
pub struct MembershipSubpageRow(ObjectSubclass<imp::MembershipSubpageRow>)
@extends gtk::Widget, gtk::ListBoxRow, @implements gtk::Accessible;
}
impl MembershipSubpageRow {
pub fn new() -> Self {
glib::Object::new()
}
}