From 42ce3b928647d55804af0f179412c027316f7bb2 Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Sun, 8 May 2016 00:25:31 +0200 Subject: [PATCH] WIP on new menu stuff --- examples/menu.rs | 6 +- src/key.rs | 2 +- src/lib.rs | 10 +- src/native/macosx/MacMiniFB.m | 13 ++ src/native/macosx/OSXWindow.m | 13 +- src/os/macos/mod.rs | 253 ++++++++++++---------------------- 6 files changed, 120 insertions(+), 177 deletions(-) diff --git a/examples/menu.rs b/examples/menu.rs index 8481637..56bcb09 100644 --- a/examples/menu.rs +++ b/examples/menu.rs @@ -89,9 +89,11 @@ fn main() { //window.add_menu("Test", &menu).expect("Unable to add menu"); let mut menu = Menu::new("TestMenu").unwrap(); - let mut item = MenuItem::new("Item", 1).enabled(true); - menu.add_item(&mut item); + menu.add_item(&MenuItem::new("Item 1", 1)); + menu.add_item(&MenuItem::new("Item 2", 2)); + menu.add_item(&MenuItem::new("Item 3", 3)); + let _ = window.add_menu(&menu); let color_mul = 1; diff --git a/src/key.rs b/src/key.rs index 920ab88..cfad8c3 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1,5 +1,5 @@ /// Key is used by the get key functions to check if some keys on the keyboard has been pressed -#[derive(PartialEq, Clone, Copy)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum Key { Key0 = 0, Key1 = 1, diff --git a/src/lib.rs b/src/lib.rs index 0cc8d87..00f9d34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -495,6 +495,7 @@ impl Window { } } + /// Command key on Mac OS pub const MENU_KEY_COMMAND: usize = 1; /// Windows key on Windows @@ -510,6 +511,9 @@ const MENU_ID_SEPARATOR:usize = 0xffffffff; pub struct Menu(imp::Menu); +#[derive(Debug)] +pub struct MenuItemHandle(pub u64); + impl Menu { pub fn new(name: &str) -> Result { imp::Menu::new(name).map(Menu) @@ -526,13 +530,13 @@ impl Menu { } #[inline] - pub fn add_item(&mut self, item: &mut MenuItem) { + pub fn add_item(&mut self, item: &MenuItem) -> MenuItemHandle { self.0.add_item(item) } #[inline] - pub fn remove_item(&mut self, _item: &mut MenuItem) { - //self.0.remove_item(item) + pub fn remove_item(&mut self, item: &MenuItemHandle) { + self.0.remove_item(item) } } diff --git a/src/native/macosx/MacMiniFB.m b/src/native/macosx/MacMiniFB.m index db192c3..e5d97be 100644 --- a/src/native/macosx/MacMiniFB.m +++ b/src/native/macosx/MacMiniFB.m @@ -462,6 +462,8 @@ void* mfb_create_menu(const char* name) { //NSMenuItem* menu_item = [[NSMenuItem alloc] initWithTitle:name action:NULL keyEquivalent:@""]; NSMenu* menu = [[NSMenu alloc] initWithTitle:ns_name]; //[menu_item setSubmenu:menu]; + + //printf("created menu %p\n"); return (void*)menu; } @@ -475,5 +477,16 @@ void mfb_destroy_menu(void* menu_item, const char* name) [main_menu removeItem:item]; } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void mfb_remove_menu_item(void* parent, uint64_t menu_item) { + NSMenu* menu = (NSMenu*)parent; + NSMenuItem* item = (NSMenuItem*)(uintptr_t)menu_item; + + printf("remove item menu %p item %p\n", menu, item); + [menu removeItem:item]; +} + + diff --git a/src/native/macosx/OSXWindow.m b/src/native/macosx/OSXWindow.m index 2a3eec1..625c585 100644 --- a/src/native/macosx/OSXWindow.m +++ b/src/native/macosx/OSXWindow.m @@ -265,7 +265,7 @@ const uint32_t MENU_KEY_CTRL = 8; const uint32_t MENU_KEY_ALT = 16; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - +/* void build_submenu(NSMenu* menu, MenuDesc* desc) { [menu removeAllItems]; @@ -332,10 +332,11 @@ void build_submenu(NSMenu* menu, MenuDesc* desc) desc++; } } +*/ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void mfb_add_menu_item( +uint64_t mfb_add_menu_item( void* in_menu, int32_t menu_id, const char* item_name, @@ -345,7 +346,9 @@ void mfb_add_menu_item( { NSMenu* menu = (NSMenu*)in_menu; - NSString* name = [NSString stringWithUTF8String: item_name]; + const char* t = strdup(item_name); + + NSString* name = [NSString stringWithUTF8String: t]; if (menu_id == -1) { @@ -386,7 +389,11 @@ void mfb_add_menu_item( [newItem setOnStateImage: newItem.offStateImage]; [menu addItem:newItem]; [newItem release]; + + return (uint64_t)newItem; } + + return 0; } @end diff --git a/src/os/macos/mod.rs b/src/os/macos/mod.rs index cbb83cb..93c7dbb 100644 --- a/src/os/macos/mod.rs +++ b/src/os/macos/mod.rs @@ -8,7 +8,7 @@ use Result; use InputCallback; use mouse_handler; use window_flags; -use MenuItem; +use {MenuItem, MenuItemHandle}; //use menu::Menu; use libc::{c_void, c_char, c_uchar}; @@ -186,13 +186,14 @@ extern { //fn mfb_active_menu(window: *mut c_void) -> i32; fn mfb_create_menu(name: *const c_char) -> *mut c_void; - fn mfb_destroy_menu(menu_item: *mut c_void); + //fn mfb_destroy_menu(menu_item: *mut c_void); fn mfb_add_menu_item(menu_item: *mut c_void, menu_id: i32, name: *const c_char, key: u32, - modifier: u32) -> *mut c_void; + modifier: u32) -> u64; + fn mfb_remove_menu_item(menu: *mut c_void, item_handle: u64); } #[derive(Default)] @@ -391,45 +392,6 @@ impl Window { Ok(()) } - /* - - pub fn add_menu(&mut self, name: &str, menu: &Vec) -> Result<()> { - let mut build_menu = Vec::>::new(); - - unsafe { - Self::recursive_convert(&mut build_menu, &Some(menu)); - let menu_len = build_menu.len(); - mfb_add_menu(self.window_handle, - CString::new(name).unwrap().as_ptr(), - build_menu[menu_len - 1].as_mut_ptr() as *mut c_void); - } - - Ok(()) - } - - pub fn update_menu(&mut self, name: &str, menu: &Vec) -> Result<()> { - let mut build_menu = Vec::>::new(); - - unsafe { - Self::recursive_convert(&mut build_menu, &Some(menu)); - let menu_len = build_menu.len(); - mfb_update_menu(self.window_handle, - CString::new(name).unwrap().as_ptr(), - build_menu[menu_len - 1].as_mut_ptr() as *mut c_void); - } - - Ok(()) - } - - pub fn remove_menu(&mut self, name: &str) -> Result<()> { - unsafe { - mfb_remove_menu(self.window_handle, CString::new(name).unwrap().as_ptr()); - } - - Ok(()) - } - */ - #[inline] pub fn is_open(&self) -> bool { unsafe { mfb_should_close(self.window_handle) == 0 } @@ -474,7 +436,75 @@ impl Window { } /* - unsafe fn map_key_to_menu_key(key: Key) -> i32 { + */ + + /* + unsafe fn recursive_convert(menu_build_vec: &mut Vec>, in_menu: &Option<&Vec>) -> *mut raw::c_void { + if in_menu.is_none() { + return ptr::null_mut(); + } + + let mut menu_build = Vec::::new(); + let menu_vec = in_menu.as_ref().unwrap(); + + for m in menu_vec.iter() { + let key_map = Self::map_key_to_menu_key(m.key); + + let mut menu = CMenu { + name: mem::uninitialized(), + id: m.id as raw::c_int, + key: key_map as raw::c_int, + special_key: 0, + modifier: m.modifier as raw::c_int, + mac_mod: m.mac_mod as raw::c_int, + enabled: m.enabled as raw::c_int, + sub_menu : Self::recursive_convert(menu_build_vec, &m.sub_menu), + }; + + let name = CString::new(m.name).unwrap(); + let name_len = m.name.len(); + + ptr::copy_nonoverlapping(name.as_ptr(), + menu.name.as_mut_ptr() as *mut i8, + name_len); + menu.name[name_len] = 0; + + menu_build.push(menu); + } + + // end marker + + menu_build.push(CMenu { + name: [0; STRING_SIZE], + id: -2, + key: 0, + special_key: 0, + modifier: 0, + mac_mod: 0, + enabled: 0, + sub_menu : ptr::null_mut(), + }); + + let ptr = menu_build.as_mut_ptr() as *mut raw::c_void ; + menu_build_vec.push(menu_build); + ptr + } + */ +} + +pub struct Menu { + menu_handle: *mut c_void, +} + +impl Menu { + pub fn new(name: &str) -> Result { + unsafe { + let menu_name = CString::new(name).unwrap(); + Ok(Menu { menu_handle: mfb_create_menu(menu_name.as_ptr()) }) + } + } + + unsafe fn map_key_to_menu_key(key: Key) -> u32 { match key { Key::A => 0x00, Key::S => 0x01, @@ -584,140 +614,25 @@ impl Window { _ => 0x7f, } } - */ - /* - unsafe fn recursive_convert(menu_build_vec: &mut Vec>, in_menu: &Option<&Vec>) -> *mut raw::c_void { - if in_menu.is_none() { - return ptr::null_mut(); - } - - let mut menu_build = Vec::::new(); - let menu_vec = in_menu.as_ref().unwrap(); - - for m in menu_vec.iter() { - let key_map = Self::map_key_to_menu_key(m.key); - - let mut menu = CMenu { - name: mem::uninitialized(), - id: m.id as raw::c_int, - key: key_map as raw::c_int, - special_key: 0, - modifier: m.modifier as raw::c_int, - mac_mod: m.mac_mod as raw::c_int, - enabled: m.enabled as raw::c_int, - sub_menu : Self::recursive_convert(menu_build_vec, &m.sub_menu), - }; - - let name = CString::new(m.name).unwrap(); - let name_len = m.name.len(); - - ptr::copy_nonoverlapping(name.as_ptr(), - menu.name.as_mut_ptr() as *mut i8, - name_len); - menu.name[name_len] = 0; - - menu_build.push(menu); - } - - // end marker - - menu_build.push(CMenu { - name: [0; STRING_SIZE], - id: -2, - key: 0, - special_key: 0, - modifier: 0, - mac_mod: 0, - enabled: 0, - sub_menu : ptr::null_mut(), - }); - - let ptr = menu_build.as_mut_ptr() as *mut raw::c_void ; - menu_build_vec.push(menu_build); - ptr - } - */ -} - -pub struct Menu { - menu_handle: *mut c_void, -} - -impl Menu { - pub fn new(name: &str) -> Result { + pub fn add_item(&mut self, item: &MenuItem) -> MenuItemHandle { unsafe { - let menu_name = CString::new(name).unwrap().as_ptr(); - Ok(Menu { menu_handle: mfb_create_menu(menu_name) }) + let item_name = CString::new(item.label.as_str()).unwrap(); + let conv_key = Self::map_key_to_menu_key(item.key); + + println!("key {:?} conv {}", item.key, conv_key); + + MenuItemHandle(mfb_add_menu_item(self.menu_handle, item.id as i32, item_name.as_ptr(), + Self::map_key_to_menu_key(item.key), item.modifier)) } } - pub fn add_item(&mut self, item: &mut MenuItem) { + pub fn remove_item(&mut self, handle: &MenuItemHandle) { unsafe { - let item_name = CString::new(item.label.as_str()).unwrap().as_ptr(); - - mfb_add_menu_item(self.menu_handle, item.id as i32, item_name, - item.key as u32, item.modifier); - } - } - - /* - #[inline] - pub fn remove_item(&mut self, item: &mut MenuItem) { - self.0.remove_item(item) - } - */ -} - -/* -pub struct MenuItem { - id: usize, - label: String, - separator: bool, - key: Key, - modifier: u32, - impl_handle: u64, -} - -impl MenuItem { - pub fn new(name: &str, id: usize) -> MenuItem { - MenuItem { - id: id, - label: "".to_owned(), - enabled: true, - separator: false, - key: Key::Unknown, - modifier: 0, - impl_handle: 0, - } - } - #[inline] - pub fn shortcut(self, key: Key, modifier: u32) -> Self { - MenuItem { - shortcut: key, - modifier: modifier, - .. self - } - } - #[inline] - pub fn separator(self, enabled: bool) -> Self { - MenuItem { - id: 0xffffffff, - .. self - } - } - #[inline] - pub fn enabled(self, enabled: bool) -> Self { - MenuItem { - enabled: enabled, - .. self + mfb_remove_menu_item(self.menu_handle, handle.0); } } } -*/ - - - impl Drop for Window { fn drop(&mut self) { @@ -727,6 +642,7 @@ impl Drop for Window { } } +/* impl Drop for Menu { fn drop(&mut self) { unsafe { @@ -734,6 +650,7 @@ impl Drop for Menu { } } } +*/