gpui: Add disabled state to app menu items (#44191)
Continue #39876 to add `disabled` state to `MenuItem`. Make this change for #44047 ready to have disabled state. 1. Add `disabled` state to `MenuItem`. 2. Add some builder methods to `Menu` and `MenuItem`. 3. Improve `set_menus` method to receive a `impl IntoIterator<Item = Menu>`. Release Notes: - N/A -- <img width="294" height="204" alt="image" src="https://github.com/user-attachments/assets/688e0db8-6c4e-4f9b-a832-8228db0e95d8" /> ```bash cargo run -p gpui --example set_menus ```
This commit is contained in:
1 parent
2728ccb8ac
commit
d8fea89fce
12 files changed
+236
-83
No files matched your search
@@ -181,6 +181,7 @@ fn run_example() {
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "Image".into(),
|
||||
items: vec![MenuItem::action("Quit", Quit)],
|
||||
disabled: false,
|
||||
}]);
|
||||
|
||||
let window_options = WindowOptions {
|
||||
|
||||
@@ -273,10 +273,7 @@ fn run_example() {
|
||||
cx.activate(true);
|
||||
cx.on_action(|_: &Quit, cx| cx.quit());
|
||||
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "Image Gallery".into(),
|
||||
items: vec![MenuItem::action("Quit", Quit)],
|
||||
}]);
|
||||
cx.set_menus([Menu::new("Image Gallery").items([MenuItem::action("Quit", Quit)])]);
|
||||
|
||||
let window_options = WindowOptions {
|
||||
titlebar: Some(TitlebarOptions {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use gpui::{
|
||||
App, Context, Global, Menu, MenuItem, SharedString, SystemMenuType, Window, WindowOptions,
|
||||
actions, div, prelude::*, rgb,
|
||||
actions, div, prelude::*,
|
||||
};
|
||||
use gpui_platform::application;
|
||||
|
||||
@@ -12,12 +12,12 @@ impl Render for SetMenus {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.flex()
|
||||
.bg(rgb(0x2e7d32))
|
||||
.bg(gpui::white())
|
||||
.size_full()
|
||||
.justify_center()
|
||||
.items_center()
|
||||
.text_xl()
|
||||
.text_color(rgb(0xffffff))
|
||||
.text_color(gpui::black())
|
||||
.child("Set Menus Example")
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ fn run_example() {
|
||||
|
||||
// Bring the menu bar to the foreground (so you can see the menu bar)
|
||||
cx.activate(true);
|
||||
// Register the `quit` function so it can be referenced by the `MenuItem::action` in the menu bar
|
||||
// Register the `quit` function so it can be referenced
|
||||
// by the `MenuItem::action` in the menu bar
|
||||
cx.on_action(quit);
|
||||
cx.on_action(toggle_check);
|
||||
// Add menu items
|
||||
@@ -91,19 +92,24 @@ impl Global for AppState {}
|
||||
|
||||
fn set_app_menus(cx: &mut App) {
|
||||
let app_state = cx.global::<AppState>();
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "set_menus".into(),
|
||||
items: vec![
|
||||
MenuItem::os_submenu("Services", SystemMenuType::Services),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action(ViewMode::List, ToggleCheck)
|
||||
.checked(app_state.view_mode == ViewMode::List),
|
||||
MenuItem::action(ViewMode::Grid, ToggleCheck)
|
||||
.checked(app_state.view_mode == ViewMode::Grid),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Quit", Quit),
|
||||
],
|
||||
}]);
|
||||
cx.set_menus([Menu::new("set_menus").items([
|
||||
MenuItem::os_submenu("Services", SystemMenuType::Services),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Disabled Item", gpui::NoAction).disabled(true),
|
||||
MenuItem::submenu(Menu::new("Disabled Submenu").disabled(true)),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("List Mode", ToggleCheck).checked(app_state.view_mode == ViewMode::List),
|
||||
MenuItem::submenu(
|
||||
Menu::new("Mode").items([
|
||||
MenuItem::action(ViewMode::List, ToggleCheck)
|
||||
.checked(app_state.view_mode == ViewMode::List),
|
||||
MenuItem::action(ViewMode::Grid, ToggleCheck)
|
||||
.checked(app_state.view_mode == ViewMode::Grid),
|
||||
]),
|
||||
),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Quit", Quit),
|
||||
])]);
|
||||
}
|
||||
|
||||
// Associate actions using the `actions!` macro (or `Action` derive macro)
|
||||
@@ -111,7 +117,7 @@ actions!(set_menus, [Quit, ToggleCheck]);
|
||||
|
||||
// Define the quit function that is registered with the App
|
||||
fn quit(_: &Quit, cx: &mut App) {
|
||||
println!("Gracefully quitting the application . . .");
|
||||
println!("Gracefully quitting the application...");
|
||||
cx.quit();
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +350,7 @@ fn run_example() {
|
||||
application().run(|cx: &mut App| {
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "GPUI Typography".into(),
|
||||
disabled: false,
|
||||
items: vec![],
|
||||
}]);
|
||||
|
||||
|
||||
@@ -2072,7 +2072,8 @@ impl App {
|
||||
}
|
||||
|
||||
/// Sets the menu bar for this application. This will replace any existing menu bar.
|
||||
pub fn set_menus(&self, menus: Vec<Menu>) {
|
||||
pub fn set_menus(&self, menus: impl IntoIterator<Item = Menu>) {
|
||||
let menus: Vec<Menu> = menus.into_iter().collect();
|
||||
self.platform.set_menus(menus, &self.keymap.borrow());
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,39 @@ pub struct Menu {
|
||||
|
||||
/// The items in the menu
|
||||
pub items: Vec<MenuItem>,
|
||||
|
||||
/// Whether this menu is disabled
|
||||
pub disabled: bool,
|
||||
}
|
||||
|
||||
impl Menu {
|
||||
/// Create a new Menu with the given name
|
||||
pub fn new(name: impl Into<SharedString>) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
items: vec![],
|
||||
disabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set items to be in this menu
|
||||
pub fn items(mut self, items: impl IntoIterator<Item = MenuItem>) -> Self {
|
||||
self.items = items.into_iter().collect();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether this menu is disabled
|
||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||
self.disabled = disabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Create an OwnedMenu from this Menu
|
||||
pub fn owned(self) -> OwnedMenu {
|
||||
OwnedMenu {
|
||||
name: self.name.to_string().into(),
|
||||
items: self.items.into_iter().map(|item| item.owned()).collect(),
|
||||
disabled: self.disabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,6 +97,9 @@ pub enum MenuItem {
|
||||
|
||||
/// Whether this action is checked
|
||||
checked: bool,
|
||||
|
||||
/// Whether this action is disabled
|
||||
disabled: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -101,6 +129,7 @@ impl MenuItem {
|
||||
action: Box::new(action),
|
||||
os_action: None,
|
||||
checked: false,
|
||||
disabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +144,7 @@ impl MenuItem {
|
||||
action: Box::new(action),
|
||||
os_action: Some(os_action),
|
||||
checked: false,
|
||||
disabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,11 +158,13 @@ impl MenuItem {
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
disabled,
|
||||
} => OwnedMenuItem::Action {
|
||||
name: name.into(),
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
disabled,
|
||||
},
|
||||
MenuItem::SystemMenu(os_menu) => OwnedMenuItem::SystemMenu(os_menu.owned()),
|
||||
}
|
||||
@@ -142,19 +174,49 @@ impl MenuItem {
|
||||
///
|
||||
/// Only for [`MenuItem::Action`], otherwise, will be ignored
|
||||
pub fn checked(mut self, checked: bool) -> Self {
|
||||
match &mut self {
|
||||
MenuItem::Action { checked: old, .. } => {
|
||||
*old = checked;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns whether this menu item is checked
|
||||
///
|
||||
/// Only for [`MenuItem::Action`], otherwise, returns false
|
||||
#[inline]
|
||||
pub fn is_checked(&self) -> bool {
|
||||
match self {
|
||||
MenuItem::Action {
|
||||
action,
|
||||
os_action,
|
||||
name,
|
||||
..
|
||||
} => MenuItem::Action {
|
||||
name,
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
},
|
||||
_ => self,
|
||||
MenuItem::Action { checked, .. } => *checked,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether this menu item is disabled
|
||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||
match &mut self {
|
||||
MenuItem::Action { disabled: old, .. } => {
|
||||
*old = disabled;
|
||||
}
|
||||
MenuItem::Submenu(submenu) => {
|
||||
submenu.disabled = disabled;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns whether this menu item is disabled
|
||||
///
|
||||
/// Only for [`MenuItem::Action`] and [`MenuItem::Submenu`], otherwise, returns false
|
||||
#[inline]
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
match self {
|
||||
MenuItem::Action { disabled, .. } => *disabled,
|
||||
MenuItem::Submenu(submenu) => submenu.disabled,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,6 +241,9 @@ pub struct OwnedMenu {
|
||||
|
||||
/// The items in the menu
|
||||
pub items: Vec<OwnedMenuItem>,
|
||||
|
||||
/// Whether this menu is disabled
|
||||
pub disabled: bool,
|
||||
}
|
||||
|
||||
/// The different kinds of items that can be in a menu
|
||||
@@ -206,6 +271,9 @@ pub enum OwnedMenuItem {
|
||||
|
||||
/// Whether this action is checked
|
||||
checked: bool,
|
||||
|
||||
/// Whether this action is disabled
|
||||
disabled: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -219,11 +287,13 @@ impl Clone for OwnedMenuItem {
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
disabled,
|
||||
} => OwnedMenuItem::Action {
|
||||
name: name.clone(),
|
||||
action: action.boxed_clone(),
|
||||
os_action: *os_action,
|
||||
checked: *checked,
|
||||
disabled: *disabled,
|
||||
},
|
||||
OwnedMenuItem::SystemMenu(os_menu) => OwnedMenuItem::SystemMenu(os_menu.clone()),
|
||||
}
|
||||
@@ -287,3 +357,70 @@ pub(crate) fn init_app_menus(platform: &dyn Platform, cx: &App) {
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Menu;
|
||||
|
||||
#[test]
|
||||
fn test_menu() {
|
||||
let menu = Menu::new("App")
|
||||
.items(vec![
|
||||
crate::MenuItem::action("Action 1", gpui::NoAction),
|
||||
crate::MenuItem::separator(),
|
||||
])
|
||||
.disabled(true);
|
||||
|
||||
assert_eq!(menu.name.as_ref(), "App");
|
||||
assert_eq!(menu.items.len(), 2);
|
||||
assert!(menu.disabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_menu_item_builder() {
|
||||
use super::MenuItem;
|
||||
|
||||
let item = MenuItem::action("Test Action", gpui::NoAction);
|
||||
assert_eq!(
|
||||
match &item {
|
||||
MenuItem::Action { name, .. } => name.as_ref(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
"Test Action"
|
||||
);
|
||||
assert!(matches!(
|
||||
item,
|
||||
MenuItem::Action {
|
||||
checked: false,
|
||||
disabled: false,
|
||||
..
|
||||
}
|
||||
));
|
||||
|
||||
assert!(
|
||||
MenuItem::action("Test Action", gpui::NoAction)
|
||||
.checked(true)
|
||||
.is_checked()
|
||||
);
|
||||
assert!(
|
||||
MenuItem::action("Test Action", gpui::NoAction)
|
||||
.disabled(true)
|
||||
.is_disabled()
|
||||
);
|
||||
|
||||
let submenu = MenuItem::submenu(super::Menu {
|
||||
name: "Submenu".into(),
|
||||
items: vec![],
|
||||
disabled: true,
|
||||
});
|
||||
assert_eq!(
|
||||
match &submenu {
|
||||
MenuItem::Submenu(menu) => menu.name.as_ref(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
"Submenu"
|
||||
);
|
||||
assert!(!submenu.is_checked());
|
||||
assert!(submenu.is_disabled());
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ use block::ConcreteBlock;
|
||||
use cocoa::{
|
||||
appkit::{
|
||||
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
|
||||
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSSavePanel,
|
||||
NSVisualEffectState, NSVisualEffectView, NSWindow,
|
||||
NSControl as _, NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel,
|
||||
NSSavePanel, NSVisualEffectState, NSVisualEffectView, NSWindow,
|
||||
},
|
||||
base::{BOOL, NO, YES, id, nil, selector},
|
||||
foundation::{
|
||||
@@ -297,6 +297,7 @@ impl MacPlatform {
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
disabled,
|
||||
} => {
|
||||
// Note that this is intentionally using earlier bindings, whereas typically
|
||||
// later ones take display precedence. See the discussion on
|
||||
@@ -394,13 +395,18 @@ impl MacPlatform {
|
||||
if *checked {
|
||||
item.setState_(NSVisualEffectState::Active);
|
||||
}
|
||||
item.setEnabled_(!disabled);
|
||||
|
||||
let tag = actions.len() as NSInteger;
|
||||
let _: () = msg_send![item, setTag: tag];
|
||||
actions.push(action.boxed_clone());
|
||||
item
|
||||
}
|
||||
MenuItem::Submenu(Menu { name, items }) => {
|
||||
MenuItem::Submenu(Menu {
|
||||
name,
|
||||
items,
|
||||
disabled,
|
||||
}) => {
|
||||
let item = NSMenuItem::new(nil).autorelease();
|
||||
let submenu = NSMenu::new(nil).autorelease();
|
||||
submenu.setDelegate_(delegate);
|
||||
@@ -408,6 +414,7 @@ impl MacPlatform {
|
||||
submenu.addItem_(Self::create_menu_item(item, delegate, actions, keymap));
|
||||
}
|
||||
item.setSubmenu_(submenu);
|
||||
item.setEnabled_(!disabled);
|
||||
item.setTitle_(ns_string(name));
|
||||
item
|
||||
}
|
||||
|
||||
@@ -35,15 +35,7 @@ fn main() {
|
||||
cx.activate(true);
|
||||
cx.on_action(quit);
|
||||
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
|
||||
cx.set_menus(vec![Menu {
|
||||
name: "Zed".into(),
|
||||
items: vec![MenuItem::Action {
|
||||
name: "Quit".into(),
|
||||
action: Box::new(Quit),
|
||||
os_action: None,
|
||||
checked: false,
|
||||
}],
|
||||
}]);
|
||||
cx.set_menus([Menu::new("Zed").items([MenuItem::action("Quit", Quit)])]);
|
||||
|
||||
let livekit_url = std::env::var("LIVEKIT_URL").unwrap_or("http://localhost:7880".into());
|
||||
let livekit_key = std::env::var("LIVEKIT_KEY").unwrap_or("devkey".into());
|
||||
|
||||
@@ -3,8 +3,5 @@ use gpui::{Menu, MenuItem};
|
||||
pub fn app_menus() -> Vec<Menu> {
|
||||
use crate::actions::Quit;
|
||||
|
||||
vec![Menu {
|
||||
name: "Storybook".into(),
|
||||
items: vec![MenuItem::action("Quit", Quit)],
|
||||
}]
|
||||
vec![Menu::new("Storybook").items([MenuItem::action("Quit", Quit)])]
|
||||
}
|
||||
@@ -114,8 +114,9 @@ impl ApplicationMenu {
|
||||
name,
|
||||
action,
|
||||
checked,
|
||||
disabled,
|
||||
..
|
||||
} => menu.action_checked(name, action, checked),
|
||||
} => menu.action_checked_with_disabled(name, action, checked, disabled),
|
||||
OwnedMenuItem::Submenu(submenu) => {
|
||||
submenu
|
||||
.items
|
||||
@@ -126,8 +127,10 @@ impl ApplicationMenu {
|
||||
name,
|
||||
action,
|
||||
checked,
|
||||
disabled,
|
||||
..
|
||||
} => menu.action_checked(name, action, checked),
|
||||
} => menu
|
||||
.action_checked_with_disabled(name, action, checked, disabled),
|
||||
OwnedMenuItem::Submenu(_) => menu,
|
||||
OwnedMenuItem::SystemMenu(_) => {
|
||||
// A system menu doesn't make sense in this context, so ignore it
|
||||
|
||||
@@ -692,10 +692,20 @@ impl ContextMenu {
|
||||
}
|
||||
|
||||
pub fn action_checked(
|
||||
self,
|
||||
label: impl Into<SharedString>,
|
||||
action: Box<dyn Action>,
|
||||
checked: bool,
|
||||
) -> Self {
|
||||
self.action_checked_with_disabled(label, action, checked, false)
|
||||
}
|
||||
|
||||
pub fn action_checked_with_disabled(
|
||||
mut self,
|
||||
label: impl Into<SharedString>,
|
||||
action: Box<dyn Action>,
|
||||
checked: bool,
|
||||
disabled: bool,
|
||||
) -> Self {
|
||||
self.items.push(ContextMenuItem::Entry(ContextMenuEntry {
|
||||
toggle: if checked {
|
||||
@@ -718,7 +728,7 @@ impl ContextMenu {
|
||||
icon_position: IconPosition::End,
|
||||
icon_size: IconSize::Small,
|
||||
icon_color: None,
|
||||
disabled: false,
|
||||
disabled,
|
||||
documentation_aside: None,
|
||||
end_slot_icon: None,
|
||||
end_slot_title: None,
|
||||
|
||||
@@ -31,6 +31,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
MenuItem::action("Toggle All Docks", workspace::ToggleAllDocks),
|
||||
MenuItem::submenu(Menu {
|
||||
name: "Editor Layout".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action("Split Up", workspace::SplitUp::default()),
|
||||
MenuItem::action("Split Down", workspace::SplitDown::default()),
|
||||
@@ -60,39 +61,31 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
vec![
|
||||
Menu {
|
||||
name: "Zed".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action("About Zed", zed_actions::About),
|
||||
MenuItem::action("Check for Updates", auto_update::Check),
|
||||
MenuItem::separator(),
|
||||
MenuItem::submenu(Menu {
|
||||
name: "Settings".into(),
|
||||
items: vec![
|
||||
MenuItem::action("Open Settings", zed_actions::OpenSettings),
|
||||
MenuItem::action("Open Settings File", super::OpenSettingsFile),
|
||||
MenuItem::action("Open Project Settings", zed_actions::OpenProjectSettings),
|
||||
MenuItem::action(
|
||||
"Open Project Settings File",
|
||||
super::OpenProjectSettingsFile,
|
||||
),
|
||||
MenuItem::action("Open Default Settings", super::OpenDefaultSettings),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Open Keymap", zed_actions::OpenKeymap),
|
||||
MenuItem::action("Open Keymap File", zed_actions::OpenKeymapFile),
|
||||
MenuItem::action(
|
||||
"Open Default Key Bindings",
|
||||
zed_actions::OpenDefaultKeymap,
|
||||
),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action(
|
||||
"Select Theme...",
|
||||
zed_actions::theme_selector::Toggle::default(),
|
||||
),
|
||||
MenuItem::action(
|
||||
"Select Icon Theme...",
|
||||
zed_actions::icon_theme_selector::Toggle::default(),
|
||||
),
|
||||
],
|
||||
}),
|
||||
MenuItem::submenu(Menu::new("Settings").items([
|
||||
MenuItem::action("Open Settings", zed_actions::OpenSettings),
|
||||
MenuItem::action("Open Settings File", super::OpenSettingsFile),
|
||||
MenuItem::action("Open Project Settings", zed_actions::OpenProjectSettings),
|
||||
MenuItem::action("Open Project Settings File", super::OpenProjectSettingsFile),
|
||||
MenuItem::action("Open Default Settings", super::OpenDefaultSettings),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action("Open Keymap", zed_actions::OpenKeymap),
|
||||
MenuItem::action("Open Keymap File", zed_actions::OpenKeymapFile),
|
||||
MenuItem::action("Open Default Key Bindings", zed_actions::OpenDefaultKeymap),
|
||||
MenuItem::separator(),
|
||||
MenuItem::action(
|
||||
"Select Theme...",
|
||||
zed_actions::theme_selector::Toggle::default(),
|
||||
),
|
||||
MenuItem::action(
|
||||
"Select Icon Theme...",
|
||||
zed_actions::icon_theme_selector::Toggle::default(),
|
||||
),
|
||||
])),
|
||||
MenuItem::separator(),
|
||||
#[cfg(target_os = "macos")]
|
||||
MenuItem::os_submenu("Services", gpui::SystemMenuType::Services),
|
||||
@@ -113,6 +106,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "File".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action("New", workspace::NewFile),
|
||||
MenuItem::action("New Window", workspace::NewWindow),
|
||||
@@ -160,6 +154,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "Edit".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::os_action("Undo", editor::actions::Undo, OsAction::Undo),
|
||||
MenuItem::os_action("Redo", editor::actions::Redo, OsAction::Redo),
|
||||
@@ -180,6 +175,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "Selection".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::os_action(
|
||||
"Select All",
|
||||
@@ -227,10 +223,12 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "View".into(),
|
||||
disabled: false,
|
||||
items: view_items,
|
||||
},
|
||||
Menu {
|
||||
name: "Go".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action("Back", workspace::GoBack),
|
||||
MenuItem::action("Forward", workspace::GoForward),
|
||||
@@ -262,6 +260,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "Run".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action(
|
||||
"Spawn Task",
|
||||
@@ -286,6 +285,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "Window".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action("Minimize", super::Minimize),
|
||||
MenuItem::action("Zoom", super::Zoom),
|
||||
@@ -294,6 +294,7 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
|
||||
},
|
||||
Menu {
|
||||
name: "Help".into(),
|
||||
disabled: false,
|
||||
items: vec![
|
||||
MenuItem::action(
|
||||
"View Release Notes Locally",
|
||||
|
||||
Reference in new issue
Block a user