Optimize appbar for macos

This commit is contained in:
xxrl
2022-04-22 23:41:12 +08:00
parent 5d143f57d7
commit cfa0c1039c
4 changed files with 94 additions and 51 deletions

View File

@@ -11,13 +11,20 @@ use objc::{
runtime::{Object, Sel, BOOL},
sel, sel_impl,
};
use sciter::{make_args, Host};
use std::{
ffi::c_void,
rc::Rc,
sync::{Arc, Mutex},
};
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
const TERMINATE_TAG: u32 = 0;
const SHOW_ABOUT_TAG: u32 = 1;
const SHOW_SETTINGS_TAG: u32 = 2;
const RUN_ME_TAG: u32 = 3;
lazy_static::lazy_static! {
pub static ref SHOULD_OPEN_UNTITLED_FILE_CALLBACK: Arc<Mutex<Option<Box<dyn Fn() + Send>>>> = Default::default();
}
@@ -32,7 +39,7 @@ struct DelegateState {
impl DelegateState {
fn command(&mut self, command: u32) {
if command == 0 {
if command == TERMINATE_TAG {
unsafe {
let () = msg_send!(NSApp(), terminate: nil);
}
@@ -42,6 +49,16 @@ impl DelegateState {
}
}
impl AppHandler for Rc<Host> {
fn command(&mut self, cmd: u32) {
if cmd == SHOW_ABOUT_TAG {
let _ = self.call_function("showAbout", &make_args![]);
} else if cmd == SHOW_SETTINGS_TAG {
let _ = self.call_function("showSettings", &make_args![]);
}
}
}
// https://github.com/xi-editor/druid/blob/master/druid-shell/src/platform/mac/application.rs
unsafe fn set_delegate(handler: Option<Box<dyn AppHandler>>) {
let mut decl =
@@ -92,32 +109,57 @@ extern "C" fn application_should_handle_open_untitled_file(
extern "C" fn handle_menu_item(this: &mut Object, _: Sel, item: id) {
unsafe {
let tag: isize = msg_send![item, tag];
if tag == 0 {
let tag = tag as u32;
if tag == RUN_ME_TAG {
crate::run_me(Vec::<String>::new()).ok();
} else {
let inner: *mut c_void = *this.get_ivar(APP_HANDLER_IVAR);
let inner = &mut *(inner as *mut DelegateState);
(*inner).command(tag as u32);
} else if tag == 1 {
crate::run_me(Vec::<String>::new()).ok();
}
}
}
pub fn make_menubar() {
unsafe fn make_menu_item(title: &str, key: &str, tag: u32) -> *mut Object {
let title = NSString::alloc(nil).init_str(title);
let action = sel!(handleMenuItem:);
let key = NSString::alloc(nil).init_str(key);
let object = NSMenuItem::alloc(nil)
.initWithTitle_action_keyEquivalent_(title, action, key)
.autorelease();
let () = msg_send![object, setTag: tag];
object
}
pub fn make_menubar(host: Rc<Host>) {
unsafe {
let _pool = NSAutoreleasePool::new(nil);
set_delegate(None);
set_delegate(Some(Box::new(host)));
let menubar = NSMenu::new(nil).autorelease();
let app_menu_item = NSMenuItem::new(nil).autorelease();
menubar.addItem_(app_menu_item);
let app_menu = NSMenu::new(nil).autorelease();
let quit_title =
NSString::alloc(nil).init_str(&format!("Quit {}", hbb_common::config::APP_NAME));
let quit_action = sel!(handleMenuItem:);
let quit_key = NSString::alloc(nil).init_str("q");
let quit_item = NSMenuItem::alloc(nil)
.initWithTitle_action_keyEquivalent_(quit_title, quit_action, quit_key)
.autorelease();
let () = msg_send![quit_item, setTag: 0];
let about_item = make_menu_item("About", "a", SHOW_ABOUT_TAG);
app_menu.addItem_(about_item);
let separator = NSMenuItem::separatorItem(nil).autorelease();
app_menu.addItem_(separator);
let settings_item = make_menu_item("Settings", "s", SHOW_SETTINGS_TAG);
app_menu.addItem_(settings_item);
if std::env::args().len() > 1 {
let new_item = make_menu_item("New Window", "n", RUN_ME_TAG);
app_menu.addItem_(new_item);
}
let separator = NSMenuItem::separatorItem(nil).autorelease();
app_menu.addItem_(separator);
let quit_item = make_menu_item(
&format!("Quit {}", hbb_common::config::APP_NAME),
"q",
TERMINATE_TAG,
);
app_menu_item.setSubmenu_(app_menu);
/*
if !enabled {
let () = msg_send![quit_item, setEnabled: NO];
@@ -129,17 +171,6 @@ pub fn make_menubar() {
let () = msg_send![item, setTag: id as isize];
*/
app_menu.addItem_(quit_item);
if std::env::args().len() > 1 {
let new_title = NSString::alloc(nil).init_str("New Window");
let new_action = sel!(handleMenuItem:);
let new_key = NSString::alloc(nil).init_str("n");
let new_item = NSMenuItem::alloc(nil)
.initWithTitle_action_keyEquivalent_(new_title, new_action, new_key)
.autorelease();
let () = msg_send![new_item, setTag: 1];
app_menu.addItem_(new_item);
}
app_menu_item.setSubmenu_(app_menu);
NSApp().setMainMenu_(menubar);
}
}