cacao/appkit/menu/menu.rs

53 lines
1.6 KiB
Rust

//! Wraps NSMenu and handles instrumenting necessary delegate pieces.
use objc_id::Id;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::{id, NSString};
use crate::menu::item::MenuItem;
/// A struct that represents an `NSMenu`. It takes ownership of items, and handles instrumenting
/// them throughout the application lifecycle.
#[derive(Debug)]
pub struct Menu {
pub inner: Id<Object>,
pub items: Vec<MenuItem>
}
impl Menu {
/// Creates a new `Menu` with the given title, and uses the passed items as submenu items.
pub fn new(title: &str, items: Vec<MenuItem>) -> Self {
let inner = unsafe {
let cls = class!(NSMenu);
let alloc: id = msg_send![cls, alloc];
let title = NSString::new(title);
let inner: id = msg_send![alloc, initWithTitle:title];
Id::from_ptr(inner)
};
for item in items.iter() {
match item {
MenuItem::Action(item) => {
unsafe {
let _: () = msg_send![&*inner, addItem:item.clone()];
}
},
MenuItem::Separator => {
unsafe {
let cls = class!(NSMenuItem);
let separator: id = msg_send![cls, separatorItem];
let _: () = msg_send![&*inner, addItem:separator];
}
}
}
}
Menu {
inner: inner,
items: items
}
}
}