89 lines
2.9 KiB
Rust
89 lines
2.9 KiB
Rust
|
|
use objc::runtime::Object;
|
|
use objc::{msg_send, sel, sel_impl};
|
|
use objc_id::ShareId;
|
|
|
|
use crate::foundation::{id, nil};
|
|
use crate::layout::traits::Layout;
|
|
use crate::window::{Window, WindowConfig, WindowDelegate, WINDOW_DELEGATE_PTR};
|
|
|
|
mod class;
|
|
use class::register_window_controller_class;
|
|
|
|
/// A `Window` represents your way of interacting with an `NSWindow`. It wraps the various moving
|
|
/// pieces to enable you to focus on reacting to lifecycle methods and doing your thing.
|
|
pub struct WindowController<T> {
|
|
pub objc: ShareId<Object>,
|
|
pub window: Window<T>
|
|
}
|
|
|
|
impl<T> WindowController<T> where T: WindowDelegate + 'static {
|
|
/// Allocates and configures an `NSWindowController` in the Objective-C/Cocoa runtime that maps over
|
|
/// to your supplied delegate.
|
|
pub fn with(config: WindowConfig, delegate: T) -> Self {
|
|
let mut window = Window::with(config, delegate);
|
|
|
|
let objc = unsafe {
|
|
let window_controller_class = register_window_controller_class::<T>();
|
|
let controller_alloc: id = msg_send![window_controller_class, alloc];
|
|
let controller: id = msg_send![controller_alloc, initWithWindow:&*window.objc];
|
|
|
|
if let Some(ptr) = window.internal_callback_ptr {
|
|
(&mut *controller).set_ivar(WINDOW_DELEGATE_PTR, ptr as usize);
|
|
}
|
|
|
|
ShareId::from_ptr(controller)
|
|
};
|
|
|
|
if let Some(window_delegate) = &mut window.delegate {
|
|
let mut window_delegate = window_delegate.borrow_mut();
|
|
|
|
(*window_delegate).did_load(Window {
|
|
internal_callback_ptr: None,
|
|
delegate: None,
|
|
objc: window.objc.clone()
|
|
});
|
|
}
|
|
|
|
WindowController {
|
|
objc: objc,
|
|
window: window
|
|
}
|
|
}
|
|
|
|
/// Sets the content view controller for the window.
|
|
pub fn set_content_view_controller<VC: Layout + 'static>(&self, view_controller: &VC) {
|
|
//self.objc_controller.set_content_view_controller(view_controller);
|
|
}
|
|
|
|
/// Shows the window, running a configuration pass if necessary.
|
|
pub fn show(&self) {
|
|
unsafe {
|
|
let _: () = msg_send![&*self.objc, showWindow:nil];
|
|
}
|
|
}
|
|
|
|
/// Closes the window.
|
|
pub fn close(&self) {
|
|
unsafe {
|
|
let _: () = msg_send![&*self.objc, close];
|
|
}
|
|
}
|
|
}
|
|
|
|
/*impl<T> Drop for Window<T> {
|
|
/// When a Window is dropped on the Rust side, we want to ensure that we break the delegate
|
|
/// link on the Objective-C side. While this shouldn't actually be an issue, I'd rather be
|
|
/// safer than sorry.
|
|
///
|
|
/// We also clean up our loopback pointer that we use for callbacks.
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
let window: id = msg_send![*objc_controller, window];
|
|
let _: () = msg_send![window, setDelegate:nil];
|
|
|
|
let _ = Rc::from_raw(self.internal_callback_ptr);
|
|
}
|
|
}
|
|
}*/
|