gpui: Add to support check state to MenuItem (#39876)
Release Notes: - N/A --- https://github.com/user-attachments/assets/d46b77ae-88ba-43da-93ad-3656a7fecaf9 The system menu is only support for macOS, so here just modify the macOS platform special code. The Windows, Linux used `ApplicationMenu`, I have already added `checked` option to Zed's ContextMenu. Then later when this PR merged, we can improve "View" menu to show check state to panels (Project Panel, Outline Panel, ...).
This commit is contained in:
@@ -64,12 +64,15 @@ pub enum MenuItem {
|
||||
/// The name of this menu item
|
||||
name: SharedString,
|
||||
|
||||
/// the action to perform when this menu item is selected
|
||||
/// The action to perform when this menu item is selected
|
||||
action: Box<dyn Action>,
|
||||
|
||||
/// The OS Action that corresponds to this action, if any
|
||||
/// See [`OsAction`] for more information
|
||||
os_action: Option<OsAction>,
|
||||
|
||||
/// Whether this action is checked
|
||||
checked: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -98,6 +101,7 @@ impl MenuItem {
|
||||
name: name.into(),
|
||||
action: Box::new(action),
|
||||
os_action: None,
|
||||
checked: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +115,7 @@ impl MenuItem {
|
||||
name: name.into(),
|
||||
action: Box::new(action),
|
||||
os_action: Some(os_action),
|
||||
checked: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,14 +128,36 @@ impl MenuItem {
|
||||
name,
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
} => OwnedMenuItem::Action {
|
||||
name: name.into(),
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
},
|
||||
MenuItem::SystemMenu(os_menu) => OwnedMenuItem::SystemMenu(os_menu.owned()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether this menu item is checked
|
||||
///
|
||||
/// Only for [`MenuItem::Action`], otherwise, will be ignored
|
||||
pub fn checked(mut self, checked: bool) -> Self {
|
||||
match self {
|
||||
MenuItem::Action {
|
||||
action,
|
||||
os_action,
|
||||
name,
|
||||
..
|
||||
} => MenuItem::Action {
|
||||
name,
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
},
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// OS menus are menus that are recognized by the operating system
|
||||
@@ -171,12 +198,15 @@ pub enum OwnedMenuItem {
|
||||
/// The name of this menu item
|
||||
name: String,
|
||||
|
||||
/// the action to perform when this menu item is selected
|
||||
/// The action to perform when this menu item is selected
|
||||
action: Box<dyn Action>,
|
||||
|
||||
/// The OS Action that corresponds to this action, if any
|
||||
/// See [`OsAction`] for more information
|
||||
os_action: Option<OsAction>,
|
||||
|
||||
/// Whether this action is checked
|
||||
checked: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -189,10 +219,12 @@ impl Clone for OwnedMenuItem {
|
||||
name,
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
} => OwnedMenuItem::Action {
|
||||
name: name.clone(),
|
||||
action: action.boxed_clone(),
|
||||
os_action: *os_action,
|
||||
checked: *checked,
|
||||
},
|
||||
OwnedMenuItem::SystemMenu(os_menu) => OwnedMenuItem::SystemMenu(os_menu.clone()),
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use cocoa::{
|
||||
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
|
||||
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard,
|
||||
NSPasteboardTypePNG, NSPasteboardTypeRTF, NSPasteboardTypeRTFD, NSPasteboardTypeString,
|
||||
NSPasteboardTypeTIFF, NSSavePanel, NSWindow,
|
||||
NSPasteboardTypeTIFF, NSSavePanel, NSVisualEffectState, NSVisualEffectView, NSWindow,
|
||||
},
|
||||
base::{BOOL, NO, YES, id, nil, selector},
|
||||
foundation::{
|
||||
@@ -315,6 +315,7 @@ impl MacPlatform {
|
||||
name,
|
||||
action,
|
||||
os_action,
|
||||
checked,
|
||||
} => {
|
||||
// Note that this is intentionally using earlier bindings, whereas typically
|
||||
// later ones take display precedence. See the discussion on
|
||||
@@ -409,6 +410,10 @@ impl MacPlatform {
|
||||
.autorelease();
|
||||
}
|
||||
|
||||
if *checked {
|
||||
item.setState_(NSVisualEffectState::Active);
|
||||
}
|
||||
|
||||
let tag = actions.len() as NSInteger;
|
||||
let _: () = msg_send![item, setTag: tag];
|
||||
actions.push(action.boxed_clone());
|
||||
|
||||
Reference in New Issue
Block a user