diff options
author | 2021-07-12 22:28:18 +0200 | |
---|---|---|
committer | 2021-07-12 22:28:18 +0200 | |
commit | 31997d255f263a0f47f5af0d8560f3d5bd37f077 (patch) | |
tree | 0413f22ec8052f0a1e310b12a4f5c4dedb883e81 | |
parent | b3ff522c182590ffcd03113b5147fa4599559059 (diff) | |
download | iced-31997d255f263a0f47f5af0d8560f3d5bd37f077.tar.gz iced-31997d255f263a0f47f5af0d8560f3d5bd37f077.tar.bz2 iced-31997d255f263a0f47f5af0d8560f3d5bd37f077.zip |
Store and synchronize `Menu` in `application::State`
-rw-r--r-- | core/src/menu.rs | 40 | ||||
-rw-r--r-- | glutin/src/application.rs | 13 | ||||
-rw-r--r-- | winit/src/application.rs | 1 | ||||
-rw-r--r-- | winit/src/application/state.rs | 21 | ||||
-rw-r--r-- | winit/src/conversion.rs | 2 |
5 files changed, 64 insertions, 13 deletions
diff --git a/core/src/menu.rs b/core/src/menu.rs index fe770216..52186140 100644 --- a/core/src/menu.rs +++ b/core/src/menu.rs @@ -4,11 +4,17 @@ use crate::keyboard::Hotkey; /// Menu representation. /// /// This can be used by `shell` implementations to create a menu. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct Menu<Message> { entries: Vec<Entry<Message>>, } +impl<Message> PartialEq for Menu<Message> { + fn eq(&self, other: &Self) -> bool { + self.entries == other.entries + } +} + impl<Message> Menu<Message> { /// Creates an empty [`Menu`]. pub fn new() -> Self { @@ -27,13 +33,13 @@ impl<Message> Menu<Message> { } /// Returns a [`MenuEntry`] iterator. - pub fn iter(self) -> impl Iterator<Item = Entry<Message>> { - self.entries.into_iter() + pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> { + self.entries.iter() } } /// Represents one of the possible entries used to build a [`Menu`]. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub enum Entry<Message> { /// Item for a [`Menu`] Item { @@ -82,3 +88,29 @@ impl<Message> Entry<Message> { Entry::Dropdown { content, submenu } } } + +impl<Message> PartialEq for Entry<Message> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + Entry::Item { + content, hotkey, .. + }, + Entry::Item { + content: other_content, + hotkey: other_hotkey, + .. + }, + ) => content == other_content && hotkey == other_hotkey, + ( + Entry::Dropdown { content, submenu }, + Entry::Dropdown { + content: other_content, + submenu: other_submenu, + }, + ) => content == other_content && submenu == other_submenu, + (Entry::Separator, Entry::Separator) => true, + _ => false, + } + } +} diff --git a/glutin/src/application.rs b/glutin/src/application.rs index a8e5dbf9..279b6c77 100644 --- a/glutin/src/application.rs +++ b/glutin/src/application.rs @@ -52,11 +52,14 @@ where runtime.track(subscription); let context = { - let builder = settings.window.into_builder( - &application.title(), - application.mode(), - event_loop.primary_monitor(), - ); + let builder = settings + .window + .into_builder( + &application.title(), + application.mode(), + event_loop.primary_monitor(), + ) + .with_menu(Some(conversion::menu(&application.menu()))); let context = ContextBuilder::new() .with_vsync(true) diff --git a/winit/src/application.rs b/winit/src/application.rs index 108c6d64..bf4b2489 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -151,6 +151,7 @@ where application.mode(), event_loop.primary_monitor(), ) + .with_menu(Some(conversion::menu(&application.menu()))) .build(&event_loop) .map_err(Error::WindowCreationFailed)?; diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 2994080c..f60f09be 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -1,5 +1,5 @@ use crate::conversion; -use crate::{Application, Color, Debug, Mode, Point, Size, Viewport}; +use crate::{Application, Color, Debug, Menu, Mode, Point, Size, Viewport}; use std::marker::PhantomData; use winit::event::{Touch, WindowEvent}; @@ -9,6 +9,7 @@ use winit::window::Window; #[derive(Debug, Clone)] pub struct State<A: Application> { title: String, + menu: Menu<A::Message>, mode: Mode, background_color: Color, scale_factor: f64, @@ -23,6 +24,7 @@ impl<A: Application> State<A> { /// Creates a new [`State`] for the provided [`Application`] and window. pub fn new(application: &A, window: &Window) -> Self { let title = application.title(); + let menu = application.menu(); let mode = application.mode(); let background_color = application.background_color(); let scale_factor = application.scale_factor(); @@ -36,10 +38,9 @@ impl<A: Application> State<A> { ) }; - window.set_menu(Some(conversion::menu(application.menu()))); - Self { title, + menu, mode, background_color, scale_factor, @@ -52,6 +53,11 @@ impl<A: Application> State<A> { } } + /// Returns the current [`Menu`] of the [`State`]. + pub fn menu(&self) -> &Menu<A::Message> { + &self.menu + } + /// Returns the current background [`Color`] of the [`State`]. pub fn background_color(&self) -> Color { self.background_color @@ -205,5 +211,14 @@ impl<A: Application> State<A> { self.scale_factor = new_scale_factor; } + + // Update menu + let new_menu = application.menu(); + + if self.menu != new_menu { + window.set_menu(Some(conversion::menu(&new_menu))); + + self.menu = new_menu; + } } } diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 4dc8bbf5..22118bf5 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -177,7 +177,7 @@ fn hotkey(hotkey: keyboard::Hotkey) -> winit::window::Hotkey { /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native -pub fn menu<Message>(menu: Menu<Message>) -> winit::window::Menu { +pub fn menu<Message>(menu: &Menu<Message>) -> winit::window::Menu { let mut converted = winit::window::Menu::new(); for item in menu.iter() { |