From 9fc5ad23edca93553137100d167de7b69e88f785 Mon Sep 17 00:00:00 2001 From: Richard Date: Mon, 5 Jul 2021 16:23:44 -0300 Subject: Initial menu implementation --- native/src/lib.rs | 2 ++ native/src/menu.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 native/src/menu.rs (limited to 'native') diff --git a/native/src/lib.rs b/native/src/lib.rs index cd214e36..56a933f0 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -37,6 +37,7 @@ pub mod clipboard; pub mod event; pub mod keyboard; pub mod layout; +pub mod menu; pub mod mouse; pub mod overlay; pub mod program; @@ -75,6 +76,7 @@ pub use element::Element; pub use event::Event; pub use hasher::Hasher; pub use layout::Layout; +pub use menu::{Menu, MenuEntry}; pub use overlay::Overlay; pub use program::Program; pub use renderer::Renderer; diff --git a/native/src/menu.rs b/native/src/menu.rs new file mode 100644 index 00000000..6c73cb32 --- /dev/null +++ b/native/src/menu.rs @@ -0,0 +1,81 @@ +//! Build menus for your application. +use crate::keyboard::Hotkey; + +/// Menu representation. +/// +/// This can be used by `shell` implementations to create a menu. +#[derive(Debug, Clone, PartialEq)] +pub struct Menu { + items: Vec>, +} + +impl Menu { + /// Creates an empty [`Menu`]. + pub fn new() -> Self { + Menu { items: Vec::new() } + } + + /// Adds an item to the [`Menu`]. + pub fn item>( + mut self, + content: S, + hotkey: impl Into>, + on_activation: Message, + ) -> Self { + let content = content.into(); + let hotkey = hotkey.into(); + + self.items.push(MenuEntry::Item { + on_activation, + content, + hotkey, + }); + self + } + + /// Adds a separator to the [`Menu`]. + pub fn separator(mut self) -> Self { + self.items.push(MenuEntry::Separator); + self + } + + /// Adds a dropdown to the [`Menu`]. + pub fn dropdown>( + mut self, + content: S, + submenu: Menu, + ) -> Self { + let content = content.into(); + + self.items.push(MenuEntry::Dropdown { content, submenu }); + self + } + + /// Returns a [`MenuEntry`] iterator. + pub fn iter(self) -> std::vec::IntoIter> { + self.items.into_iter() + } +} + +/// Represents one of the possible entries used to build a [`Menu`]. +#[derive(Debug, Clone, PartialEq)] +pub enum MenuEntry { + /// Item for a [`Menu`] + Item { + /// The title of the item + content: String, + /// The [`Hotkey`] to activate the item, if any + hotkey: Option, + /// The message generated when the item is activated + on_activation: Message, + }, + /// Dropdown for a [`Menu`] + Dropdown { + /// Title of the dropdown + content: String, + /// The submenu of the dropdown + submenu: Menu, + }, + /// Separator for a [`Menu`] + Separator, +} -- cgit