use std::sync::Once;
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use crate::appkit::toolbar::{ToolbarDelegate, TOOLBAR_PTR};
use crate::foundation::{id, load_or_register_class, NSArray, NSString, BOOL};
use crate::utils::load;
extern "C" fn allowed_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar
.allowed_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
.into();
identifiers.into()
}
extern "C" fn default_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar
.default_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
.into();
identifiers.into()
}
extern "C" fn selectable_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar
.selectable_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
.into();
identifiers.into()
}
extern "C" fn item_for_identifier<T: ToolbarDelegate>(this: &Object, _: Sel, _: id, identifier: id, _: BOOL) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifier = NSString::from_retained(identifier);
let item = toolbar.item_for(identifier.to_str());
unsafe { msg_send![&*item.objc, self] }
}
pub(crate) fn register_toolbar_class<T: ToolbarDelegate>(instance: &T) -> *const Class {
load_or_register_class("NSObject", instance.subclass_name(), |decl| unsafe {
decl.add_ivar::<usize>(TOOLBAR_PTR);
decl.add_method(
sel!(toolbarAllowedItemIdentifiers:),
allowed_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbarDefaultItemIdentifiers:),
default_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbarSelectableItemIdentifiers:),
selectable_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:),
item_for_identifier::<T> as extern "C" fn(&Object, _, _, _, _) -> id
);
})
}