muda_win/items/
check.rs

1use std::{cell::RefCell, mem, rc::Rc};
2
3use crate::{accelerator::Accelerator, sealed::IsMenuItemBase, IsMenuItem, MenuId, MenuItemKind};
4
5/// A check menu item inside a [`Menu`] or [`Submenu`]
6/// and usually contains a text and a check mark or a similar toggle
7/// that corresponds to a checked and unchecked states.
8///
9/// [`Menu`]: crate::Menu
10/// [`Submenu`]: crate::Submenu
11#[derive(Clone)]
12pub struct CheckMenuItem {
13    pub(crate) id: Rc<MenuId>,
14    pub(crate) inner: Rc<RefCell<crate::platform_impl::MenuChild>>,
15}
16
17impl IsMenuItemBase for CheckMenuItem {}
18impl IsMenuItem for CheckMenuItem {
19    fn kind(&self) -> MenuItemKind {
20        MenuItemKind::Check(self.clone())
21    }
22
23    fn id(&self) -> &MenuId {
24        self.id()
25    }
26
27    fn into_id(self) -> MenuId {
28        self.into_id()
29    }
30}
31
32impl CheckMenuItem {
33    /// Create a new check menu item.
34    ///
35    /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic
36    ///   for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
37    pub fn new<S: AsRef<str>>(
38        text: S,
39        enabled: bool,
40        checked: bool,
41        accelerator: Option<Accelerator>,
42    ) -> Self {
43        let item = crate::platform_impl::MenuChild::new_check(
44            text.as_ref(),
45            enabled,
46            checked,
47            accelerator,
48            None,
49        );
50        Self {
51            id: Rc::new(item.id().clone()),
52            inner: Rc::new(RefCell::new(item)),
53        }
54    }
55
56    /// Create a new check menu item with the specified id.
57    ///
58    /// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic
59    ///   for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
60    pub fn with_id<I: Into<MenuId>, S: AsRef<str>>(
61        id: I,
62        text: S,
63        enabled: bool,
64        checked: bool,
65        accelerator: Option<Accelerator>,
66    ) -> Self {
67        let id = id.into();
68        Self {
69            id: Rc::new(id.clone()),
70            inner: Rc::new(RefCell::new(crate::platform_impl::MenuChild::new_check(
71                text.as_ref(),
72                enabled,
73                checked,
74                accelerator,
75                Some(id),
76            ))),
77        }
78    }
79
80    /// Returns a unique identifier associated with this submenu.
81    pub fn id(&self) -> &MenuId {
82        &self.id
83    }
84
85    /// Get the text for this check menu item.
86    pub fn text(&self) -> String {
87        self.inner.borrow().text()
88    }
89
90    /// Set the text for this check menu item. `text` could optionally contain
91    /// an `&` before a character to assign this character as the mnemonic
92    /// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
93    pub fn set_text<S: AsRef<str>>(&self, text: S) {
94        self.inner.borrow_mut().set_text(text.as_ref())
95    }
96
97    /// Get whether this check menu item is enabled or not.
98    pub fn is_enabled(&self) -> bool {
99        self.inner.borrow().is_enabled()
100    }
101
102    /// Enable or disable this check menu item.
103    pub fn set_enabled(&self, enabled: bool) {
104        self.inner.borrow_mut().set_enabled(enabled)
105    }
106
107    /// Set this check menu item accelerator.
108    pub fn set_accelerator(&self, accelerator: Option<Accelerator>) -> crate::Result<()> {
109        self.inner.borrow_mut().set_accelerator(accelerator)
110    }
111
112    /// Get whether this check menu item is checked or not.
113    pub fn is_checked(&self) -> bool {
114        self.inner.borrow().is_checked()
115    }
116
117    /// Check or Uncheck this check menu item.
118    pub fn set_checked(&self, checked: bool) {
119        self.inner.borrow_mut().set_checked(checked)
120    }
121
122    /// Convert this menu item into its menu ID.
123    pub fn into_id(mut self) -> MenuId {
124        // Note: `Rc::into_inner` is available from Rust 1.70
125        if let Some(id) = Rc::get_mut(&mut self.id) {
126            mem::take(id)
127        } else {
128            self.id().clone()
129        }
130    }
131}