Clean up warnings, finish moving View/ViewController to new paradigm, general cleanup - need to rewrite docs
This commit is contained in:
parent
fc53848ba2
commit
c1da7b1b37
|
@ -5,7 +5,6 @@
|
|||
use std::sync::Once;
|
||||
|
||||
use objc::class;
|
||||
//, msg_send, sel, sel_impl};
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class};
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ use objc::runtime::{Class, Object, Sel};
|
|||
|
||||
use url::Url;
|
||||
|
||||
use crate::foundation::{id, nil, BOOL, YES, NO, NSUInteger, NSArray, NSString};
|
||||
use crate::app::APP_PTR;
|
||||
use crate::app::traits::AppDelegate;
|
||||
use crate::constants::APP_PTR;
|
||||
use crate::error::AppKitError;
|
||||
use crate::foundation::{id, nil, BOOL, YES, NO, NSUInteger, NSArray, NSString};
|
||||
use crate::printing::PrintSettings;
|
||||
use crate::user_activity::UserActivity;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use objc::runtime::Object;
|
|||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
||||
use crate::foundation::{id, YES, NO, NSUInteger, AutoReleasePool};
|
||||
use crate::constants::APP_PTR;
|
||||
use crate::menu::Menu;
|
||||
|
||||
mod class;
|
||||
|
@ -21,6 +20,8 @@ pub use enums::AppDelegateResponse;
|
|||
pub mod traits;
|
||||
pub use traits::{AppDelegate, Dispatcher};
|
||||
|
||||
pub(crate) static APP_PTR: &str = "rstAppPtr";
|
||||
|
||||
/// A handler to make some boilerplate less annoying.
|
||||
#[inline]
|
||||
fn shared_application<F: Fn(id)>(handler: F) {
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
//! Constants typically used for referencing around in the Objective-C runtime.
|
||||
//! Specific to this crate.
|
||||
|
||||
pub(crate) static APP_PTR: &str = "rstAppPtr";
|
||||
pub(crate) static BACKGROUND_COLOR: &str = "rstBackgroundColor";
|
||||
pub(crate) static TOOLBAR_PTR: &str = "rstToolbarPtr";
|
||||
pub(crate) static VIEW_DELEGATE_PTR: &str = "rstViewDelegatePtr";
|
||||
|
||||
#[cfg(feature = "webview")]
|
||||
pub(crate) static WEBVIEW_CONFIG_VAR: &str = "rstWebViewConfig";
|
||||
|
|
|
@ -6,6 +6,13 @@ use std::rc::Rc;
|
|||
use std::cell::RefCell;
|
||||
|
||||
use objc::runtime::Object;
|
||||
use objc_id::ShareId;
|
||||
|
||||
/// A generic trait that's used throughout multiple different controls in this framework - acts as
|
||||
/// a guard for whether something is a (View|etc)Controller. Only needs to return the backing node.
|
||||
pub trait Controller {
|
||||
fn get_backing_node(&self) -> ShareId<Object>;
|
||||
}
|
||||
|
||||
/// Used for moving a pointer back into an Rc, so we can work with the object held behind it. Note
|
||||
/// that it's very important to make sure you reverse this when you're done (using
|
||||
|
|
|
@ -12,13 +12,12 @@ use std::sync::Once;
|
|||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc::{class, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::foundation::{id, nil, YES, NO, NSUInteger};
|
||||
use crate::constants::{BACKGROUND_COLOR, VIEW_DELEGATE_PTR};
|
||||
use crate::foundation::{id, YES, NO, NSUInteger};
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::view::traits::ViewDelegate;
|
||||
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.
|
||||
|
@ -26,19 +25,6 @@ extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
|
|||
return YES;
|
||||
}
|
||||
|
||||
/// Used for handling background colors in layer backed views (which is the default here).
|
||||
/// @TODO: This could be more efficient, I think.
|
||||
extern fn update_layer(this: &Object, _: Sel) {
|
||||
unsafe {
|
||||
let background_color: id = *this.get_ivar(BACKGROUND_COLOR);
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
@ -132,10 +118,7 @@ pub(crate) fn register_view_class() -> *const Class {
|
|||
let superclass = class!(NSView);
|
||||
let mut decl = ClassDecl::new("RSTView", superclass).unwrap();
|
||||
|
||||
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||
decl.add_method(sel!(isFlipped), 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();
|
||||
});
|
||||
|
@ -156,11 +139,8 @@ pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Cla
|
|||
// 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_ivar::<id>(BACKGROUND_COLOR);
|
||||
|
||||
decl.add_method(sel!(isFlipped), 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, _));
|
||||
|
||||
// Drag and drop operations (e.g, accepting files)
|
||||
decl.add_method(sel!(draggingEntered:), dragging_entered::<T> as extern fn (&mut Object, _, _) -> NSUInteger);
|
||||
|
|
|
@ -7,8 +7,7 @@ use objc::declare::ClassDecl;
|
|||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, sel, sel_impl};
|
||||
|
||||
use crate::constants::VIEW_DELEGATE_PTR;
|
||||
use crate::view::traits::ViewDelegate;
|
||||
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||
use crate::utils::load;
|
||||
|
||||
/// Called when the view controller receives a `viewWillAppear` message.
|
||||
|
|
|
@ -1,36 +1,42 @@
|
|||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use objc_id::ShareId;
|
||||
use objc::runtime::Object;
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
|
||||
use crate::foundation::{id, NO};
|
||||
use crate::constants::VIEW_DELEGATE_PTR;
|
||||
use crate::foundation::id;
|
||||
use crate::layout::{Layout};
|
||||
use crate::view::traits::ViewDelegate;
|
||||
use crate::view::{VIEW_DELEGATE_PTR, View, ViewDelegate};
|
||||
|
||||
mod class;
|
||||
use class::register_view_controller_class;
|
||||
|
||||
//#[derive(Debug)]
|
||||
pub struct ViewController {
|
||||
pub struct ViewController<T> {
|
||||
pub objc: ShareId<Object>,
|
||||
pub view: Box<dyn ViewDelegate>
|
||||
pub view: View<T>
|
||||
}
|
||||
|
||||
impl ViewController {
|
||||
pub fn new<T: ViewDelegate + Layout + 'static>(view: T) -> Self {
|
||||
let view = Box::new(view);
|
||||
impl<T> ViewController<T> where T: ViewDelegate + 'static {
|
||||
pub fn new(delegate: T) -> Self {
|
||||
let mut view = View::with(delegate);
|
||||
|
||||
let objc = unsafe {
|
||||
let vc: id = msg_send![register_view_controller_class::<T>(), new];
|
||||
|
||||
if let Some(ptr)= view.internal_callback_ptr {
|
||||
(&mut *vc).set_ivar(VIEW_DELEGATE_PTR, ptr as usize);
|
||||
}
|
||||
|
||||
let _: () = msg_send![vc, setView:&*view.get_backing_node()];
|
||||
let ptr: *const T = &*view;
|
||||
(&mut *vc).set_ivar(VIEW_DELEGATE_PTR, ptr as usize);
|
||||
|
||||
ShareId::from_ptr(vc)
|
||||
};
|
||||
|
||||
let handle = view.clone_as_handle();
|
||||
if let Some(view_delegate) = &mut view.delegate {
|
||||
let mut view_delegate = view_delegate.borrow_mut();
|
||||
(*view_delegate).did_load(handle);
|
||||
}
|
||||
|
||||
ViewController {
|
||||
objc: objc,
|
||||
view: view
|
||||
|
|
|
@ -14,7 +14,6 @@ use objc::{msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, YES, NO, NSArray, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::constants::{BACKGROUND_COLOR, VIEW_DELEGATE_PTR};
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::pasteboard::PasteboardType;
|
||||
|
||||
|
@ -27,6 +26,8 @@ pub use controller::ViewController;
|
|||
pub mod traits;
|
||||
pub use traits::ViewDelegate;
|
||||
|
||||
pub(crate) static VIEW_DELEGATE_PTR: &str = "rstViewDelegatePtr";
|
||||
|
||||
/// A clone-able handler to a `ViewController` reference in the Objective C runtime. We use this
|
||||
/// instead of a stock `View` for easier recordkeeping, since it'll need to hold the `View` on that
|
||||
/// side anyway.
|
||||
|
@ -37,7 +38,7 @@ pub struct View<T = ()> {
|
|||
|
||||
/// An internal callback pointer that we use in delegate loopbacks. Default implementations
|
||||
/// don't require this.
|
||||
internal_callback_ptr: Option<*const RefCell<T>>,
|
||||
pub(crate) internal_callback_ptr: Option<*const RefCell<T>>,
|
||||
|
||||
/// A pointer to the delegate for this view.
|
||||
pub delegate: Option<Rc<RefCell<T>>>,
|
||||
|
@ -133,19 +134,7 @@ impl<T> View<T> where T: ViewDelegate + 'static {
|
|||
|
||||
{
|
||||
let mut delegate = delegate.borrow_mut();
|
||||
(*delegate).did_load(View {
|
||||
internal_callback_ptr: None,
|
||||
delegate: None,
|
||||
top: view.top.clone(),
|
||||
leading: view.leading.clone(),
|
||||
trailing: view.trailing.clone(),
|
||||
bottom: view.bottom.clone(),
|
||||
width: view.width.clone(),
|
||||
height: view.height.clone(),
|
||||
center_x: view.center_x.clone(),
|
||||
center_y: view.center_y.clone(),
|
||||
objc: view.objc.clone()
|
||||
});
|
||||
(*delegate).did_load(view.clone_as_handle());
|
||||
}
|
||||
|
||||
view.delegate = Some(delegate);
|
||||
|
@ -154,6 +143,26 @@ impl<T> View<T> where T: ViewDelegate + 'static {
|
|||
}
|
||||
|
||||
impl<T> View<T> {
|
||||
/// An internal method that returns a clone of this object, sans references to the delegate or
|
||||
/// callback pointer. We use this in calling `did_load()` - implementing delegates get a way to
|
||||
/// reference, customize and use the view but without the trickery of holding pieces of the
|
||||
/// delegate - the `View` is the only true holder of those.
|
||||
pub(crate) fn clone_as_handle(&self) -> View {
|
||||
View {
|
||||
internal_callback_ptr: None,
|
||||
delegate: None,
|
||||
top: self.top.clone(),
|
||||
leading: self.leading.clone(),
|
||||
trailing: self.trailing.clone(),
|
||||
bottom: self.bottom.clone(),
|
||||
width: self.width.clone(),
|
||||
height: self.height.clone(),
|
||||
center_x: self.center_x.clone(),
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this to set the background color for the backing layer.
|
||||
pub fn set_background_color(&self, color: Color) {
|
||||
let bg = color.into_platform_specific_color();
|
||||
|
@ -162,9 +171,6 @@ impl<T> View<T> {
|
|||
let cg: id = msg_send![bg, CGColor];
|
||||
let layer: id = msg_send![&*self.objc, layer];
|
||||
let _: () = msg_send![layer, setBackgroundColor:cg];
|
||||
//let view: id = msg_send![*self.objc, view];
|
||||
//(*view).set_ivar(BACKGROUND_COLOR, color.into_platform_specific_color());
|
||||
//let _: () = msg_send![view, setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,18 +187,6 @@ impl<T> View<T> {
|
|||
let _: () = msg_send![&*self.objc, registerForDraggedTypes:types.into_inner()];
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn add_subview<L: Layout>(&self, subview: &L) {
|
||||
/*if let Some(subview_controller) = subview.get_backing_node() {
|
||||
unsafe {
|
||||
let _: () = msg_send![*this, addChildViewController:&*subview_controller];
|
||||
|
||||
let subview: id = msg_send![&*subview_controller, view];
|
||||
let view: id = msg_send![*this, view];
|
||||
let _: () = msg_send![view, addSubview:subview];
|
||||
}
|
||||
}*/
|
||||
//}
|
||||
}
|
||||
|
||||
impl<T> Layout for View<T> {
|
||||
|
@ -212,7 +206,7 @@ impl<T> Layout for View<T> {
|
|||
impl<T> Drop for View<T> {
|
||||
/// A bit of extra cleanup for delegate callback pointers.
|
||||
fn drop(&mut self) {
|
||||
if let ptr = &self.internal_callback_ptr {
|
||||
if let Some(ptr) = &self.internal_callback_ptr {
|
||||
unsafe {
|
||||
let _ = Rc::from_raw(ptr);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use objc::{msg_send, sel, sel_impl};
|
|||
use objc_id::ShareId;
|
||||
|
||||
use crate::foundation::{id, nil};
|
||||
use crate::layout::traits::Layout;
|
||||
use crate::utils::Controller;
|
||||
use crate::window::{Window, WindowConfig, WindowDelegate, WINDOW_DELEGATE_PTR};
|
||||
|
||||
mod class;
|
||||
|
@ -51,9 +51,13 @@ impl<T> WindowController<T> where T: WindowDelegate + 'static {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
/// Given a view, sets it as the content view controller for this window.
|
||||
pub fn set_content_view_controller<C: Controller + 'static>(&self, controller: &C) {
|
||||
let backing_node = controller.get_backing_node();
|
||||
|
||||
unsafe {
|
||||
let _: () = msg_send![&*self.objc, setContentViewController:&*backing_node];
|
||||
}
|
||||
}
|
||||
|
||||
/// Shows the window, running a configuration pass if necessary.
|
||||
|
|
|
@ -11,6 +11,7 @@ use objc_id::ShareId;
|
|||
use crate::foundation::{id, nil, YES, NO, NSString, NSUInteger, CGRect, CGSize};
|
||||
use crate::layout::traits::Layout;
|
||||
use crate::toolbar::{Toolbar, ToolbarController};
|
||||
use crate::utils::Controller;
|
||||
|
||||
mod class;
|
||||
use class::{register_window_class, register_window_class_with_delegate};
|
||||
|
@ -146,15 +147,6 @@ impl<T> Window<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Used for setting the content view controller for this window.
|
||||
pub fn set_content_view_controller<L: Layout + 'static>(&self, view_controller: &L) {
|
||||
//unsafe {
|
||||
// if let Some(vc) = view_controller.get_backing_node() {
|
||||
// let _: () = msg_send![*controller, setContentViewController:&*vc];
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/// Given a view, sets it as the content view for this window.
|
||||
pub fn set_content_view<L: Layout + 'static>(&self, view: &L) {
|
||||
let backing_node = view.get_backing_node();
|
||||
|
@ -164,6 +156,15 @@ impl<T> Window<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Given a view, sets it as the content view controller for this window.
|
||||
pub fn set_content_view_controller<C: Controller + 'static>(&self, controller: &C) {
|
||||
let backing_node = controller.get_backing_node();
|
||||
|
||||
unsafe {
|
||||
let _: () = msg_send![&*self.objc, setContentViewController:&*backing_node];
|
||||
}
|
||||
}
|
||||
|
||||
/// Shows the window.
|
||||
pub fn show(&self) {
|
||||
unsafe {
|
||||
|
|
Loading…
Reference in a new issue