fractal/session/model/sidebar_data/
icon_item.rs

1use std::fmt;
2
3use gettextrs::gettext;
4use gtk::{glib, prelude::*, subclass::prelude::*};
5
6use crate::session::model::RoomCategory;
7
8#[derive(Debug, Default, Hash, Eq, PartialEq, Clone, Copy, glib::Enum)]
9#[enum_type(name = "SidebarIconItemType")]
10pub enum SidebarIconItemType {
11    /// The explore view.
12    #[default]
13    Explore,
14    /// An action to forget a room.
15    Forget,
16}
17
18impl SidebarIconItemType {
19    /// The name of the icon for this item type.
20    pub(crate) fn icon_name(self) -> &'static str {
21        match self {
22            Self::Explore => "explore-symbolic",
23            Self::Forget => "user-trash-symbolic",
24        }
25    }
26}
27
28impl fmt::Display for SidebarIconItemType {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        let label = match self {
31            Self::Explore => gettext("Explore"),
32            Self::Forget => gettext("Forget Room"),
33        };
34
35        f.write_str(&label)
36    }
37}
38
39mod imp {
40    use std::{cell::Cell, marker::PhantomData};
41
42    use super::*;
43
44    #[derive(Debug, Default, glib::Properties)]
45    #[properties(wrapper_type = super::SidebarIconItem)]
46    pub struct SidebarIconItem {
47        /// The type of this item.
48        #[property(get, construct_only, builder(SidebarIconItemType::default()))]
49        item_type: Cell<SidebarIconItemType>,
50        /// The display name of this item.
51        #[property(get = Self::display_name)]
52        display_name: PhantomData<String>,
53        /// The icon name used for this item.
54        #[property(get = Self::icon_name)]
55        icon_name: PhantomData<String>,
56    }
57
58    #[glib::object_subclass]
59    impl ObjectSubclass for SidebarIconItem {
60        const NAME: &'static str = "SidebarIconItem";
61        type Type = super::SidebarIconItem;
62    }
63
64    #[glib::derived_properties]
65    impl ObjectImpl for SidebarIconItem {}
66
67    impl SidebarIconItem {
68        /// The display name of this item.
69        fn display_name(&self) -> String {
70            self.item_type.get().to_string()
71        }
72
73        /// The icon name used for this item.
74        fn icon_name(&self) -> String {
75            self.item_type.get().icon_name().to_owned()
76        }
77    }
78}
79
80glib::wrapper! {
81    /// A top-level row in the sidebar with an icon.
82    pub struct SidebarIconItem(ObjectSubclass<imp::SidebarIconItem>);
83}
84
85impl SidebarIconItem {
86    pub fn new(item_type: SidebarIconItemType) -> Self {
87        glib::Object::builder()
88            .property("item-type", item_type)
89            .build()
90    }
91
92    /// Whether this item should be shown for the drag-n-drop of a room with the
93    /// given category.
94    pub(crate) fn visible_for_room_category(&self, source_category: Option<RoomCategory>) -> bool {
95        match self.item_type() {
96            SidebarIconItemType::Explore => true,
97            SidebarIconItemType::Forget => source_category == Some(RoomCategory::Left),
98        }
99    }
100}