summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-07-12 22:28:18 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-07-12 22:28:18 +0200
commit31997d255f263a0f47f5af0d8560f3d5bd37f077 (patch)
tree0413f22ec8052f0a1e310b12a4f5c4dedb883e81
parentb3ff522c182590ffcd03113b5147fa4599559059 (diff)
downloadiced-31997d255f263a0f47f5af0d8560f3d5bd37f077.tar.gz
iced-31997d255f263a0f47f5af0d8560f3d5bd37f077.tar.bz2
iced-31997d255f263a0f47f5af0d8560f3d5bd37f077.zip
Store and synchronize `Menu` in `application::State`
-rw-r--r--core/src/menu.rs40
-rw-r--r--glutin/src/application.rs13
-rw-r--r--winit/src/application.rs1
-rw-r--r--winit/src/application/state.rs21
-rw-r--r--winit/src/conversion.rs2
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() {