Missing files from last commit, whoops. Also begin the long arduous process of bringing in NSNotificationName. Just end me now.
This commit is contained in:
parent
ba59b06177
commit
784727748c
|
@ -20,6 +20,9 @@
|
||||||
//use objc::runtime::Object;
|
//use objc::runtime::Object;
|
||||||
//use objc_id::ShareId;
|
//use objc_id::ShareId;
|
||||||
|
|
||||||
|
mod name;
|
||||||
|
pub use name::NotificationName;
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
pub use traits::Dispatcher;
|
pub use traits::Dispatcher;
|
||||||
|
|
||||||
|
|
1321
src/notification_center/name.rs
Normal file
1321
src/notification_center/name.rs
Normal file
File diff suppressed because it is too large
Load diff
72
src/view/controller/ios.rs
Normal file
72
src/view/controller/ios.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
use std::sync::Once;
|
||||||
|
use std::unreachable;
|
||||||
|
|
||||||
|
use objc::declare::ClassDecl;
|
||||||
|
use objc::runtime::{Class, Object, Sel};
|
||||||
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::foundation::{BOOL};
|
||||||
|
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||||
|
use crate::utils::{load, as_bool};
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewWillAppear:` message.
|
||||||
|
extern fn will_appear<T: ViewDelegate>(this: &mut Object, _: Sel, animated: BOOL) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(UIViewController)), viewWillAppear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.will_appear(as_bool(animated));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewDidAppear:` message.
|
||||||
|
extern fn did_appear<T: ViewDelegate>(this: &mut Object, _: Sel, animated: BOOL) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(UIViewController)), viewDidAppear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.did_appear(as_bool(animated));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewWillDisappear:` message.
|
||||||
|
extern fn will_disappear<T: ViewDelegate>(this: &mut Object, _: Sel, animated: BOOL) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(UIViewController)), viewWillDisappear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.will_disappear(as_bool(animated));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewDidDisappear:` message.
|
||||||
|
extern fn did_disappear<T: ViewDelegate>(this: &mut Object, _: Sel, animated: BOOL) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(UIViewController)), viewDidDisappear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.did_disappear(as_bool(animated));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers an `NSViewDelegate`.
|
||||||
|
pub(crate) fn register_view_controller_class<T: ViewDelegate + 'static>() -> *const Class {
|
||||||
|
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
INIT.call_once(|| unsafe {
|
||||||
|
let superclass = class!(UIViewController);
|
||||||
|
let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap();
|
||||||
|
|
||||||
|
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
decl.add_method(sel!(viewWillAppear:), will_appear::<T> as extern fn(&mut Object, _, BOOL));
|
||||||
|
decl.add_method(sel!(viewDidAppear:), did_appear::<T> as extern fn(&mut Object, _, BOOL));
|
||||||
|
decl.add_method(sel!(viewWillDisappear:), will_disappear::<T> as extern fn(&mut Object, _, BOOL));
|
||||||
|
decl.add_method(sel!(viewDidDisappear:), did_disappear::<T> as extern fn(&mut Object, _, BOOL));
|
||||||
|
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe { VIEW_CLASS }
|
||||||
|
}
|
73
src/view/controller/macos.rs
Normal file
73
src/view/controller/macos.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
//! Hoists a basic `NSViewController`.
|
||||||
|
|
||||||
|
use std::sync::Once;
|
||||||
|
|
||||||
|
use objc::declare::ClassDecl;
|
||||||
|
use objc::runtime::{Class, Object, Sel};
|
||||||
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||||
|
use crate::utils::load;
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewWillAppear` message.
|
||||||
|
extern fn will_appear<T: ViewDelegate>(this: &mut Object, _: Sel) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(NSViewController)), viewWillAppear];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.will_appear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewDidAppear` message.
|
||||||
|
extern fn did_appear<T: ViewDelegate>(this: &mut Object, _: Sel) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(NSViewController)), viewDidAppear];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.did_appear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewWillDisappear` message.
|
||||||
|
extern fn will_disappear<T: ViewDelegate>(this: &mut Object, _: Sel) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(NSViewController)), viewWillDisappear];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.will_disappear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the view controller receives a `viewDidDisappear` message.
|
||||||
|
extern fn did_disappear<T: ViewDelegate>(this: &mut Object, _: Sel) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![super(this, class!(NSViewController)), viewDidDisappear];
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
controller.did_disappear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers an `NSViewDelegate`.
|
||||||
|
pub(crate) fn register_view_controller_class<T: ViewDelegate + 'static>() -> *const Class {
|
||||||
|
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
INIT.call_once(|| unsafe {
|
||||||
|
let superclass = class!(NSViewController);
|
||||||
|
let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap();
|
||||||
|
|
||||||
|
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
// NSViewDelegate
|
||||||
|
decl.add_method(sel!(viewWillAppear), will_appear::<T> as extern fn(&mut Object, _));
|
||||||
|
decl.add_method(sel!(viewDidAppear), did_appear::<T> as extern fn(&mut Object, _));
|
||||||
|
decl.add_method(sel!(viewWillDisappear), will_disappear::<T> as extern fn(&mut Object, _));
|
||||||
|
decl.add_method(sel!(viewDidDisappear), did_disappear::<T> as extern fn(&mut Object, _));
|
||||||
|
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe { VIEW_CLASS }
|
||||||
|
}
|
45
src/view/ios.rs
Normal file
45
src/view/ios.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use std::sync::Once;
|
||||||
|
|
||||||
|
use objc::declare::ClassDecl;
|
||||||
|
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||||
|
use objc::{class, sel, sel_impl};
|
||||||
|
use objc_id::Id;
|
||||||
|
|
||||||
|
use crate::foundation::{id, YES, NO, NSUInteger};
|
||||||
|
use crate::dragdrop::DragInfo;
|
||||||
|
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||||
|
use crate::utils::load;
|
||||||
|
|
||||||
|
/// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we
|
||||||
|
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||||
|
/// used if there's no delegates.
|
||||||
|
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!(UIView);
|
||||||
|
let mut decl = ClassDecl::new("RSTView", superclass).unwrap();
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe { VIEW_CLASS }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||||
|
/// need to do.
|
||||||
|
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Class {
|
||||||
|
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
INIT.call_once(|| unsafe {
|
||||||
|
let superclass = class!(UIView);
|
||||||
|
let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap();
|
||||||
|
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
VIEW_CLASS
|
||||||
|
}
|
||||||
|
}
|
125
src/view/macos.rs
Normal file
125
src/view/macos.rs
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
//! 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 objc::declare::ClassDecl;
|
||||||
|
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||||
|
use objc::{class, sel, sel_impl};
|
||||||
|
use objc_id::Id;
|
||||||
|
|
||||||
|
use crate::foundation::{id, YES, NO, NSUInteger};
|
||||||
|
use crate::dragdrop::DragInfo;
|
||||||
|
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||||
|
use crate::utils::load;
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when a drag/drop operation has entered this view.
|
||||||
|
extern fn dragging_entered<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
|
||||||
|
let view = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
view.dragging_entered(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
}).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when a drag/drop operation has entered this view.
|
||||||
|
extern fn prepare_for_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
||||||
|
let view = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
match view.prepare_for_drag_operation(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
}) {
|
||||||
|
true => YES,
|
||||||
|
false => NO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when a drag/drop operation has entered this view.
|
||||||
|
extern fn perform_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
|
||||||
|
let view = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
match view.perform_drag_operation(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
}) {
|
||||||
|
true => YES,
|
||||||
|
false => NO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when a drag/drop operation has entered this view.
|
||||||
|
extern fn conclude_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
|
||||||
|
let view = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
view.conclude_drag_operation(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when a drag/drop operation has entered this view.
|
||||||
|
extern fn dragging_exited<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
|
||||||
|
let view = load::<T>(this, VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
view.dragging_exited(DragInfo {
|
||||||
|
info: unsafe { Id::from_ptr(info) }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we
|
||||||
|
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||||
|
/// used if there's no delegates.
|
||||||
|
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!(NSView);
|
||||||
|
let mut decl = ClassDecl::new("RSTView", superclass).unwrap();
|
||||||
|
|
||||||
|
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
||||||
|
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe { VIEW_CLASS }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||||
|
/// need to do.
|
||||||
|
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Class {
|
||||||
|
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
INIT.call_once(|| unsafe {
|
||||||
|
let superclass = class!(NSView);
|
||||||
|
let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap();
|
||||||
|
|
||||||
|
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||||
|
// move.
|
||||||
|
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||||
|
|
||||||
|
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
||||||
|
|
||||||
|
// Drag and drop operations (e.g, accepting files)
|
||||||
|
decl.add_method(sel!(draggingEntered:), dragging_entered::<T> as extern fn (&mut Object, _, _) -> NSUInteger);
|
||||||
|
decl.add_method(sel!(prepareForDragOperation:), prepare_for_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
|
||||||
|
decl.add_method(sel!(performDragOperation:), perform_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
|
||||||
|
decl.add_method(sel!(concludeDragOperation:), conclude_drag_operation::<T> as extern fn (&mut Object, _, _));
|
||||||
|
decl.add_method(sel!(draggingExited:), dragging_exited::<T> as extern fn (&mut Object, _, _));
|
||||||
|
|
||||||
|
VIEW_CLASS = decl.register();
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
VIEW_CLASS
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue