use super::*;
use crate::wrappers::appkit::new_class_name;
use objc2::__framework_prelude::{AnyClass, AnyObject, Bool, Sel};
use objc2::ffi::objc_disposeClassPair;
use objc2::runtime::ClassBuilder;
use objc2::{msg_send, sel, ClassType};
use objc2_app_kit::{NSEvent, NSView};
use std::ffi::c_void;
pub unsafe fn create_view_class<V: ViewImpl>() -> &'static AnyClass {
let class_name = new_class_name("BaseviewNSView_");
let mut class = ClassBuilder::new(&class_name, NSView::class()).unwrap();
unsafe {
class.add_method(
sel!(acceptsFirstResponder),
property_yes as extern "C-unwind" fn(_, _) -> _,
);
class.add_method(
sel!(becomeFirstResponder),
become_first_responder::<V> as extern "C-unwind" fn(_, _) -> _,
);
class.add_method(
sel!(resignFirstResponder),
resign_first_responder::<V> as extern "C-unwind" fn(_, _) -> _,
);
class.add_method(sel!(isFlipped), property_yes as extern "C-unwind" fn(_, _) -> _);
class.add_method(
sel!(preservesContentInLiveResize),
property_no as extern "C-unwind" fn(_, _) -> _,
);
class.add_method(
sel!(acceptsFirstMouse:),
accepts_first_mouse as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(windowShouldClose:),
window_should_close::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(sel!(dealloc), dealloc::<V> as extern "C-unwind" fn(_, _));
class.add_method(
sel!(viewWillMoveToWindow:),
view_will_move_to_window::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(sel!(hitTest:), hit_test::<V> as extern "C-unwind" fn(_, _, _) -> _);
class.add_method(
sel!(updateTrackingAreas:),
update_tracking_areas::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(sel!(mouseMoved:), mouse_moved::<V> as extern "C-unwind" fn(_, _, _) -> _);
class.add_method(
sel!(mouseDragged:),
mouse_moved::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(rightMouseDragged:),
mouse_moved::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(otherMouseDragged:),
mouse_moved::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(scrollWheel:),
scroll_wheel::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(viewDidChangeBackingProperties:),
view_did_change_backing_properties::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(draggingEntered:),
dragging_entered::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(performDragOperation:),
perform_drag_operation::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(draggingUpdated:),
dragging_updated::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(draggingExited:),
dragging_exited::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(
sel!(handleNotification:),
handle_notification::<V> as extern "C-unwind" fn(_, _, _) -> _,
);
class.add_method(sel!(mouseDown:), mouse_down::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(mouseUp:), mouse_up::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(
sel!(rightMouseDown:),
right_mouse_down::<V> as extern "C-unwind" fn(_, _, _),
);
class.add_method(sel!(rightMouseUp:), right_mouse_up::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(
sel!(otherMouseDown:),
other_mouse_down::<V> as extern "C-unwind" fn(_, _, _),
);
class.add_method(sel!(otherMouseUp:), other_mouse_up::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(mouseEntered:), mouse_entered::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(mouseExited:), mouse_exited::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(keyDown:), key_down::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(keyUp:), key_up::<V> as extern "C-unwind" fn(_, _, _));
class.add_method(sel!(flagsChanged:), flags_changed::<V> as extern "C-unwind" fn(_, _, _));
}
class.add_ivar::<*mut c_void>(BASEVIEW_STATE_IVAR);
class.register()
}
pub extern "C-unwind" fn dealloc<V: ViewImpl>(this: &mut AnyObject, _sel: Sel) {
let class = this.class();
View::<V>::free_inner(this, class);
if let Some(superclass) = class.superclass() {
let () = unsafe { msg_send![super(this, superclass), dealloc] };
}
unsafe { objc_disposeClassPair(class as *const _ as *mut _) }
}
extern "C-unwind" fn property_yes(_this: &NSView, _sel: Sel) -> Bool {
Bool::YES
}
extern "C-unwind" fn property_no(_this: &NSView, _sel: Sel) -> Bool {
Bool::NO
}
extern "C-unwind" fn accepts_first_mouse(_this: &NSView, _sel: Sel, _event: &NSEvent) -> Bool {
Bool::YES
}
extern "C-unwind" fn become_first_responder<V: ViewImpl>(this: &View<V>, _sel: Sel) -> Bool {
V::become_first_responder(this.inner_ref()).into()
}
extern "C-unwind" fn resign_first_responder<V: ViewImpl>(this: &View<V>, _sel: Sel) -> Bool {
V::resign_first_responder(this.inner_ref()).into()
}
extern "C-unwind" fn window_should_close<V: ViewImpl>(
this: &View<V>, _: Sel, _sender: &AnyObject,
) -> Bool {
V::window_should_close(this.inner_ref()).into()
}
extern "C-unwind" fn view_did_change_backing_properties<V: ViewImpl>(
this: &View<V>, _: Sel, _: &AnyObject,
) {
V::view_did_change_backing_properties(this.inner_ref());
}
extern "C-unwind" fn hit_test<V: ViewImpl>(
this: &View<V>, _sel: Sel, point: NSPoint,
) -> Option<&NSView> {
V::hit_test(this.inner_ref(), point)
}
extern "C-unwind" fn view_will_move_to_window<V: ViewImpl>(
this: &View<V>, _self: Sel, new_window: Option<&NSWindow>,
) {
V::view_will_move_to_window(this.inner_ref(), new_window);
}
extern "C-unwind" fn update_tracking_areas<V: ViewImpl>(this: &View<V>, _self: Sel, _: &AnyObject) {
V::update_tracking_areas(this.inner_ref());
}
extern "C-unwind" fn mouse_moved<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::mouse_moved(this.inner_ref(), event);
}
extern "C-unwind" fn scroll_wheel<V: ViewImpl>(this: &View<V>, _: Sel, event: &NSEvent) {
V::scroll_wheel(this.inner_ref(), event);
}
extern "C-unwind" fn dragging_entered<V: ViewImpl>(
this: &View<V>, _sel: Sel, sender: Option<&ProtocolObject<dyn NSDraggingInfo>>,
) -> NSDragOperation {
V::dragging_entered(this.inner_ref(), sender)
}
extern "C-unwind" fn dragging_updated<V: ViewImpl>(
this: &View<V>, _sel: Sel, sender: Option<&ProtocolObject<dyn NSDraggingInfo>>,
) -> NSDragOperation {
V::dragging_updated(this.inner_ref(), sender)
}
extern "C-unwind" fn prepare_for_drag_operation<V: ViewImpl>(
this: &View<V>, _sel: Sel, sender: Option<&ProtocolObject<dyn NSDraggingInfo>>,
) -> Bool {
V::prepare_for_drag_operation(this.inner_ref(), sender).into()
}
extern "C-unwind" fn perform_drag_operation<V: ViewImpl>(
this: &View<V>, _sel: Sel, sender: Option<&ProtocolObject<dyn NSDraggingInfo>>,
) -> Bool {
V::perform_drag_operation(this.inner_ref(), sender).into()
}
extern "C-unwind" fn dragging_exited<V: ViewImpl>(
this: &View<V>, _sel: Sel, sender: Option<&ProtocolObject<dyn NSDraggingInfo>>,
) {
V::dragging_exited(this.inner_ref(), sender)
}
extern "C-unwind" fn handle_notification<V: ViewImpl>(
this: &View<V>, _cmd: Sel, notification: &NSNotification,
) {
V::handle_notification(this.inner_ref(), notification)
}
extern "C-unwind" fn mouse_entered<V: ViewImpl>(this: &View<V>, _: Sel, _: &AnyObject) {
V::mouse_entered(this.inner_ref());
}
extern "C-unwind" fn mouse_exited<V: ViewImpl>(this: &View<V>, _: Sel, _: &AnyObject) {
V::mouse_exited(this.inner_ref());
}
extern "C-unwind" fn key_down<V: ViewImpl>(this: &View<V>, _: Sel, event: &NSEvent) {
V::key_down(this.inner_ref(), event);
}
extern "C-unwind" fn key_up<V: ViewImpl>(this: &View<V>, _: Sel, event: &NSEvent) {
V::key_up(this.inner_ref(), event);
}
extern "C-unwind" fn flags_changed<V: ViewImpl>(this: &View<V>, _: Sel, event: &NSEvent) {
V::flags_changed(this.inner_ref(), event);
}
extern "C-unwind" fn mouse_down<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::mouse_down(this.inner_ref(), event);
}
extern "C-unwind" fn mouse_up<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::mouse_up(this.inner_ref(), event);
}
extern "C-unwind" fn right_mouse_down<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::right_mouse_down(this.inner_ref(), event);
}
extern "C-unwind" fn right_mouse_up<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::right_mouse_up(this.inner_ref(), event);
}
extern "C-unwind" fn other_mouse_down<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::other_mouse_down(this.inner_ref(), event);
}
extern "C-unwind" fn other_mouse_up<V: ViewImpl>(this: &View<V>, _sel: Sel, event: &NSEvent) {
V::other_mouse_up(this.inner_ref(), event);
}