//! This module does one specific thing: register a custom `NSView` class that's... brought to the //! modern era. //! //! I kid, I kid. //! //! It just enforces that coordinates are judged from the top-left, which is what most people look //! for in the modern era. It also implements a few helpers for things like setting a background //! color, and enforcing layer backing by default. use std::sync::Once; use cocoa::base::{id, nil, YES}; use objc::declare::ClassDecl; use objc::runtime::{Class, Object, Sel, BOOL}; use objc::{class, msg_send, sel, sel_impl}; /// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though. extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL { return YES; } extern fn update_layer(this: &Object, _: Sel) { unsafe { let background_color: id = msg_send![class!(NSColor), redColor]; if background_color != nil { let layer: id = msg_send![this, layer]; let cg: id = msg_send![background_color, CGColor]; let _: () = msg_send![layer, setBackgroundColor:cg]; } } } /// Injects an `NSView` subclass, with some callback and pointer ivars for what we /// need to do. pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = Class::get("NSView").unwrap(); let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL); decl.add_method(sel!(requiresConstraintBasedLayout), enforce_normalcy as extern fn(&Object, _) -> BOOL); decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern fn(&Object, _) -> BOOL); decl.add_method(sel!(updateLayer), update_layer as extern fn(&Object, _)); VIEW_CLASS = decl.register(); }); unsafe { VIEW_CLASS } }