fractal/session/model/sidebar_data/
icon_item.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::fmt;

use gettextrs::gettext;
use gtk::{glib, prelude::*, subclass::prelude::*};

use crate::session::model::RoomCategory;

#[derive(Debug, Default, Hash, Eq, PartialEq, Clone, Copy, glib::Enum)]
#[repr(u32)]
#[enum_type(name = "SidebarIconItemType")]
pub enum SidebarIconItemType {
    /// The explore view.
    #[default]
    Explore = 0,
    /// An action to forget a room.
    Forget = 1,
}

impl SidebarIconItemType {
    /// The name of the icon for this item type.
    pub fn icon_name(self) -> &'static str {
        match self {
            Self::Explore => "explore-symbolic",
            Self::Forget => "user-trash-symbolic",
        }
    }
}

impl fmt::Display for SidebarIconItemType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let label = match self {
            Self::Explore => gettext("Explore"),
            Self::Forget => gettext("Forget Room"),
        };

        f.write_str(&label)
    }
}

mod imp {
    use std::{cell::Cell, marker::PhantomData};

    use super::*;

    #[derive(Debug, Default, glib::Properties)]
    #[properties(wrapper_type = super::SidebarIconItem)]
    pub struct SidebarIconItem {
        /// The type of this item.
        #[property(get, construct_only, builder(SidebarIconItemType::default()))]
        pub item_type: Cell<SidebarIconItemType>,
        /// The display name of this item.
        #[property(get = Self::display_name)]
        pub display_name: PhantomData<String>,
        /// The icon name used for this item.
        #[property(get = Self::icon_name)]
        pub icon_name: PhantomData<String>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for SidebarIconItem {
        const NAME: &'static str = "SidebarIconItem";
        type Type = super::SidebarIconItem;
    }

    #[glib::derived_properties]
    impl ObjectImpl for SidebarIconItem {}

    impl SidebarIconItem {
        /// The display name of this item.
        fn display_name(&self) -> String {
            self.item_type.get().to_string()
        }

        /// The icon name used for this item.
        fn icon_name(&self) -> String {
            self.item_type.get().icon_name().to_owned()
        }
    }
}

glib::wrapper! {
    /// A top-level row in the sidebar with an icon.
    pub struct SidebarIconItem(ObjectSubclass<imp::SidebarIconItem>);
}

impl SidebarIconItem {
    pub fn new(item_type: SidebarIconItemType) -> Self {
        glib::Object::builder()
            .property("item-type", item_type)
            .build()
    }

    /// Whether this item should be shown for the drag-n-drop of a room with the
    /// given category.
    pub fn visible_for_room_category(&self, source_category: Option<RoomCategory>) -> bool {
        match self.item_type() {
            SidebarIconItemType::Explore => true,
            SidebarIconItemType::Forget => source_category == Some(RoomCategory::Left),
        }
    }
}