menu.rs

 1use crate::{Action, App, ForegroundPlatform, MutableAppContext};
 2
 3pub struct Menu<'a> {
 4    pub name: &'a str,
 5    pub items: Vec<MenuItem<'a>>,
 6}
 7
 8pub enum MenuItem<'a> {
 9    Separator,
10    Submenu(Menu<'a>),
11    Action {
12        name: &'a str,
13        action: Box<dyn Action>,
14    },
15}
16
17impl MutableAppContext {
18    pub fn set_menus(&mut self, menus: Vec<Menu>) {
19        self.foreground_platform
20            .set_menus(menus, &self.keystroke_matcher);
21    }
22}
23
24pub(crate) fn setup_menu_handlers(foreground_platform: &dyn ForegroundPlatform, app: &App) {
25    foreground_platform.on_will_open_menu(Box::new({
26        let cx = app.0.clone();
27        move || {
28            let mut cx = cx.borrow_mut();
29            cx.keystroke_matcher.clear_pending();
30        }
31    }));
32    foreground_platform.on_validate_menu_command(Box::new({
33        let cx = app.0.clone();
34        move |action| {
35            let cx = cx.borrow_mut();
36            !cx.keystroke_matcher.has_pending_keystrokes() && cx.is_action_available(action)
37        }
38    }));
39    foreground_platform.on_menu_command(Box::new({
40        let cx = app.0.clone();
41        move |action| {
42            let mut cx = cx.borrow_mut();
43            if let Some(key_window_id) = cx.cx.platform.key_window_id() {
44                if let Some(view_id) = cx.focused_view_id(key_window_id) {
45                    cx.handle_dispatch_action_from_effect(key_window_id, Some(view_id), action);
46                    return;
47                }
48            }
49            cx.dispatch_global_action_any(action);
50        }
51    }));
52}