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