diff options
author | 2021-07-19 20:59:09 +0700 | |
---|---|---|
committer | 2021-07-19 20:59:09 +0700 | |
commit | 3099f3610003f513a386125d3cb81bfbf0ffe887 (patch) | |
tree | c006a8a3f5191bbbaa470ab7772684dbef26ff6c /core | |
parent | 2e7eac7d2167b492149e064927e764eca67f98fe (diff) | |
download | iced-3099f3610003f513a386125d3cb81bfbf0ffe887.tar.gz iced-3099f3610003f513a386125d3cb81bfbf0ffe887.tar.bz2 iced-3099f3610003f513a386125d3cb81bfbf0ffe887.zip |
Implement `Menu::map` naively
Diffstat (limited to 'core')
-rw-r--r-- | core/src/menu.rs | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/core/src/menu.rs b/core/src/menu.rs index 52186140..e9d3d13a 100644 --- a/core/src/menu.rs +++ b/core/src/menu.rs @@ -26,15 +26,30 @@ impl<Message> Menu<Message> { Self { entries } } + /// Returns a [`MenuEntry`] iterator. + pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> { + self.entries.iter() + } + /// Adds an [`Entry`] to the [`Menu`]. pub fn push(mut self, entry: Entry<Message>) -> Self { self.entries.push(entry); self } - /// Returns a [`MenuEntry`] iterator. - pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> { - self.entries.iter() + /// Maps the `Message` of the [`Menu`] using the provided function. + /// + /// This is useful to compose menus and split them into different + /// abstraction levels. + pub fn map<B>(self, f: &impl Fn(Message) -> B) -> Menu<B> { + // TODO: Use a boxed trait to avoid reallocation of entries + Menu { + entries: self + .entries + .into_iter() + .map(|entry| entry.map(f)) + .collect(), + } } } @@ -71,7 +86,7 @@ impl<Message> Entry<Message> { let content = content.into(); let hotkey = hotkey.into(); - Entry::Item { + Self::Item { content, hotkey, on_activation, @@ -85,7 +100,26 @@ impl<Message> Entry<Message> { ) -> Self { let content = content.into(); - Entry::Dropdown { content, submenu } + Self::Dropdown { content, submenu } + } + + fn map<B>(self, f: &impl Fn(Message) -> B) -> Entry<B> { + match self { + Self::Item { + content, + hotkey, + on_activation, + } => Entry::Item { + content, + hotkey, + on_activation: f(on_activation), + }, + Self::Dropdown { content, submenu } => Entry::Dropdown { + content, + submenu: submenu.map(f), + }, + Self::Separator => Entry::Separator, + } } } |