From 2e7eac7d2167b492149e064927e764eca67f98fe Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 13 Jul 2021 21:31:34 +0200 Subject: Implement `conversion::menu_message` --- winit/src/conversion.rs | 50 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 687a037e..dc7f90ad 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -220,16 +220,54 @@ pub fn menu(menu: &Menu) -> winit::window::Menu { /// Given a [`Menu`] and an identifier of a [`menu::Entry`], it returns the /// `Message` that should be produced when that entry is activated. -pub fn menu_message( - _menu: &Menu, - id: isize, -) -> Option +pub fn menu_message(menu: &Menu, id: isize) -> Option where Message: Clone, { - println!("Menu entry activated: {}", id); + use std::convert::TryFrom; - None + fn find_message( + target: usize, + starting_id: usize, + menu: &Menu, + ) -> Result + where + Message: Clone, + { + let mut id = starting_id; + + for entry in menu.iter() { + match entry { + menu::Entry::Item { on_activation, .. } => { + if id == target { + return Ok(on_activation.clone()); + } + + id += 1; + } + menu::Entry::Dropdown { submenu, .. } => { + match find_message(target, id, submenu) { + Ok(message) => { + return Ok(message); + } + Err(n_children) => { + id += n_children; + } + } + } + menu::Entry::Separator => {} + } + } + + Err(id - starting_id) + } + + // TODO: Does `winit` really need to provide an `isize`? + if let Ok(id) = usize::try_from(id) { + find_message(id, 0, menu).ok() + } else { + None + } } /// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon. -- cgit