2020-02-28 13:34:34 +11:00
|
|
|
//! 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;
|
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
use cocoa::base::{id, nil, YES};
|
2020-02-28 13:34:34 +11:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|