app_menu.rs

  1use crate::{Action, AppContext, Platform};
  2use util::ResultExt;
  3
  4/// A menu of the application, either a main menu or a submenu
  5pub struct Menu<'a> {
  6    /// The name of the menu
  7    pub name: &'a str,
  8
  9    /// The items in the menu
 10    pub items: Vec<MenuItem<'a>>,
 11}
 12
 13/// The different kinds of items that can be in a menu
 14pub enum MenuItem<'a> {
 15    /// A separator between items
 16    Separator,
 17
 18    /// A submenu
 19    Submenu(Menu<'a>),
 20
 21    /// An action that can be performed
 22    Action {
 23        /// The name of this menu item
 24        name: &'a str,
 25
 26        /// the action to perform when this menu item is selected
 27        action: Box<dyn Action>,
 28
 29        /// The OS Action that corresponds to this action, if any
 30        /// See [`OsAction`] for more information
 31        os_action: Option<OsAction>,
 32    },
 33}
 34
 35impl<'a> MenuItem<'a> {
 36    /// Creates a new menu item that is a separator
 37    pub fn separator() -> Self {
 38        Self::Separator
 39    }
 40
 41    /// Creates a new menu item that is a submenu
 42    pub fn submenu(menu: Menu<'a>) -> Self {
 43        Self::Submenu(menu)
 44    }
 45
 46    /// Creates a new menu item that invokes an action
 47    pub fn action(name: &'a str, action: impl Action) -> Self {
 48        Self::Action {
 49            name,
 50            action: Box::new(action),
 51            os_action: None,
 52        }
 53    }
 54
 55    /// Creates a new menu item that invokes an action and has an OS action
 56    pub fn os_action(name: &'a str, action: impl Action, os_action: OsAction) -> Self {
 57        Self::Action {
 58            name,
 59            action: Box::new(action),
 60            os_action: Some(os_action),
 61        }
 62    }
 63}
 64
 65// TODO: As part of the global selections refactor, these should
 66// be moved to GPUI-provided actions that make this association
 67// without leaking the platform details to GPUI users
 68
 69/// OS actions are actions that are recognized by the operating system
 70/// This allows the operating system to provide specialized behavior for
 71/// these actions
 72#[derive(Copy, Clone, Eq, PartialEq)]
 73pub enum OsAction {
 74    /// The 'cut' action
 75    Cut,
 76
 77    /// The 'copy' action
 78    Copy,
 79
 80    /// The 'paste' action
 81    Paste,
 82
 83    /// The 'select all' action
 84    SelectAll,
 85
 86    /// The 'undo' action
 87    Undo,
 88
 89    /// The 'redo' action
 90    Redo,
 91}
 92
 93pub(crate) fn init_app_menus(platform: &dyn Platform, cx: &mut AppContext) {
 94    platform.on_will_open_app_menu(Box::new({
 95        let cx = cx.to_async();
 96        move || {
 97            cx.update(|cx| cx.clear_pending_keystrokes()).ok();
 98        }
 99    }));
100
101    platform.on_validate_app_menu_command(Box::new({
102        let cx = cx.to_async();
103        move |action| {
104            cx.update(|cx| cx.is_action_available(action))
105                .unwrap_or(false)
106        }
107    }));
108
109    platform.on_app_menu_action(Box::new({
110        let cx = cx.to_async();
111        move |action| {
112            cx.update(|cx| cx.dispatch_action(action)).log_err();
113        }
114    }));
115}