Skip to main content

muda/items/
check.rs

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