diff --git a/examples/frame_layout.rs b/examples/frame_layout.rs index 927ae861..c8091668 100644 --- a/examples/frame_layout.rs +++ b/examples/frame_layout.rs @@ -3,7 +3,7 @@ use cacao::color::Color; use cacao::geometry::Rect; -use cacao::layout::Layout; +use cacao::layout::{Frame, Layout}; use cacao::view::View; use cacao::appkit::menu::{Menu, MenuItem}; diff --git a/src/appkit/segmentedcontrol.rs b/src/appkit/segmentedcontrol.rs index a6a8468c..0ea33f4a 100644 --- a/src/appkit/segmentedcontrol.rs +++ b/src/appkit/segmentedcontrol.rs @@ -3,11 +3,11 @@ use std::fmt; use std::sync::Once; -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; use std::rc::Rc; use objc::declare::ClassDecl; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object, Sel}; use objc::{class, msg_send, msg_send_id, sel}; @@ -293,12 +293,12 @@ impl SegmentedControl { } impl ObjcAccess for SegmentedControl { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } @@ -306,12 +306,12 @@ impl Layout for SegmentedControl {} impl Control for SegmentedControl {} impl ObjcAccess for &SegmentedControl { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/appkit/window/mod.rs b/src/appkit/window/mod.rs index c479c79b..ee3cf2e7 100644 --- a/src/appkit/window/mod.rs +++ b/src/appkit/window/mod.rs @@ -330,7 +330,7 @@ impl Window { } /// Given a view, sets it as the content view for this window. pub fn set_content_view(&self, view: &L) { - view.with_backing_obj_mut(|backing_node| unsafe { + view.with_backing_obj_mut(&|backing_node| unsafe { let _: () = msg_send![&*self.objc, setContentView:&*backing_node]; }); } diff --git a/src/button/mod.rs b/src/button/mod.rs index 5fd80cb0..c6767f13 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -21,7 +21,9 @@ //! my_view.add_subview(&button); //! ``` -use objc::rc::{Id, Shared}; +use std::cell::Ref; + +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -311,12 +313,12 @@ impl Button { } impl ObjcAccess for Button { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } @@ -325,12 +327,12 @@ impl Layout for Button {} impl Control for Button {} impl ObjcAccess for &Button { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/control/mod.rs b/src/control/mod.rs index 8691011c..a957cb47 100644 --- a/src/control/mod.rs +++ b/src/control/mod.rs @@ -27,7 +27,7 @@ pub enum ControlSize { pub trait Control: ObjcAccess { /// Whether this control is enabled or not. fn set_enabled(&self, is_enabled: bool) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setEnabled:match is_enabled { true => YES, false => NO @@ -48,7 +48,7 @@ pub trait Control: ObjcAccess { } }; - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setControlSize: control_size]; }); } diff --git a/src/image/mod.rs b/src/image/mod.rs index 8b567235..be587910 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -1,6 +1,8 @@ +use std::cell::Ref; + use core_foundation::base::TCFType; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -174,12 +176,12 @@ impl ImageView { } impl ObjcAccess for ImageView { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 3e1759e7..0751ea41 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -43,9 +43,11 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. +use std::cell::Ref; + use core_foundation::base::TCFType; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, sel}; @@ -389,12 +391,12 @@ impl TextField { } impl ObjcAccess for TextField { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 38bafee4..14bc0a71 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -4,7 +4,7 @@ //! more complicated views that need to deal with differing screen sizes. mod traits; -pub use traits::Layout; +pub use traits::{Frame, Layout}; #[cfg(all(feature = "appkit", target_os = "macos"))] mod animator; diff --git a/src/layout/traits.rs b/src/layout/traits.rs index 6249b175..97e74c73 100644 --- a/src/layout/traits.rs +++ b/src/layout/traits.rs @@ -1,6 +1,8 @@ //! Various traits related to controllers opting in to autolayout routines and support for view //! heirarchies. +use objc::msg_send_id; + use core_graphics::base::CGFloat; use core_graphics::geometry::{CGPoint, CGRect, CGSize}; @@ -15,6 +17,8 @@ use crate::objc_access::ObjcAccess; #[cfg(feature = "appkit")] use crate::pasteboard::PasteboardType; +use super::{LayoutAnchorX, LayoutAnchorY}; + /// A trait that view wrappers must conform to. Enables managing the subview tree. #[allow(unused_variables)] pub trait Layout: ObjcAccess { @@ -24,7 +28,7 @@ pub trait Layout: ObjcAccess { /// pass from the system will redraw it accordingly, and set the underlying value back to /// `false`. fn set_needs_display(&self, needs_display: bool) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setNeedsDisplay:match needs_display { true => YES, false => NO @@ -33,9 +37,9 @@ pub trait Layout: ObjcAccess { } /// Adds another Layout-backed control or view as a subview of this view. - fn add_subview(&self, view: &V) { - self.with_backing_obj_mut(|backing_node| { - view.with_backing_obj_mut(|subview_node| unsafe { + fn add_subview(&self, view: &dyn Layout) { + self.with_backing_obj_mut(&|backing_node| { + view.with_backing_obj_mut(&|subview_node| unsafe { let _: () = msg_send![backing_node, addSubview: subview_node]; }); }); @@ -43,24 +47,11 @@ pub trait Layout: ObjcAccess { /// Removes a control or view from the superview. fn remove_from_superview(&self) { - self.with_backing_obj_mut(|backing_node| unsafe { + self.with_backing_obj_mut(&|backing_node| unsafe { let _: () = msg_send![backing_node, removeFromSuperview]; }); } - /// Sets the `frame` for the view this trait is applied to. - /// - /// Note that Cacao, by default, opts into autolayout - you need to call - /// `set_translates_autoresizing_mask_into_constraints` to enable frame-based layout calls (or - /// use an appropriate initializer for a given view type). - fn set_frame>(&self, rect: R) { - let frame: CGRect = rect.into(); - - self.with_backing_obj_mut(move |backing_node| unsafe { - let _: () = msg_send![backing_node, setFrame: frame]; - }); - } - /// Sets whether the view for this trait should translate autoresizing masks into layout /// constraints. /// @@ -68,7 +59,7 @@ pub trait Layout: ObjcAccess { /// then you should set this to `true` (or use an appropriate initializer that does it for you). #[cfg(feature = "autolayout")] fn set_translates_autoresizing_mask_into_constraints(&self, translates: bool) { - self.with_backing_obj_mut(|backing_node| unsafe { + self.with_backing_obj_mut(&|backing_node| unsafe { let _: () = msg_send![backing_node, setTranslatesAutoresizingMaskIntoConstraints:match translates { true => YES, false => NO @@ -80,7 +71,7 @@ pub trait Layout: ObjcAccess { /// /// When hidden, widgets don't receive events and is not visible. fn set_hidden(&self, hide: bool) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setHidden:match hide { true => YES, false => NO @@ -93,13 +84,15 @@ pub trait Layout: ObjcAccess { /// Note that this can report `false` if an ancestor widget is hidden, thus hiding this - to check in /// that case, you may want `is_hidden_or_ancestor_is_hidden()`. fn is_hidden(&self) -> bool { - self.get_from_backing_obj(|obj| to_bool(unsafe { msg_send![obj, isHidden] })) + let obj = self.get_backing_obj(); + to_bool(unsafe { msg_send![&**obj, isHidden] }) } /// Returns whether this is hidden, *or* whether an ancestor view is hidden. #[cfg(feature = "appkit")] fn is_hidden_or_ancestor_is_hidden(&self) -> bool { - self.get_from_backing_obj(|obj| to_bool(unsafe { msg_send![obj, isHiddenOrHasHiddenAncestor] })) + let obj = self.get_backing_obj(); + to_bool(unsafe { msg_send![&**obj, isHiddenOrHasHiddenAncestor] }) } /// Register this view for drag and drop operations. @@ -118,7 +111,7 @@ pub trait Layout: ObjcAccess { .collect::>() .into(); - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, registerForDraggedTypes:&*types]; }); } @@ -129,7 +122,7 @@ pub trait Layout: ObjcAccess { /// currently to avoid compile issues. #[cfg(feature = "appkit")] fn unregister_dragged_types(&self) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, unregisterDraggedTypes]; }); } @@ -140,7 +133,7 @@ pub trait Layout: ObjcAccess { /// can be helpful - but always test! #[cfg(feature = "appkit")] fn set_posts_frame_change_notifications(&self, posts: bool) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setPostsFrameChangedNotifications:match posts { true => YES, false => NO @@ -154,7 +147,7 @@ pub trait Layout: ObjcAccess { /// can be helpful - but always test! #[cfg(feature = "appkit")] fn set_posts_bounds_change_notifications(&self, posts: bool) { - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setPostsBoundsChangedNotifications:match posts { true => YES, false => NO @@ -168,8 +161,46 @@ pub trait Layout: ObjcAccess { fn set_alpha(&self, value: f64) { let value: CGFloat = value.into(); - self.with_backing_obj_mut(|obj| unsafe { + self.with_backing_obj_mut(&|obj| unsafe { let _: () = msg_send![obj, setAlphaValue: value]; }); } + + #[cfg(feature = "appkit")] + fn get_top(&self) -> LayoutAnchorY { + let id = self.get_backing_obj(); + LayoutAnchorY::Top(unsafe { msg_send_id![&**id, topAnchor] }) + } + #[cfg(feature = "appkit")] + fn get_bottom(&self) -> LayoutAnchorY { + let id = self.get_backing_obj(); + LayoutAnchorY::Bottom(unsafe { msg_send_id![&**id, bottomAnchor] }) + } + #[cfg(feature = "appkit")] + fn get_leading(&self) -> LayoutAnchorX { + let id = self.get_backing_obj(); + LayoutAnchorX::Leading(unsafe { msg_send_id![&**id, leadingAnchor] }) + } + #[cfg(feature = "appkit")] + fn get_trailing(&self) -> LayoutAnchorX { + let id = self.get_backing_obj(); + LayoutAnchorX::Trailing(unsafe { msg_send_id![&**id, trailingAnchor] }) + } +} + +pub trait Frame: Layout { + /// Sets the `frame` for the view this trait is applied to. + /// + /// Note that Cacao, by default, opts into autolayout - you need to call + /// `set_translates_autoresizing_mask_into_constraints` to enable frame-based layout calls (or + /// use an appropriate initializer for a given view type). + fn set_frame>(&self, rect: R) { + let frame: CGRect = rect.into(); + + self.with_backing_obj_mut(&move |backing_node| unsafe { + let _: () = msg_send![backing_node, setFrame: frame]; + }); + } } + +impl Frame for T {} diff --git a/src/listview/mod.rs b/src/listview/mod.rs index 7f239be1..9844e963 100644 --- a/src/listview/mod.rs +++ b/src/listview/mod.rs @@ -96,7 +96,7 @@ pub(crate) static LISTVIEW_DELEGATE_PTR: &str = "rstListViewDelegatePtr"; use std::any::Any; use std::sync::{Arc, RwLock}; -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; use std::rc::Rc; /// A helper method for instantiating view classes and applying default settings to them. @@ -750,21 +750,21 @@ impl ListView { } impl ObjcAccess for ListView { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { // In AppKit, we need to provide the scrollview for layout purposes - iOS and tvOS will know // what to do normally. #[cfg(feature = "appkit")] self.scrollview.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { + fn get_backing_obj(&self) -> Ref<'_, Id> { // In AppKit, we need to provide the scrollview for layout purposes - iOS and tvOS will know // what to do normally. // // @TODO: Review this, as property access isn't really used in the same place as layout // stuff... hmm... #[cfg(feature = "appkit")] - self.scrollview.objc.get(handler) + self.scrollview.objc.get_ref() } } diff --git a/src/listview/row/mod.rs b/src/listview/row/mod.rs index ef6342d8..32f690a3 100644 --- a/src/listview/row/mod.rs +++ b/src/listview/row/mod.rs @@ -42,7 +42,7 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; use std::rc::Rc; use objc::rc::{Id, Owned, Shared}; @@ -449,12 +449,12 @@ impl ListViewRow { } impl ObjcAccess for ListViewRow { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/objc_access.rs b/src/objc_access.rs index a24055e4..bb02eba4 100644 --- a/src/objc_access.rs +++ b/src/objc_access.rs @@ -2,7 +2,12 @@ //! defined on here provide access handlers for common properties that the sub-traits need to //! enable modifying. -use objc::runtime::Object; +use std::cell::Ref; + +use objc::{ + rc::{Id, Owned}, + runtime::Object +}; use crate::foundation::id; @@ -13,11 +18,11 @@ use crate::foundation::id; pub trait ObjcAccess { /// Used for mutably interacting with the underlying Objective-C instance. /// Setters should use this. - fn with_backing_obj_mut(&self, handler: F); + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)); /// Used for checking backing properties of the underlying Objective-C instance, without /// needing a mutable borrow. /// /// Getters should use this. - fn get_from_backing_obj R, R>(&self, handler: F) -> R; + fn get_backing_obj(&self) -> Ref<'_, Id>; } diff --git a/src/progress/mod.rs b/src/progress/mod.rs index 9de32950..cdc7003d 100644 --- a/src/progress/mod.rs +++ b/src/progress/mod.rs @@ -15,9 +15,11 @@ //! my_view.add_subview(&indicator); //! ``` +use std::cell::Ref; + use core_graphics::base::CGFloat; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, sel}; @@ -207,12 +209,12 @@ impl ProgressIndicator { } impl ObjcAccess for ProgressIndicator { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/scrollview/mod.rs b/src/scrollview/mod.rs index e945c14d..d198dbf5 100644 --- a/src/scrollview/mod.rs +++ b/src/scrollview/mod.rs @@ -42,9 +42,11 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. +use std::cell::Ref; + use core_foundation::base::TCFType; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, sel}; @@ -306,12 +308,12 @@ impl ScrollView { } impl ObjcAccess for ScrollView { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/select/mod.rs b/src/select/mod.rs index 02b1e0ed..1be2cc41 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1,7 +1,9 @@ //! Implements a Select-style dropdown. By default this uses NSPopupSelect on macOS. +use std::cell::Ref; + use core_graphics::geometry::CGRect; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -203,17 +205,17 @@ impl Select { } impl ObjcAccess for Select { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } impl Layout for Select { - fn add_subview(&self, _view: &V) { + fn add_subview(&self, _view: &dyn Layout) { panic!( r#" Tried to add a subview to a Select. This is not allowed in Cacao. If you think this should be supported, @@ -226,17 +228,17 @@ impl Layout for Select { impl Control for Select {} impl ObjcAccess for &Select { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } impl Layout for &Select { - fn add_subview(&self, _view: &V) { + fn add_subview(&self, _view: &dyn Layout) { panic!( r#" Tried to add a subview to a Select. This is not allowed in Cacao. If you think this should be supported, diff --git a/src/switch.rs b/src/switch.rs index 601ac901..cfe1edf6 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -1,7 +1,9 @@ //! A wrapper for NSSwitch. Currently the epitome of jank - if you're poking around here, expect //! that this will change at some point. -use objc::rc::{Id, Shared}; +use std::cell::Ref; + +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -139,17 +141,17 @@ impl Switch { } impl ObjcAccess for Switch { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } impl Layout for Switch { - fn add_subview(&self, _view: &V) { + fn add_subview(&self, _view: &dyn Layout) { panic!( r#" Tried to add a subview to a Switch. This is not allowed in Cacao. If you think this should be supported, diff --git a/src/text/label/mod.rs b/src/text/label/mod.rs index 23cb7de8..93e91691 100644 --- a/src/text/label/mod.rs +++ b/src/text/label/mod.rs @@ -43,9 +43,11 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. +use std::cell::Ref; + use core_foundation::base::TCFType; -use objc::rc::{Id, Shared}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -439,12 +441,12 @@ impl Label { } impl ObjcAccess for Label { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/utils/properties.rs b/src/utils/properties.rs index 6ccb8eaa..3cfb0467 100644 --- a/src/utils/properties.rs +++ b/src/utils/properties.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; use std::rc::Rc; use objc::rc::{Id, Owned}; @@ -40,6 +40,10 @@ impl ObjcProperty { let obj = self.0.borrow(); handler(&**obj) } + + pub fn get_ref(&self) -> Ref<'_, Id> { + self.0.borrow() + } } /// A wrapper for a single-threaded nullable `Property`. diff --git a/src/view/controller/mod.rs b/src/view/controller/mod.rs index 453e76d9..7bf96297 100644 --- a/src/view/controller/mod.rs +++ b/src/view/controller/mod.rs @@ -60,7 +60,7 @@ where vc.set_ivar(VIEW_DELEGATE_PTR, ptr as usize); } - view.with_backing_obj_mut(|backing_node| { + view.with_backing_obj_mut(&|backing_node| { let _: () = msg_send![&vc, setView: backing_node]; }); diff --git a/src/view/mod.rs b/src/view/mod.rs index c0e1a334..98043beb 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -42,6 +42,9 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. +use std::cell::Ref; + +use objc::rc::{Id, Owned}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; @@ -350,12 +353,12 @@ impl View { } impl ObjcAccess for View { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } diff --git a/src/view/popover/mod.rs b/src/view/popover/mod.rs index 1beeb129..e4f4abb5 100644 --- a/src/view/popover/mod.rs +++ b/src/view/popover/mod.rs @@ -81,7 +81,7 @@ impl Popover { pub fn show_popover(&self, relative_to: Rect, view: &V, edge: Edge) { let rect: CGRect = relative_to.into(); unsafe { - view.with_backing_obj_mut(|obj| { + view.with_backing_obj_mut(&|obj| { let _: () = msg_send![&*self.objc, showRelativeToRect:rect ofView: &*obj preferredEdge: edge as u32]; }); } diff --git a/src/webview/mod.rs b/src/webview/mod.rs index 8cbae491..a0cef291 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -14,10 +14,10 @@ //! platform. use core_graphics::geometry::CGRect; - use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; +use std::cell::Ref; use crate::foundation::{id, nil, NSString, NO, YES}; use crate::geometry::Rect; @@ -333,19 +333,19 @@ impl WebView { } impl ObjcAccess for WebView { - fn with_backing_obj_mut(&self, handler: F) { + fn with_backing_obj_mut(&self, handler: &dyn Fn(id)) { self.objc.with_mut(handler); } - fn get_from_backing_obj R, R>(&self, handler: F) -> R { - self.objc.get(handler) + fn get_backing_obj(&self) -> Ref<'_, Id> { + self.objc.get_ref() } } impl Layout for WebView { /// Currently, this is a noop. Theoretically there is reason to support this, but in practice /// I've never seen it needed... but am open to discussion. - fn add_subview(&self, _: &V) {} + fn add_subview(&self, _: &dyn Layout) {} } impl std::fmt::Debug for WebView {