mirror of
https://github.com/italicsjenga/muda.git
synced 2025-01-11 04:11:32 +11:00
feat: add builders (#73)
This commit is contained in:
parent
dded1938d9
commit
ee30bf8d29
5
.changes/about-metadata-builder.md
Normal file
5
.changes/about-metadata-builder.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"muda": "patch"
|
||||||
|
---
|
||||||
|
|
||||||
|
Add `AboutMetadataBuilder`.
|
5
.changes/builders.md
Normal file
5
.changes/builders.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"muda": "patch"
|
||||||
|
---
|
||||||
|
|
||||||
|
Add `builders` module with `MenuItemBuilder`, `SubmenuBuilder`, `CheckMenuItemBuilder` and `IconMenuItemBuilder`.
|
5
.changes/try-from.md
Normal file
5
.changes/try-from.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"muda": "patch"
|
||||||
|
---
|
||||||
|
|
||||||
|
Impl `TryFrom<&str>` and `TryFrom<String>` for `Accelerator`.
|
176
src/about_metadata.rs
Normal file
176
src/about_metadata.rs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
use crate::icon::Icon;
|
||||||
|
|
||||||
|
/// Application metadata for the [`PredefinedMenuItem::about`].
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct AboutMetadata {
|
||||||
|
/// Sets the application name.
|
||||||
|
pub name: Option<String>,
|
||||||
|
/// The application version.
|
||||||
|
pub version: Option<String>,
|
||||||
|
/// The short version, e.g. "1.0".
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows / Linux:** Appended to the end of `version` in parentheses.
|
||||||
|
pub short_version: Option<String>,
|
||||||
|
/// The authors of the application.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub authors: Option<Vec<String>>,
|
||||||
|
/// Application comments.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub comments: Option<String>,
|
||||||
|
/// The copyright of the application.
|
||||||
|
pub copyright: Option<String>,
|
||||||
|
/// The license of the application.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub license: Option<String>,
|
||||||
|
/// The application website.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub website: Option<String>,
|
||||||
|
/// The website label.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub website_label: Option<String>,
|
||||||
|
/// The credits.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows / Linux:** Unsupported.
|
||||||
|
pub credits: Option<String>,
|
||||||
|
/// The application icon.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows:** Unsupported.
|
||||||
|
pub icon: Option<Icon>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AboutMetadata {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) fn full_version(&self) -> Option<String> {
|
||||||
|
Some(format!(
|
||||||
|
"{}{}",
|
||||||
|
(self.version.as_ref())?,
|
||||||
|
(self.short_version.as_ref())
|
||||||
|
.map(|v| format!(" ({v})"))
|
||||||
|
.unwrap_or_default()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A builder type for [`AboutMetadata`].
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct AboutMetadataBuilder(AboutMetadata);
|
||||||
|
|
||||||
|
impl AboutMetadataBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the application name.
|
||||||
|
pub fn name<S: Into<String>>(mut self, name: Option<S>) -> Self {
|
||||||
|
self.0.name = name.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the application version.
|
||||||
|
pub fn version<S: Into<String>>(mut self, version: Option<S>) -> Self {
|
||||||
|
self.0.version = version.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the short version, e.g. "1.0".
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows / Linux:** Appended to the end of `version` in parentheses.
|
||||||
|
pub fn short_version<S: Into<String>>(mut self, short_version: Option<S>) -> Self {
|
||||||
|
self.0.short_version = short_version.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the authors of the application.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub fn authors(mut self, authors: Option<Vec<String>>) -> Self {
|
||||||
|
self.0.authors = authors;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Application comments.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub fn comments<S: Into<String>>(mut self, comments: Option<S>) -> Self {
|
||||||
|
self.0.comments = comments.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the copyright of the application.
|
||||||
|
pub fn copyright<S: Into<String>>(mut self, copyright: Option<S>) -> Self {
|
||||||
|
self.0.copyright = copyright.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the license of the application.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub fn license<S: Into<String>>(mut self, license: Option<S>) -> Self {
|
||||||
|
self.0.license = license.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the application website.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub fn website<S: Into<String>>(mut self, website: Option<S>) -> Self {
|
||||||
|
self.0.website = website.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the website label.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** Unsupported.
|
||||||
|
pub fn website_label<S: Into<String>>(mut self, website_label: Option<S>) -> Self {
|
||||||
|
self.0.website_label = website_label.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the credits.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows / Linux:** Unsupported.
|
||||||
|
pub fn credits<S: Into<String>>(mut self, credits: Option<S>) -> Self {
|
||||||
|
self.0.credits = credits.map(|s| s.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Sets the application icon.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows:** Unsupported.
|
||||||
|
pub fn icon(mut self, icon: Option<Icon>) -> Self {
|
||||||
|
self.0.icon = icon;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct the final [`AboutMetadata`]
|
||||||
|
pub fn build(self) -> AboutMetadata {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,22 @@ impl FromStr for Accelerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for Accelerator {
|
||||||
|
type Error = crate::Error;
|
||||||
|
|
||||||
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
|
parse_accelerator(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for Accelerator {
|
||||||
|
type Error = crate::Error;
|
||||||
|
|
||||||
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
|
parse_accelerator(&value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_accelerator(accelerator: &str) -> crate::Result<Accelerator> {
|
fn parse_accelerator(accelerator: &str) -> crate::Result<Accelerator> {
|
||||||
let tokens = accelerator.split('+').collect::<Vec<&str>>();
|
let tokens = accelerator.split('+').collect::<Vec<&str>>();
|
||||||
|
|
||||||
|
|
57
src/builders/check.rs
Normal file
57
src/builders/check.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use crate::{accelerator::Accelerator, CheckMenuItem};
|
||||||
|
|
||||||
|
/// A builder type for [`CheckMenuItem`]
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct CheckMenuItemBuilder {
|
||||||
|
text: String,
|
||||||
|
enabled: bool,
|
||||||
|
checked: bool,
|
||||||
|
acccelerator: Option<Accelerator>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CheckMenuItemBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the text for this check menu item.
|
||||||
|
///
|
||||||
|
/// See [`CheckMenuItem::set_text`] for more info.
|
||||||
|
pub fn text<S: Into<String>>(mut self, text: S) -> Self {
|
||||||
|
self.text = text.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable or disable this menu item.
|
||||||
|
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||||
|
self.enabled = enabled;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check or uncheck this menu item.
|
||||||
|
pub fn checked(mut self, checked: bool) -> Self {
|
||||||
|
self.checked = checked;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this check menu item accelerator.
|
||||||
|
pub fn acccelerator<A: TryInto<Accelerator>>(
|
||||||
|
mut self,
|
||||||
|
acccelerator: Option<A>,
|
||||||
|
) -> crate::Result<Self>
|
||||||
|
where
|
||||||
|
crate::Error: From<<A as TryInto<Accelerator>>::Error>,
|
||||||
|
{
|
||||||
|
self.acccelerator = acccelerator.map(|a| a.try_into()).transpose()?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build this check menu item.
|
||||||
|
pub fn build(self) -> CheckMenuItem {
|
||||||
|
CheckMenuItem::new(self.text, self.enabled, self.checked, self.acccelerator)
|
||||||
|
}
|
||||||
|
}
|
79
src/builders/icon.rs
Normal file
79
src/builders/icon.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
accelerator::Accelerator,
|
||||||
|
icon::{Icon, NativeIcon},
|
||||||
|
IconMenuItem,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A builder type for [`IconMenuItem`]
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct IconMenuItemBuilder {
|
||||||
|
text: String,
|
||||||
|
enabled: bool,
|
||||||
|
acccelerator: Option<Accelerator>,
|
||||||
|
icon: Option<Icon>,
|
||||||
|
native_icon: Option<NativeIcon>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IconMenuItemBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the text for this icon menu item.
|
||||||
|
///
|
||||||
|
/// See [`IconMenuItem::set_text`] for more info.
|
||||||
|
pub fn text<S: Into<String>>(mut self, text: S) -> Self {
|
||||||
|
self.text = text.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable or disable this menu item.
|
||||||
|
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||||
|
self.enabled = enabled;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this icon menu item icon.
|
||||||
|
pub fn icon(mut self, icon: Option<Icon>) -> Self {
|
||||||
|
self.icon = icon;
|
||||||
|
self.native_icon = None;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this icon menu item native icon.
|
||||||
|
pub fn native_icon(mut self, icon: Option<NativeIcon>) -> Self {
|
||||||
|
self.native_icon = icon;
|
||||||
|
self.icon = None;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this icon menu item accelerator.
|
||||||
|
pub fn acccelerator<A: TryInto<Accelerator>>(
|
||||||
|
mut self,
|
||||||
|
acccelerator: Option<A>,
|
||||||
|
) -> crate::Result<Self>
|
||||||
|
where
|
||||||
|
crate::Error: From<<A as TryInto<Accelerator>>::Error>,
|
||||||
|
{
|
||||||
|
self.acccelerator = acccelerator.map(|a| a.try_into()).transpose()?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build this icon menu item.
|
||||||
|
pub fn build(self) -> IconMenuItem {
|
||||||
|
if self.icon.is_some() {
|
||||||
|
IconMenuItem::new(self.text, self.enabled, self.icon, self.acccelerator)
|
||||||
|
} else {
|
||||||
|
IconMenuItem::with_native_icon(
|
||||||
|
self.text,
|
||||||
|
self.enabled,
|
||||||
|
self.native_icon,
|
||||||
|
self.acccelerator,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/builders/mod.rs
Normal file
16
src/builders/mod.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
//! A module containting builder types
|
||||||
|
|
||||||
|
mod check;
|
||||||
|
mod icon;
|
||||||
|
mod normal;
|
||||||
|
mod submenu;
|
||||||
|
|
||||||
|
pub use crate::about_metadata::AboutMetadataBuilder;
|
||||||
|
pub use check::*;
|
||||||
|
pub use icon::*;
|
||||||
|
pub use normal::*;
|
||||||
|
pub use submenu::*;
|
50
src/builders/normal.rs
Normal file
50
src/builders/normal.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use crate::{accelerator::Accelerator, MenuItem};
|
||||||
|
|
||||||
|
/// A builder type for [`MenuItem`]
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct MenuItemBuilder {
|
||||||
|
text: String,
|
||||||
|
enabled: bool,
|
||||||
|
acccelerator: Option<Accelerator>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MenuItemBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the text for this menu item.
|
||||||
|
///
|
||||||
|
/// See [`MenuItem::set_text`] for more info.
|
||||||
|
pub fn text<S: Into<String>>(mut self, text: S) -> Self {
|
||||||
|
self.text = text.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable or disable this menu item.
|
||||||
|
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||||
|
self.enabled = enabled;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this menu item accelerator.
|
||||||
|
pub fn acccelerator<A: TryInto<Accelerator>>(
|
||||||
|
mut self,
|
||||||
|
acccelerator: Option<A>,
|
||||||
|
) -> crate::Result<Self>
|
||||||
|
where
|
||||||
|
crate::Error: From<<A as TryInto<Accelerator>>::Error>,
|
||||||
|
{
|
||||||
|
self.acccelerator = acccelerator.map(|a| a.try_into()).transpose()?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build this menu item.
|
||||||
|
pub fn build(self) -> MenuItem {
|
||||||
|
MenuItem::new(self.text, self.enabled, self.acccelerator)
|
||||||
|
}
|
||||||
|
}
|
59
src/builders/submenu.rs
Normal file
59
src/builders/submenu.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use crate::{IsMenuItem, Submenu};
|
||||||
|
|
||||||
|
/// A builder type for [`Submenu`]
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct SubmenuBuilder<'a> {
|
||||||
|
text: String,
|
||||||
|
enabled: bool,
|
||||||
|
items: Vec<&'a dyn IsMenuItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for SubmenuBuilder<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("SubmenuBuilder")
|
||||||
|
.field("text", &self.text)
|
||||||
|
.field("enabled", &self.enabled)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SubmenuBuilder<'a> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the text for this menu item.
|
||||||
|
///
|
||||||
|
/// See [`Submenu::set_text`] for more info.
|
||||||
|
pub fn text<S: Into<String>>(mut self, text: S) -> Self {
|
||||||
|
self.text = text.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable or disable this menu item.
|
||||||
|
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||||
|
self.enabled = enabled;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an item to this submenu.
|
||||||
|
pub fn item(mut self, item: &'a dyn IsMenuItem) -> Self {
|
||||||
|
self.items.push(item);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add these items to this submenu.
|
||||||
|
pub fn items(mut self, items: &[&'a dyn IsMenuItem]) -> Self {
|
||||||
|
self.items.extend_from_slice(items);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build this menu item.
|
||||||
|
pub fn build(self) -> crate::Result<Submenu> {
|
||||||
|
Submenu::with_items(self.text, self.enabled, &self.items)
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,7 +60,7 @@ impl CheckMenuItem {
|
||||||
self.0.borrow().text()
|
self.0.borrow().text()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text for this check menu item. `text` could optionally contain
|
/// Set the text for this check menu item. `text` could optionally contain
|
||||||
/// an `&` before a character to assign this character as the mnemonic
|
/// an `&` before a character to assign this character as the mnemonic
|
||||||
/// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
|
/// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
|
||||||
pub fn set_text<S: AsRef<str>>(&self, text: S) {
|
pub fn set_text<S: AsRef<str>>(&self, text: S) {
|
||||||
|
|
|
@ -48,6 +48,29 @@ impl IconMenuItem {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new icon menu item but with a native icon.
|
||||||
|
///
|
||||||
|
/// See [`IconMenuItem::new`] for more info.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific:
|
||||||
|
///
|
||||||
|
/// - **Windows / Linux**: Unsupported.
|
||||||
|
pub fn with_native_icon<S: AsRef<str>>(
|
||||||
|
text: S,
|
||||||
|
enabled: bool,
|
||||||
|
native_icon: Option<NativeIcon>,
|
||||||
|
acccelerator: Option<Accelerator>,
|
||||||
|
) -> Self {
|
||||||
|
Self(Rc::new(RefCell::new(
|
||||||
|
crate::platform_impl::MenuChild::new_native_icon(
|
||||||
|
text.as_ref(),
|
||||||
|
enabled,
|
||||||
|
native_icon,
|
||||||
|
acccelerator,
|
||||||
|
),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a unique identifier associated with this submenu.
|
/// Returns a unique identifier associated with this submenu.
|
||||||
pub fn id(&self) -> u32 {
|
pub fn id(&self) -> u32 {
|
||||||
self.0.borrow().id()
|
self.0.borrow().id()
|
||||||
|
@ -58,7 +81,7 @@ impl IconMenuItem {
|
||||||
self.0.borrow().text()
|
self.0.borrow().text()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text for this check menu item. `text` could optionally contain
|
/// Set the text for this check menu item. `text` could optionally contain
|
||||||
/// an `&` before a character to assign this character as the mnemonic
|
/// an `&` before a character to assign this character as the mnemonic
|
||||||
/// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
|
/// for this check menu item. To display a `&` without assigning a mnemenonic, use `&&`.
|
||||||
pub fn set_text<S: AsRef<str>>(&self, text: S) {
|
pub fn set_text<S: AsRef<str>>(&self, text: S) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl MenuItem {
|
||||||
self.0.borrow().id()
|
self.0.borrow().id()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text for this menu item.
|
/// Set the text for this menu item.
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> String {
|
||||||
self.0.borrow().text()
|
self.0.borrow().text()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use crate::{accelerator::Accelerator, icon::Icon, IsMenuItem, MenuItemType};
|
use crate::{accelerator::Accelerator, AboutMetadata, IsMenuItem, MenuItemType};
|
||||||
use keyboard_types::{Code, Modifiers};
|
use keyboard_types::{Code, Modifiers};
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -182,78 +182,6 @@ impl PredefinedMenuItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Application metadata for the [`PredefinedMenuItem::about`].
|
|
||||||
#[derive(Debug, Clone, Default)]
|
|
||||||
pub struct AboutMetadata {
|
|
||||||
/// The application name.
|
|
||||||
pub name: Option<String>,
|
|
||||||
/// The application version.
|
|
||||||
pub version: Option<String>,
|
|
||||||
/// The short version, e.g. "1.0".
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **Windows / Linux:** Appended to the end of `version` in parentheses.
|
|
||||||
pub short_version: Option<String>,
|
|
||||||
/// The authors of the application.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** Unsupported.
|
|
||||||
pub authors: Option<Vec<String>>,
|
|
||||||
/// Application comments.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** Unsupported.
|
|
||||||
pub comments: Option<String>,
|
|
||||||
/// The copyright of the application.
|
|
||||||
pub copyright: Option<String>,
|
|
||||||
/// The license of the application.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** Unsupported.
|
|
||||||
pub license: Option<String>,
|
|
||||||
/// The application website.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** Unsupported.
|
|
||||||
pub website: Option<String>,
|
|
||||||
/// The website label.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** Unsupported.
|
|
||||||
pub website_label: Option<String>,
|
|
||||||
/// The credits.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **Windows / Linux:** Unsupported.
|
|
||||||
pub credits: Option<String>,
|
|
||||||
/// The application icon.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **Windows:** Unsupported.
|
|
||||||
pub icon: Option<Icon>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AboutMetadata {
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn full_version(&self) -> Option<String> {
|
|
||||||
Some(format!(
|
|
||||||
"{}{}",
|
|
||||||
(self.version.as_ref())?,
|
|
||||||
(self.short_version.as_ref())
|
|
||||||
.map(|v| format!(" ({v})"))
|
|
||||||
.unwrap_or_default()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_about_metadata() {
|
fn test_about_metadata() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -128,7 +128,9 @@
|
||||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||||
use once_cell::sync::{Lazy, OnceCell};
|
use once_cell::sync::{Lazy, OnceCell};
|
||||||
|
|
||||||
|
mod about_metadata;
|
||||||
pub mod accelerator;
|
pub mod accelerator;
|
||||||
|
pub mod builders;
|
||||||
mod error;
|
mod error;
|
||||||
mod items;
|
mod items;
|
||||||
mod menu;
|
mod menu;
|
||||||
|
@ -139,7 +141,8 @@ mod util;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate objc;
|
extern crate objc;
|
||||||
|
|
||||||
pub use self::error::*;
|
pub use about_metadata::AboutMetadata;
|
||||||
|
pub use error::*;
|
||||||
pub use items::*;
|
pub use items::*;
|
||||||
pub use menu::Menu;
|
pub use menu::Menu;
|
||||||
pub mod icon;
|
pub mod icon;
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub(crate) use icon::PlatformIcon;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
accelerator::Accelerator,
|
accelerator::Accelerator,
|
||||||
icon::Icon,
|
icon::{Icon, NativeIcon},
|
||||||
items::*,
|
items::*,
|
||||||
util::{AddOp, Counter},
|
util::{AddOp, Counter},
|
||||||
MenuEvent, MenuItemType,
|
MenuEvent, MenuItemType,
|
||||||
|
@ -480,6 +480,24 @@ impl MenuChild {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_native_icon(
|
||||||
|
text: &str,
|
||||||
|
enabled: bool,
|
||||||
|
_native_icon: Option<NativeIcon>,
|
||||||
|
accelerator: Option<Accelerator>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
text: text.to_string(),
|
||||||
|
enabled,
|
||||||
|
accelerator,
|
||||||
|
id: COUNTER.next(),
|
||||||
|
type_: MenuItemType::Icon,
|
||||||
|
gtk_menu_items: Rc::new(RefCell::new(HashMap::new())),
|
||||||
|
is_syncing_checked_state: Rc::new(AtomicBool::new(false)),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared methods
|
/// Shared methods
|
||||||
|
|
|
@ -311,6 +311,23 @@ impl MenuChild {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_native_icon(
|
||||||
|
text: &str,
|
||||||
|
enabled: bool,
|
||||||
|
native_icon: Option<NativeIcon>,
|
||||||
|
accelerator: Option<Accelerator>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
type_: MenuItemType::Icon,
|
||||||
|
text: text.to_string(),
|
||||||
|
enabled,
|
||||||
|
id: COUNTER.next(),
|
||||||
|
native_icon,
|
||||||
|
accelerator,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared methods
|
/// Shared methods
|
||||||
|
@ -695,7 +712,11 @@ impl MenuChild {
|
||||||
let () = msg_send![ns_menu_item, setEnabled: NO];
|
let () = msg_send![ns_menu_item, setEnabled: NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
menuitem_set_icon(ns_menu_item, self.icon.as_ref());
|
if self.icon.is_some() {
|
||||||
|
menuitem_set_icon(ns_menu_item, self.icon.as_ref());
|
||||||
|
} else if self.native_icon.is_some() {
|
||||||
|
menuitem_set_native_icon(ns_menu_item, self.native_icon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ns_menu_items
|
self.ns_menu_items
|
||||||
|
|
|
@ -10,11 +10,11 @@ pub(crate) use self::icon::WinIcon as PlatformIcon;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
accelerator::Accelerator,
|
accelerator::Accelerator,
|
||||||
icon::Icon,
|
icon::{Icon, NativeIcon},
|
||||||
items::{AboutMetadata, PredfinedMenuItemType},
|
items::PredfinedMenuItemType,
|
||||||
util::{AddOp, Counter},
|
util::{AddOp, Counter},
|
||||||
CheckMenuItem, IconMenuItem, IsMenuItem, MenuEvent, MenuItem, MenuItemType, PredefinedMenuItem,
|
AboutMetadata, CheckMenuItem, IconMenuItem, IsMenuItem, MenuEvent, MenuItem, MenuItemType,
|
||||||
Submenu,
|
PredefinedMenuItem, Submenu,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
cell::{RefCell, RefMut},
|
cell::{RefCell, RefMut},
|
||||||
|
@ -474,6 +474,24 @@ impl MenuChild {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_native_icon(
|
||||||
|
text: &str,
|
||||||
|
enabled: bool,
|
||||||
|
_native_icon: Option<NativeIcon>,
|
||||||
|
accelerator: Option<Accelerator>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
type_: MenuItemType::Icon,
|
||||||
|
text: text.to_string(),
|
||||||
|
enabled,
|
||||||
|
parents_hemnu: Vec::new(),
|
||||||
|
id: COUNTER.next(),
|
||||||
|
accelerator,
|
||||||
|
root_menu_haccel_stores: Some(Vec::new()),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared methods
|
/// Shared methods
|
||||||
|
|
Loading…
Reference in a new issue