Store and synchronize Menu in application::State
This commit is contained in:
parent
b3ff522c18
commit
31997d255f
5 changed files with 64 additions and 13 deletions
|
|
@ -4,11 +4,17 @@ use crate::keyboard::Hotkey;
|
||||||
/// Menu representation.
|
/// Menu representation.
|
||||||
///
|
///
|
||||||
/// This can be used by `shell` implementations to create a menu.
|
/// This can be used by `shell` implementations to create a menu.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Menu<Message> {
|
pub struct Menu<Message> {
|
||||||
entries: Vec<Entry<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> {
|
impl<Message> Menu<Message> {
|
||||||
/// Creates an empty [`Menu`].
|
/// Creates an empty [`Menu`].
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
@ -27,13 +33,13 @@ impl<Message> Menu<Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [`MenuEntry`] iterator.
|
/// Returns a [`MenuEntry`] iterator.
|
||||||
pub fn iter(self) -> impl Iterator<Item = Entry<Message>> {
|
pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> {
|
||||||
self.entries.into_iter()
|
self.entries.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents one of the possible entries used to build a [`Menu`].
|
/// Represents one of the possible entries used to build a [`Menu`].
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Entry<Message> {
|
pub enum Entry<Message> {
|
||||||
/// Item for a [`Menu`]
|
/// Item for a [`Menu`]
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -82,3 +88,29 @@ impl<Message> Entry<Message> {
|
||||||
Entry::Dropdown { content, submenu }
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,11 +52,14 @@ where
|
||||||
runtime.track(subscription);
|
runtime.track(subscription);
|
||||||
|
|
||||||
let context = {
|
let context = {
|
||||||
let builder = settings.window.into_builder(
|
let builder = settings
|
||||||
&application.title(),
|
.window
|
||||||
application.mode(),
|
.into_builder(
|
||||||
event_loop.primary_monitor(),
|
&application.title(),
|
||||||
);
|
application.mode(),
|
||||||
|
event_loop.primary_monitor(),
|
||||||
|
)
|
||||||
|
.with_menu(Some(conversion::menu(&application.menu())));
|
||||||
|
|
||||||
let context = ContextBuilder::new()
|
let context = ContextBuilder::new()
|
||||||
.with_vsync(true)
|
.with_vsync(true)
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ where
|
||||||
application.mode(),
|
application.mode(),
|
||||||
event_loop.primary_monitor(),
|
event_loop.primary_monitor(),
|
||||||
)
|
)
|
||||||
|
.with_menu(Some(conversion::menu(&application.menu())))
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.map_err(Error::WindowCreationFailed)?;
|
.map_err(Error::WindowCreationFailed)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::conversion;
|
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 std::marker::PhantomData;
|
||||||
use winit::event::{Touch, WindowEvent};
|
use winit::event::{Touch, WindowEvent};
|
||||||
|
|
@ -9,6 +9,7 @@ use winit::window::Window;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct State<A: Application> {
|
pub struct State<A: Application> {
|
||||||
title: String,
|
title: String,
|
||||||
|
menu: Menu<A::Message>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
|
|
@ -23,6 +24,7 @@ impl<A: Application> State<A> {
|
||||||
/// Creates a new [`State`] for the provided [`Application`] and window.
|
/// Creates a new [`State`] for the provided [`Application`] and window.
|
||||||
pub fn new(application: &A, window: &Window) -> Self {
|
pub fn new(application: &A, window: &Window) -> Self {
|
||||||
let title = application.title();
|
let title = application.title();
|
||||||
|
let menu = application.menu();
|
||||||
let mode = application.mode();
|
let mode = application.mode();
|
||||||
let background_color = application.background_color();
|
let background_color = application.background_color();
|
||||||
let scale_factor = application.scale_factor();
|
let scale_factor = application.scale_factor();
|
||||||
|
|
@ -36,10 +38,9 @@ impl<A: Application> State<A> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
window.set_menu(Some(conversion::menu(application.menu())));
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
title,
|
title,
|
||||||
|
menu,
|
||||||
mode,
|
mode,
|
||||||
background_color,
|
background_color,
|
||||||
scale_factor,
|
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`].
|
/// Returns the current background [`Color`] of the [`State`].
|
||||||
pub fn background_color(&self) -> Color {
|
pub fn background_color(&self) -> Color {
|
||||||
self.background_color
|
self.background_color
|
||||||
|
|
@ -205,5 +211,14 @@ impl<A: Application> State<A> {
|
||||||
|
|
||||||
self.scale_factor = new_scale_factor;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ fn hotkey(hotkey: keyboard::Hotkey) -> winit::window::Hotkey {
|
||||||
///
|
///
|
||||||
/// [`winit`]: https://github.com/rust-windowing/winit
|
/// [`winit`]: https://github.com/rust-windowing/winit
|
||||||
/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
|
/// [`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();
|
let mut converted = winit::window::Menu::new();
|
||||||
|
|
||||||
for item in menu.iter() {
|
for item in menu.iter() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue