diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 766677bb..6ac62756 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -189,10 +189,13 @@ impl View { /// so on. It returns a generic `View`, which the caller can then customize as needed. pub(crate) fn init(view: id) -> View { unsafe { - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO]; + let _: () = msg_send![ + view, + setTranslatesAutoresizingMaskIntoConstraints: false, + ]; #[cfg(target_os = "macos")] - let _: () = msg_send![view, setWantsLayer:YES]; + let _: () = msg_send![view, setWantsLayer: true]; } View { @@ -357,7 +360,7 @@ pub(crate) fn register_view_class() -> &'static Class { INIT.call_once(|| unsafe { let superclass = class!(NSView); - let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); + let mut decl = ClassBuilder::new("RSTView", superclass).unwrap(); decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(_, _) -> _); diff --git a/Cargo.toml b/Cargo.toml index 639e96c1..2a2a9268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,6 @@ rustdoc-args = ["--cfg", "docsrs"] bitmask-enum = "2.2.1" objc = { version = "=0.3.0-beta.2", package = "objc2" } block = { version = "=0.2.0-alpha.6", package = "block2" } -# Temporary: Patched versions that implement `Encode` for common types -# Branch: `objc2` -core-foundation = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "7d593d016175755e492a92ef89edca68ac3bd5cd" } -core-graphics = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "7d593d016175755e492a92ef89edca68ac3bd5cd" } dispatch = "0.2.0" infer = { version = "0.15", optional = true } lazy_static = "1.4.0" @@ -36,9 +32,11 @@ uuid = { version = "1.1", features = ["v4"], optional = true } [dev-dependencies] eval = "0.4" +core-graphics = "0.23" +foreign-types = "0.5" [features] -appkit = ["core-foundation/mac_os_10_8_features"] +appkit = [] uikit = [] autolayout = [] default = ["appkit", "autolayout"] diff --git a/README.md b/README.md index 9a7d04f0..e0cc46f9 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,8 @@ The following are a list of [Cargo features][cargo-features] that can be enabled [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section ## General Notes -**Why not extend the existing cocoa-rs crate?** -A good question. At the end of the day, that crate (I believe, and someone can correct me if I'm wrong) is somewhat tied to Servo, and I wanted to experiment with what the best approach for representing the Cocoa UI model in Rust was. This crate doesn't ignore their work entirely, either - `core_foundation` and `core_graphics` are used internally and re-exported for general use. +**Why not extend the existing cocoa-rs crate?** +A good question. At the end of the day, that crate (I believe, and someone can correct me if I'm wrong) is somewhat tied to Servo, and I wanted to experiment with what the best approach for representing the Cocoa UI model in Rust was. **Why should I write in Rust, rather than X language?** In _my_ case, I want to be able to write native applications for my devices (and the platform I like to build products for) without being locked in to writing in Apple-specific languages... and without writing in C/C++ or JavaScript (note: the _toolchain_, not the language - ES6/Typescript are fine). I want to do this because I'm tired of hitting a mountain of work when I want to port my applications to other ecosystems. I think that Rust offers a (growing, but significant) viable model for sharing code across platforms and ecosystems without sacrificing performance. diff --git a/examples/custom_image_drawing.rs b/examples/custom_image_drawing.rs index 8dc6bee0..3a853c82 100644 --- a/examples/custom_image_drawing.rs +++ b/examples/custom_image_drawing.rs @@ -1,6 +1,9 @@ //! This example showcases how to do custom drawing on an ImageView //! with CoreGraphics. Feel free to modify it and play around! +use core_graphics::context::CGContextRef; +use foreign_types::ForeignTypeRef; + use cacao::appkit::menu::{Menu, MenuItem}; use cacao::appkit::window::Window; use cacao::appkit::{App, AppDelegate}; @@ -30,7 +33,12 @@ impl Default for BasicApp { window: Window::default(), content_view: View::new(), image_view: ImageView::new(), - image: Image::draw(config, |_cg_rect, context| { + image: Image::draw(config, |resized_frame, source, context| { + let context = unsafe { CGContextRef::from_ptr(context.cast()) }; + + context.translate(resized_frame.top, resized_frame.left); + context.scale(resized_frame.width / source.0, resized_frame.height / source.1); + context.move_to_point(11.25, 8.19); context.add_line_to_point(11.25, 5.); context.add_line_to_point(6.56, 5.); diff --git a/src/appkit/app/delegate.rs b/src/appkit/app/delegate.rs index 4f4fce31..963e50ac 100644 --- a/src/appkit/app/delegate.rs +++ b/src/appkit/app/delegate.rs @@ -21,7 +21,7 @@ use crate::user_activity::UserActivity; /// standard `utils` version as this doesn't require `RefCell` backing. fn app(this: &Object) -> &T { unsafe { - let app_ptr: usize = *this.get_ivar(APP_PTR); + let app_ptr: usize = *this.ivar(APP_PTR); let app = app_ptr as *const T; &*app } diff --git a/src/appkit/app/enums.rs b/src/appkit/app/enums.rs index 140515cc..5ea29b11 100644 --- a/src/appkit/app/enums.rs +++ b/src/appkit/app/enums.rs @@ -1,4 +1,5 @@ //! Various types used at the AppController level. +#![allow(unused_parens)] use crate::foundation::NSUInteger; diff --git a/src/appkit/app/mod.rs b/src/appkit/app/mod.rs index a266d925..4129607b 100644 --- a/src/appkit/app/mod.rs +++ b/src/appkit/app/mod.rs @@ -44,7 +44,7 @@ use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::appkit::menu::Menu; -use crate::foundation::{id, nil, AutoReleasePool, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, AutoReleasePool, NSUInteger}; use crate::invoker::TargetActionHandler; use crate::notification_center::Dispatcher; use crate::utils::activate_cocoa_multithreading; @@ -195,7 +195,7 @@ where queue.exec_async(move || unsafe { let app: id = msg_send![register_app_class(), sharedApplication]; let app_delegate: id = msg_send![app, delegate]; - let delegate_ptr: usize = *(*app_delegate).get_ivar(APP_PTR); + let delegate_ptr: usize = *(*app_delegate).ivar(APP_PTR); let delegate = delegate_ptr as *const T; (&*delegate).on_ui_message(message); }); @@ -209,7 +209,7 @@ where queue.exec_async(move || unsafe { let app: id = msg_send![register_app_class(), sharedApplication]; let app_delegate: id = msg_send![app, delegate]; - let delegate_ptr: usize = *(*app_delegate).get_ivar(APP_PTR); + let delegate_ptr: usize = *(*app_delegate).ivar(APP_PTR); let delegate = delegate_ptr as *const T; (&*delegate).on_background_message(message); }); @@ -246,10 +246,7 @@ impl App { /// from your trait implementation of `should_terminate()`. pub fn reply_to_termination_request(should_terminate: bool) { shared_application(|app| unsafe { - let _: () = msg_send![app, replyToApplicationShouldTerminate:match should_terminate { - true => YES, - false => NO - }]; + let _: () = msg_send![app, replyToApplicationShouldTerminate: should_terminate]; }); } diff --git a/src/appkit/cursor.rs b/src/appkit/cursor.rs index 2a161f30..ba966a1d 100644 --- a/src/appkit/cursor.rs +++ b/src/appkit/cursor.rs @@ -1,6 +1,6 @@ use objc::{class, msg_send, sel}; -use crate::foundation::{id, NO, YES}; +use crate::foundation::id; /// Represents a type of cursor that you can associate with mouse movement. /// @TODO: Loading? @@ -163,10 +163,7 @@ impl Cursor { /// Trying to invert this with `unhide` will result in undefined system behavior. pub fn set_hidden_until_mouse_moves(status: bool) { unsafe { - let _: () = msg_send![class!(NSCursor), setHiddenUntilMouseMoves:match status { - true => YES, - false => NO - }]; + let _: () = msg_send![class!(NSCursor), setHiddenUntilMouseMoves: status]; } } } diff --git a/src/appkit/event/mod.rs b/src/appkit/event/mod.rs index 9d6568cc..256b4c8a 100644 --- a/src/appkit/event/mod.rs +++ b/src/appkit/event/mod.rs @@ -1,12 +1,13 @@ use bitmask_enum::bitmask; use block::ConcreteBlock; +use objc::foundation::NSPoint; use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::events::EventType; -use crate::foundation::{id, nil, NSInteger, NSPoint, NSString}; +use crate::foundation::{id, nil, NSInteger, NSString}; /// An EventMask describes the type of event. #[bitmask(u64)] diff --git a/src/appkit/menu/item.rs b/src/appkit/menu/item.rs index 7ea6c09b..678d626e 100644 --- a/src/appkit/menu/item.rs +++ b/src/appkit/menu/item.rs @@ -294,7 +294,7 @@ impl MenuItem { /// need to do some extra logic to ensure release calls are properly sent. extern "C" fn dealloc_cacao_menuitem(this: &Object, _: Sel) { unsafe { - let ptr: usize = *this.get_ivar(BLOCK_PTR); + let ptr: usize = *this.ivar(BLOCK_PTR); let obj = ptr as *mut Action; if !obj.is_null() { diff --git a/src/appkit/segmentedcontrol.rs b/src/appkit/segmentedcontrol.rs index a6a8468c..40882eaa 100644 --- a/src/appkit/segmentedcontrol.rs +++ b/src/appkit/segmentedcontrol.rs @@ -6,14 +6,14 @@ use std::sync::Once; use std::cell::RefCell; use std::rc::Rc; -use objc::declare::ClassDecl; +use objc::declare::ClassBuilder; use objc::rc::{Id, Shared}; -use objc::runtime::{Class, Object, Sel}; +use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, msg_send_id, sel}; use crate::color::Color; use crate::control::Control; -use crate::foundation::{id, nil, NSArray, NSString, NSUInteger, BOOL, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString, NSUInteger}; use crate::image::Image; use crate::invoker::TargetActionHandler; use crate::keys::Key; @@ -120,10 +120,10 @@ impl SegmentedControl { action:nil ]; - let _: () = msg_send![control, setWantsLayer: YES]; + let _: () = msg_send![control, setWantsLayer: true]; #[cfg(feature = "autolayout")] - let _: () = msg_send![control, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![control, setTranslatesAutoresizingMaskIntoConstraints: false]; control }; @@ -239,7 +239,7 @@ impl SegmentedControl { #[cfg(feature = "appkit")] self.objc.with_mut(move |obj| unsafe { let text: id = msg_send![obj, attributedTitle]; - let len: isize = msg_send![text, length]; + let len: usize = msg_send![text, length]; let mut attr_str = AttributedString::wrap(text); attr_str.set_text_color(color.as_ref(), 0..len); @@ -253,10 +253,7 @@ impl SegmentedControl { #[cfg(feature = "appkit")] pub fn set_bordered(&self, is_bordered: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setBordered:match is_bordered { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setBordered: is_bordered]; }); } @@ -284,10 +281,7 @@ impl SegmentedControl { /// Toggles the highlighted status of the button. pub fn set_highlighted(&self, highlight: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, highlight:match highlight { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, highlight: highlight]; }); } } @@ -338,7 +332,7 @@ fn register_class() -> *const Class { INIT.call_once(|| unsafe { let superclass = class!(NSSegmentedControl); - let decl = ClassDecl::new("RSTSegmentedControl", superclass).unwrap(); + let decl = ClassBuilder::new("RSTSegmentedControl", superclass).unwrap(); VIEW_CLASS = decl.register(); }); diff --git a/src/appkit/toolbar/class.rs b/src/appkit/toolbar/class.rs index 60ff60da..aab6eeb7 100644 --- a/src/appkit/toolbar/class.rs +++ b/src/appkit/toolbar/class.rs @@ -2,7 +2,6 @@ use std::sync::Once; -use objc::declare::ClassDecl; use objc::rc::Id; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, sel}; diff --git a/src/appkit/toolbar/item.rs b/src/appkit/toolbar/item.rs index 22428d45..96b547ab 100644 --- a/src/appkit/toolbar/item.rs +++ b/src/appkit/toolbar/item.rs @@ -3,16 +3,16 @@ //! //! UNFORTUNATELY, this is a very old and janky API. So... yeah. -use core_graphics::geometry::CGSize; use std::fmt; +use objc::foundation::NSSize; use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::appkit::segmentedcontrol::SegmentedControl; use crate::button::{BezelStyle, Button}; -use crate::foundation::{id, NSString, NO, YES}; +use crate::foundation::{id, NSString}; use crate::image::Image; use crate::invoker::TargetActionHandler; @@ -89,7 +89,7 @@ impl ToolbarItem { /// Sets the minimum size for this button. pub fn set_min_size(&mut self, width: f64, height: f64) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setMinSize: size]; } } @@ -97,7 +97,7 @@ impl ToolbarItem { /// Sets the maximum size for this button. pub fn set_max_size(&mut self, width: f64, height: f64) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setMaxSize: size]; } } @@ -110,10 +110,7 @@ impl ToolbarItem { pub fn set_bordered(&self, bordered: bool) { unsafe { - let _: () = msg_send![&*self.objc, setBordered:match bordered { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setBordered: bordered]; } } } diff --git a/src/appkit/toolbar/mod.rs b/src/appkit/toolbar/mod.rs index ada8614a..2d85225b 100644 --- a/src/appkit/toolbar/mod.rs +++ b/src/appkit/toolbar/mod.rs @@ -9,7 +9,7 @@ use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, nil, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, NSString, NSUInteger}; mod class; use class::register_toolbar_class; @@ -88,10 +88,7 @@ impl Toolbar { /// contents. pub fn set_shows_baseline_separator(&self, shows: bool) { unsafe { - let _: () = msg_send![&*self.objc, setShowsBaselineSeparator:match shows { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setShowsBaselineSeparator: shows]; } } @@ -116,10 +113,7 @@ impl Toolbar { /// Set whether the toolbar is visible or not. pub fn set_visible(&self, visibility: bool) { unsafe { - let _: () = msg_send![&*self.objc, setVisible:match visibility { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setVisible: visibility]; } } diff --git a/src/appkit/window/class.rs b/src/appkit/window/class.rs index c0c9061a..950ea8bf 100644 --- a/src/appkit/window/class.rs +++ b/src/appkit/window/class.rs @@ -3,15 +3,13 @@ use std::sync::Once; -use core_graphics::base::CGFloat; - -use objc::declare::ClassDecl; +use objc::foundation::{CGFloat, NSSize}; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, sel}; use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR}; use crate::foundation::{id, load_or_register_class, NSUInteger}; -use crate::utils::{load, CGSize}; +use crate::utils::load; /// Called when an `NSWindowDelegate` receives a `windowWillClose:` event. /// Good place to clean up memory and what not. @@ -53,14 +51,11 @@ extern "C" fn did_change_screen_profile(this: &Object, _: Sel } /// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event. -extern "C" fn will_resize(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize { +extern "C" fn will_resize(this: &Object, _: Sel, _: id, size: NSSize) -> NSSize { let window = load::(this, WINDOW_DELEGATE_PTR); - let s = window.will_resize(size.width as f64, size.height as f64); + let s = window.will_resize(size.width() as f64, size.height() as f64); - CGSize { - width: s.0 as CGFloat, - height: s.1 as CGFloat - } + NSSize::new(s.0 as CGFloat, s.1 as CGFloat) } /// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event. @@ -112,15 +107,12 @@ extern "C" fn did_enter_full_screen(this: &Object, _: Sel, _: } /// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event. -extern "C" fn content_size_for_full_screen(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize { +extern "C" fn content_size_for_full_screen(this: &Object, _: Sel, _: id, size: NSSize) -> NSSize { let window = load::(this, WINDOW_DELEGATE_PTR); - let (width, height) = window.content_size_for_full_screen(size.width as f64, size.height as f64); + let (width, height) = window.content_size_for_full_screen(size.width() as f64, size.height() as f64); - CGSize { - width: width as CGFloat, - height: height as CGFloat - } + NSSize::new(width as CGFloat, height as CGFloat) } /// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event. diff --git a/src/appkit/window/mod.rs b/src/appkit/window/mod.rs index c479c79b..45d1f396 100644 --- a/src/appkit/window/mod.rs +++ b/src/appkit/window/mod.rs @@ -10,16 +10,14 @@ use block::ConcreteBlock; -use core_graphics::base::CGFloat; -use core_graphics::geometry::{CGRect, CGSize}; - +use objc::foundation::{CGFloat, NSRect, NSSize}; use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::appkit::toolbar::{Toolbar, ToolbarDelegate}; use crate::color::Color; -use crate::foundation::{id, nil, to_bool, NSInteger, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, NSInteger, NSString, NSUInteger}; use crate::layout::Layout; use crate::objc_access::ObjcAccess; use crate::utils::{os, Controller}; @@ -68,32 +66,29 @@ impl Window { /// after we initialize the backing `NSWindow`. pub fn new(config: WindowConfig) -> Window { let objc = unsafe { - // This behavior might make sense to keep as default (YES), but I think the majority of + // This behavior might make sense to keep as default (true), but I think the majority of // apps that would use this toolkit wouldn't be tab-oriented... - let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: NO]; + let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: false]; // Other types of backing (Retained/NonRetained) are archaic, dating back to the // NeXTSTEP era, and are outright deprecated... so we don't allow setting them. let buffered: NSUInteger = 2; - let dimensions: CGRect = config.initial_dimensions.into(); + let dimensions: NSRect = config.initial_dimensions.into(); let window: Id<_, _> = msg_send_id![ msg_send_id![class!(NSWindow), alloc], initWithContentRect: dimensions, styleMask: config.style, backing: buffered, - defer: match config.defer { - true => YES, - false => NO - }, + defer: config.defer, ]; // This is very important! NSWindow is an old class and has some behavior that we need // to disable, like... this. If we don't set this, we'll segfault entirely because the // Objective-C runtime gets out of sync by releasing the window out from underneath of // us. - let _: () = msg_send![&*window, setReleasedWhenClosed: NO]; + let _: () = msg_send![&*window, setReleasedWhenClosed: false]; - let _: () = msg_send![&*window, setRestorable: NO]; + let _: () = msg_send![&*window, setRestorable: false]; // This doesn't exist prior to Big Sur, but is important to support for Big Sur. // @@ -133,23 +128,20 @@ where let mut delegate = Box::new(delegate); let objc: Id = unsafe { - // This behavior might make sense to keep as default (YES), but I think the majority of + // This behavior might make sense to keep as default (true), but I think the majority of // apps that would use this toolkit wouldn't be tab-oriented... - let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: NO]; + let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: false]; // Other types of backing (Retained/NonRetained) are archaic, dating back to the // NeXTSTEP era, and are outright deprecated... so we don't allow setting them. let buffered: NSUInteger = 2; - let dimensions: CGRect = config.initial_dimensions.into(); + let dimensions: NSRect = config.initial_dimensions.into(); let mut window: Id = msg_send_id![ msg_send_id![class, alloc], initWithContentRect: dimensions, styleMask: config.style, backing: buffered, - defer: match config.defer { - true => YES, - false => NO - }, + defer: config.defer, ]; let delegate_ptr: *const T = &*delegate; @@ -159,12 +151,12 @@ where // to disable, like... this. If we don't set this, we'll segfault entirely because the // Objective-C runtime gets out of sync by releasing the window out from underneath of // us. - let _: () = msg_send![&*window, setReleasedWhenClosed: NO]; + let _: () = msg_send![&*window, setReleasedWhenClosed: false]; // We set the window to be its own delegate - this is cleaned up inside `Drop`. let _: () = msg_send![&*window, setDelegate: &*window]; - let _: () = msg_send![&*window, setRestorable: NO]; + let _: () = msg_send![&*window, setRestorable: false]; // This doesn't exist prior to Big Sur, but is important to support for Big Sur. // @@ -227,20 +219,14 @@ impl Window { /// Used for configuring whether the window is movable via the background. pub fn set_movable_by_background(&self, movable: bool) { unsafe { - let _: () = msg_send![&*self.objc, setMovableByWindowBackground:match movable { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setMovableByWindowBackground: movable]; } } /// Used for setting whether this titlebar appears transparent. pub fn set_titlebar_appears_transparent(&self, transparent: bool) { unsafe { - let _: () = msg_send![&*self.objc, setTitlebarAppearsTransparent:match transparent { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setTitlebarAppearsTransparent: transparent]; } } @@ -255,7 +241,7 @@ impl Window { /// Sets the content size for this window. pub fn set_content_size>(&self, width: F, height: F) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setContentSize: size]; } } @@ -263,7 +249,7 @@ impl Window { /// Sets the minimum size this window can shrink to. pub fn set_minimum_content_size>(&self, width: F, height: F) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setContentMinSize: size]; } } @@ -271,7 +257,7 @@ impl Window { /// Sets the maximum size this window can shrink to. pub fn set_maximum_content_size>(&self, width: F, height: F) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setContentMaxSize: size]; } } @@ -279,7 +265,7 @@ impl Window { /// Sets the minimum size this window can shrink to. pub fn set_minimum_size>(&self, width: F, height: F) { unsafe { - let size = CGSize::new(width.into(), height.into()); + let size = NSSize::new(width.into(), height.into()); let _: () = msg_send![&*self.objc, setMinSize: size]; } } @@ -316,10 +302,7 @@ impl Window { /// window. pub fn set_shows_toolbar_button(&self, shows: bool) { unsafe { - let _: () = msg_send![&*self.objc, setShowsToolbarButton:match shows { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setShowsToolbarButton: shows]; } } @@ -379,12 +362,12 @@ impl Window { /// Returns whether this window is opaque or not. pub fn is_opaque(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isOpaque] }) + unsafe { msg_send![&*self.objc, isOpaque] } } /// Returns whether this window is miniaturized or not. pub fn is_miniaturized(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isMiniaturized] }) + unsafe { msg_send![&*self.objc, isMiniaturized] } } /// Miniaturize this window. @@ -413,27 +396,27 @@ impl Window { /// /// From Apple's documentation: /// - /// _The value of this property is YES if the window is on the currently active space; otherwise, NO. + /// _The value of this property is `true` if the window is on the currently active space; otherwise, `false`. /// For visible windows, this property indicates whether the window is currently visible on the active /// space. For nonvisible windows, it indicates whether ordering the window onscreen would cause it to /// be on the active space._ pub fn is_on_active_space(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isOnActiveSpace] }) + unsafe { msg_send![&*self.objc, isOnActiveSpace] } } /// Returns whether this window is visible or not. pub fn is_visible(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isVisible] }) + unsafe { msg_send![&*self.objc, isVisible] } } /// Returns whether this window is the key or not. pub fn is_key(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isKeyWindow] }) + unsafe { msg_send![&*self.objc, isKeyWindow] } } /// Returns whether this window can become the key window. pub fn can_become_key(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, canBecomeKeyWindow] }) + unsafe { msg_send![&*self.objc, canBecomeKeyWindow] } } /// Make this window the key window. @@ -453,21 +436,18 @@ impl Window { /// Returns if this is the main window or not. pub fn is_main_window(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, isMainWindow] }) + unsafe { msg_send![&*self.objc, isMainWindow] } } /// Returns if this can become the main window. pub fn can_become_main_window(&self) -> bool { - to_bool(unsafe { msg_send![&*self.objc, canBecomeMainWindow] }) + unsafe { msg_send![&*self.objc, canBecomeMainWindow] } } /// Set whether this window should be excluded from the top-level "Windows" menu. pub fn set_excluded_from_windows_menu(&self, excluded: bool) { unsafe { - let _: () = msg_send![&*self.objc, setExcludedFromWindowsMenu:match excluded { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.objc, setExcludedFromWindowsMenu: excluded]; } } diff --git a/src/bundle.rs b/src/bundle.rs index 78bac9e5..ca8cc8f8 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -15,7 +15,7 @@ use objc::ffi; use objc::runtime::{Class, Imp, Object, Sel}; use objc::{class, msg_send, sel, Encode, EncodeArguments, Encoding, Message}; -use crate::foundation::{id, nil, BOOL, YES, NSString}; +use crate::foundation::{id, nil, NSString}; /// Types that can be used as the implementation of an Objective-C method. pub trait MethodImplementation { @@ -56,8 +56,8 @@ extern "C" fn get_bundle_id(this: &Object, s: Sel, v: id) -> id { unsafe { let bundle = class!(NSBundle); let main_bundle: id = msg_send![bundle, mainBundle]; - let e: BOOL = msg_send![this, isEqual:main_bundle]; - if e == YES { + let e = msg_send![this, isEqual:main_bundle]; + if e { let url: id = msg_send![main_bundle, bundleURL]; let x: id = msg_send![url, absoluteString]; println!("Got here? {:?}", x); diff --git a/src/button/mod.rs b/src/button/mod.rs index 5fd80cb0..792b3002 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -31,7 +31,7 @@ pub use enums::*; use crate::appkit::FocusRingType; use crate::color::Color; use crate::control::Control; -use crate::foundation::{id, load_or_register_class, nil, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, load_or_register_class, nil, NSString, NSUInteger}; use crate::image::Image; use crate::invoker::TargetActionHandler; use crate::keys::Key; @@ -129,10 +129,10 @@ impl Button { action:nil ]; - let _: () = msg_send![button, setWantsLayer: YES]; + let _: () = msg_send![button, setWantsLayer: true]; #[cfg(feature = "autolayout")] - let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints: false]; button }; @@ -257,7 +257,7 @@ impl Button { #[cfg(feature = "appkit")] self.objc.with_mut(move |obj| unsafe { let text: id = msg_send![obj, attributedTitle]; - let len: isize = msg_send![text, length]; + let len: usize = msg_send![text, length]; let mut attr_str = AttributedString::wrap(text); attr_str.set_text_color(color.as_ref(), 0..len); @@ -271,10 +271,7 @@ impl Button { #[cfg(feature = "appkit")] pub fn set_bordered(&self, is_bordered: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setBordered:match is_bordered { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setBordered: is_bordered]; }); } @@ -302,10 +299,7 @@ impl Button { /// Toggles the highlighted status of the button. pub fn set_highlighted(&self, highlight: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, highlight:match highlight { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, highlight: highlight]; }); } } diff --git a/src/color/appkit_dynamic_color.rs b/src/color/appkit_dynamic_color.rs index 000ebc17..eca7d032 100644 --- a/src/color/appkit_dynamic_color.rs +++ b/src/color/appkit_dynamic_color.rs @@ -10,7 +10,7 @@ //! that enables this functionality, we want to be able to provide this with some level of //! backwards compatibility for Mojave, as that's still a supported OS. -use core_graphics::base::CGFloat; +use objc::foundation::CGFloat; use objc::runtime::{Class, Object, Sel}; use objc::{class, msg_send, sel}; @@ -59,21 +59,21 @@ fn get_effective_color(this: &Object) -> id { let style: id = msg_send![appearance, bestMatchFromAppearancesWithNames:&*names]; if style == NSAppearanceNameDarkAqua { - return *this.get_ivar(AQUA_DARK_COLOR_NORMAL_CONTRAST); + return *this.ivar(AQUA_DARK_COLOR_NORMAL_CONTRAST); } if style == NSAppearanceNameAccessibilityHighContrastAqua { - return *this.get_ivar(AQUA_LIGHT_COLOR_HIGH_CONTRAST); + return *this.ivar(AQUA_LIGHT_COLOR_HIGH_CONTRAST); } if style == NSAppearanceNameAccessibilityHighContrastDarkAqua { - return *this.get_ivar(AQUA_DARK_COLOR_HIGH_CONTRAST); + return *this.ivar(AQUA_DARK_COLOR_HIGH_CONTRAST); } } } unsafe { - return *this.get_ivar(AQUA_LIGHT_COLOR_NORMAL_CONTRAST); + return *this.ivar(AQUA_LIGHT_COLOR_NORMAL_CONTRAST); } } diff --git a/src/color/mod.rs b/src/color/mod.rs index 03eac3bf..caabac40 100644 --- a/src/color/mod.rs +++ b/src/color/mod.rs @@ -15,10 +15,7 @@ /// @TODO: bundle iOS/tvOS support. use std::sync::{Arc, RwLock}; -use core_foundation::base::TCFType; -use core_graphics::base::CGFloat; -use core_graphics::color::CGColor; - +use objc::foundation::CGFloat; use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; @@ -392,10 +389,11 @@ impl Color { /// objects. If you're painting in a context that requires dark mode support, make sure /// you're not using a cached version of this unless you explicitly want the _same_ color /// in every context it's used in. - pub fn cg_color(&self) -> CGColor { + pub fn cg_color(&self) -> id { + // TODO: Better return type unsafe { let objc: id = self.into(); - CGColor::wrap_under_get_rule(msg_send![objc, CGColor]) + msg_send![objc, CGColor] } } } diff --git a/src/control/mod.rs b/src/control/mod.rs index 8691011c..c9c941a7 100644 --- a/src/control/mod.rs +++ b/src/control/mod.rs @@ -1,7 +1,7 @@ use objc::runtime::Object; use objc::{class, msg_send, sel}; -use crate::foundation::{id, NSUInteger, NO, YES}; +use crate::foundation::{id, NSUInteger}; use crate::objc_access::ObjcAccess; /// Use this enum for specifying NSControl size types. @@ -28,10 +28,7 @@ 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 { - let _: () = msg_send![obj, setEnabled:match is_enabled { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setEnabled: is_enabled]; }); } diff --git a/src/defaults/mod.rs b/src/defaults/mod.rs index e8fee70c..1d2fe59b 100644 --- a/src/defaults/mod.rs +++ b/src/defaults/mod.rs @@ -38,7 +38,7 @@ use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, nil, to_bool, NSData, NSMutableDictionary, NSNumber, NSString, BOOL, NO, YES}; +use crate::foundation::{id, nil, NSData, NSMutableDictionary, NSNumber, NSString}; mod value; pub use value::Value; @@ -195,7 +195,7 @@ impl UserDefaults { // `NSInteger` (platform specific) and `double` (f64) respectively, but conceivably we // might need others. // - // BOOL returns as "c", which... something makes me feel weird there, but testing it seems + // Bool returns as "c", which... something makes me feel weird there, but testing it seems // reliable. // // For context: https://nshipster.com/type-encodings/ @@ -236,12 +236,10 @@ impl UserDefaults { /// assert_eq!(value, false); /// ``` pub fn is_forced_for_key>(&self, key: K) -> bool { - let result: BOOL = unsafe { + unsafe { let key = NSString::new(key.as_ref()); msg_send![&*self.0, objectIsForcedForKey:&*key] - }; - - to_bool(result) + } } /// Blocks for any asynchronous updates to the defaults database and returns. diff --git a/src/filesystem/manager.rs b/src/filesystem/manager.rs index e5e5893f..f11b5b8f 100644 --- a/src/filesystem/manager.rs +++ b/src/filesystem/manager.rs @@ -5,13 +5,13 @@ use std::error::Error; use std::sync::{Arc, RwLock}; use objc::rc::{Id, Owned}; -use objc::runtime::{Object, BOOL}; +use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use url::Url; use crate::error::Error as AppKitError; use crate::filesystem::enums::{SearchPathDirectory, SearchPathDomainMask}; -use crate::foundation::{id, nil, NSString, NSUInteger, NO}; +use crate::foundation::{id, nil, NSString, NSUInteger}; /// A FileManager can be used for file operations (moving files, etc). /// @@ -47,11 +47,14 @@ impl FileManager { let directory = unsafe { let manager = self.0.read().unwrap(); - let dir: id = msg_send![&**manager, URLForDirectory:dir - inDomain:mask - appropriateForURL:nil - create:NO - error:nil]; + let dir: id = msg_send![ + &**manager, + URLForDirectory: dir, + inDomain: mask, + appropriateForURL: nil, + create: false, + error: nil, + ]; NSString::retain(msg_send![dir, absoluteString]) }; @@ -75,8 +78,8 @@ impl FileManager { let manager = self.0.read().unwrap(); let error: id = nil; - let result: BOOL = msg_send![&**manager, moveItemAtURL:from_url toURL:to_url error:&error]; - if result == NO { + let result = msg_send![&**manager, moveItemAtURL:from_url toURL:to_url error:&error]; + if result { return Err(AppKitError::new(error).into()); } } diff --git a/src/filesystem/save.rs b/src/filesystem/save.rs index 869e59b7..e2a52c71 100644 --- a/src/filesystem/save.rs +++ b/src/filesystem/save.rs @@ -8,7 +8,7 @@ use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, nil, NSInteger, NSString, NO, YES}; +use crate::foundation::{id, nil, NSInteger, NSString}; #[derive(Debug)] pub struct FileSavePanel { @@ -67,10 +67,7 @@ impl FileSavePanel { /// Sets whether directories can be created by the user. pub fn set_can_create_directories(&mut self, can_create: bool) { unsafe { - let _: () = msg_send![&*self.panel, setCanCreateDirectories:match can_create { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.panel, setCanCreateDirectories: can_create]; } self.can_create_directories = can_create; diff --git a/src/filesystem/select.rs b/src/filesystem/select.rs index b30fc51c..3fef7f71 100644 --- a/src/filesystem/select.rs +++ b/src/filesystem/select.rs @@ -11,7 +11,7 @@ use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::filesystem::enums::ModalResponse; -use crate::foundation::{id, nil, NSInteger, NSString, NO, NSURL, YES}; +use crate::foundation::{id, nil, NSInteger, NSString, NSURL}; #[cfg(feature = "appkit")] use crate::appkit::window::{Window, WindowDelegate}; @@ -71,10 +71,7 @@ impl FileSelectPanel { /// Sets whether files can be chosen by the user. pub fn set_can_choose_files(&mut self, can_choose: bool) { unsafe { - let _: () = msg_send![&*self.panel, setCanChooseFiles:match can_choose { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.panel, setCanChooseFiles: can_choose]; } self.can_choose_files = can_choose; @@ -91,10 +88,7 @@ impl FileSelectPanel { /// Sets whether the user can choose directories. pub fn set_can_choose_directories(&mut self, can_choose: bool) { unsafe { - let _: () = msg_send![&*self.panel, setCanChooseDirectories:match can_choose { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.panel, setCanChooseDirectories: can_choose]; } self.can_choose_directories = can_choose; @@ -103,10 +97,7 @@ impl FileSelectPanel { /// Sets whether the panel resolves aliases. pub fn set_resolves_aliases(&mut self, resolves: bool) { unsafe { - let _: () = msg_send![&*self.panel, setResolvesAliases:match resolves { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.panel, setResolvesAliases: resolves]; } self.resolves_aliases = resolves; @@ -115,10 +106,7 @@ impl FileSelectPanel { /// Sets whether the panel allows multiple selections. pub fn set_allows_multiple_selection(&mut self, allows: bool) { unsafe { - let _: () = msg_send![&*self.panel, setAllowsMultipleSelection:match allows { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.panel, setAllowsMultipleSelection: allows]; } self.allows_multiple_selection = allows; diff --git a/src/foundation/class.rs b/src/foundation/class.rs index 820f602e..18c0a0c3 100644 --- a/src/foundation/class.rs +++ b/src/foundation/class.rs @@ -8,7 +8,7 @@ use std::thread; use std::time::Instant; use lazy_static::lazy_static; -use objc::declare::ClassDecl; +use objc::declare::ClassBuilder; use objc::ffi; use objc::runtime::Class; @@ -132,7 +132,7 @@ impl ClassMap { #[inline(always)] pub fn load_or_register_class(superclass_name: &'static str, subclass_name: &'static str, config: F) -> &'static Class where - F: Fn(&mut ClassDecl) + 'static + F: Fn(&mut ClassBuilder) + 'static { load_or_register_class_with_optional_generated_suffix(superclass_name, subclass_name, true, config) } @@ -158,7 +158,7 @@ pub fn load_or_register_class_with_optional_generated_suffix( config: F ) -> &'static Class where - F: Fn(&mut ClassDecl) + 'static + F: Fn(&mut ClassBuilder) + 'static { if let Some(subclass) = CLASSES.load(subclass_name, Some(superclass_name)) { return subclass; @@ -189,7 +189,7 @@ where false => format!("{}_{}", subclass_name, superclass_name) }; - match ClassDecl::new(&objc_subclass_name, superclass) { + match ClassBuilder::new(&objc_subclass_name, superclass) { Some(mut decl) => { config(&mut decl); diff --git a/src/foundation/data.rs b/src/foundation/data.rs index 48bd145b..55e7637b 100644 --- a/src/foundation/data.rs +++ b/src/foundation/data.rs @@ -9,7 +9,7 @@ use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, to_bool, NSUInteger, BOOL, NO, YES}; +use crate::foundation::{id, NSUInteger}; /// Wrapper for a retained `NSData` object. /// @@ -79,9 +79,7 @@ impl NSData { /// A helper method for determining if a given `NSObject` is an `NSData`. pub fn is(obj: id) -> bool { - let result: BOOL = unsafe { msg_send![obj, isKindOfClass: class!(NSData)] }; - - to_bool(result) + unsafe { msg_send![obj, isKindOfClass: class!(NSData)] } } /// Returns the length of the underlying `NSData` bytes. diff --git a/src/foundation/mod.rs b/src/foundation/mod.rs index f73c0530..8459cfdc 100644 --- a/src/foundation/mod.rs +++ b/src/foundation/mod.rs @@ -19,7 +19,6 @@ #![allow(non_upper_case_globals)] use objc::runtime; -pub use objc::runtime::{BOOL, NO, YES}; mod autoreleasepool; pub use autoreleasepool::AutoReleasePool; @@ -47,22 +46,6 @@ pub use string::NSString; mod urls; pub use urls::{NSURLBookmarkCreationOption, NSURLBookmarkResolutionOption, NSURL}; -/// Bool mapping types differ between ARM and x64. There's a number of places that we need to check -/// against BOOL results throughout the framework, and this just simplifies some mismatches. -#[inline(always)] -pub fn to_bool(result: BOOL) -> bool { - match result { - YES => true, - NO => false, - - //#[cfg(target_arch = "aarch64")] - #[cfg(not(target_arch = "aarch64"))] - _ => { - std::unreachable!(); - } - } -} - /// More or less maps over to Objective-C's `id` type, which... can really be anything. #[allow(non_camel_case_types)] pub type id = *mut runtime::Object; @@ -86,5 +69,3 @@ pub type NSInteger = libc::c_long; /// Platform-specific. #[cfg(target_pointer_width = "64")] pub type NSUInteger = libc::c_ulong; - -pub type NSPoint = core_graphics::geometry::CGPoint; diff --git a/src/foundation/number.rs b/src/foundation/number.rs index ce980395..45cd861d 100644 --- a/src/foundation/number.rs +++ b/src/foundation/number.rs @@ -5,7 +5,7 @@ use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, to_bool, NSInteger, BOOL, NO, YES}; +use crate::foundation::{id, NSInteger}; /// Wrapper for a `NSNumber` object. /// @@ -23,12 +23,7 @@ impl NSNumber { /// Constructs a `numberWithBool` instance of `NSNumber` and retains it. pub fn bool(value: bool) -> Self { - NSNumber(unsafe { - msg_send_id![class!(NSNumber), numberWithBool:match value { - true => YES, - false => NO - }] - }) + NSNumber(unsafe { msg_send_id![class!(NSNumber), numberWithBool: value] }) } /// Constructs a `numberWithInteger` instance of `NSNumber` and retains it. @@ -73,20 +68,16 @@ impl NSNumber { unsafe { msg_send![&*self.0, doubleValue] } } - /// Pulls the underlying `BOOL` value out and passes it back as a `bool`. + /// Pulls the underlying `Bool` value out and passes it back as a `bool`. /// /// Note that this _does not check_ if the underlying type is actually this. You are /// responsible for doing so via the `objc_type()` method. pub fn as_bool(&self) -> bool { - let result: BOOL = unsafe { msg_send![&*self.0, boolValue] }; - - to_bool(result) + unsafe { msg_send![&*self.0, boolValue] } } /// A helper method for determining if a given `NSObject` is an `NSNumber`. pub fn is(obj: id) -> bool { - let result: BOOL = unsafe { msg_send![obj, isKindOfClass: class!(NSNumber)] }; - - to_bool(result) + unsafe { msg_send![obj, isKindOfClass: class!(NSNumber)] } } } diff --git a/src/foundation/string.rs b/src/foundation/string.rs index d6adbbe8..f1113b60 100644 --- a/src/foundation/string.rs +++ b/src/foundation/string.rs @@ -7,7 +7,7 @@ use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, to_bool, BOOL, NO, YES}; +use crate::foundation::id; const UTF8_ENCODING: usize = 4; @@ -49,7 +49,7 @@ impl<'a> NSString<'a> { initWithBytesNoCopy: s.as_ptr(), length: s.len(), encoding: UTF8_ENCODING, - freeWhenDone: NO, + freeWhenDone: false, ] }, @@ -75,8 +75,7 @@ impl<'a> NSString<'a> { /// Utility method for checking whether an `NSObject` is an `NSString`. pub fn is(obj: id) -> bool { - let result: BOOL = unsafe { msg_send![obj, isKindOfClass: class!(NSString)] }; - to_bool(result) + unsafe { msg_send![obj, isKindOfClass: class!(NSString)] } } /// Helper method for returning the UTF8 bytes for this `NSString`. diff --git a/src/foundation/urls/mod.rs b/src/foundation/urls/mod.rs index 103143f3..b63c3cd3 100644 --- a/src/foundation/urls/mod.rs +++ b/src/foundation/urls/mod.rs @@ -82,7 +82,7 @@ impl<'a> NSURL<'a> { pub fn bookmark_data( &self, options: &[NSURLBookmarkCreationOption], - resource_value_keys: &[NSURLResourceKey], + _resource_value_keys: &[NSURLResourceKey], relative_to_url: Option ) -> Result> { let mut opts: NSUInteger = 0; @@ -125,10 +125,10 @@ impl<'a> NSURL<'a> { /// Converts bookmark data into a URL. pub fn from_bookmark_data( - data: NSData, - options: &[NSURLBookmarkResolutionOption], - relative_to_url: Option, - data_is_stale: bool + _data: NSData, + _options: &[NSURLBookmarkResolutionOption], + _relative_to_url: Option, + _data_is_stale: bool ) -> Result> { Err("LOL".into()) } diff --git a/src/geometry.rs b/src/geometry.rs index 77ea7f36..89e07a9f 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,6 +1,6 @@ //! Wrapper methods for various geometry types (rects, sizes, ec). -use core_graphics::geometry::{CGPoint, CGRect, CGSize}; +use objc::foundation::{NSPoint, NSRect, NSSize}; /// A struct that represents a box - top, left, width and height. You might use this for, say, /// setting the initial frame of a view. @@ -49,19 +49,20 @@ pub enum Edge { MaxX = 2, MaxY = 3 } -impl From for CGRect { - fn from(rect: Rect) -> CGRect { - CGRect::new(&CGPoint::new(rect.left, rect.top), &CGSize::new(rect.width, rect.height)) + +impl From for NSRect { + fn from(rect: Rect) -> NSRect { + NSRect::new(NSPoint::new(rect.left, rect.top), NSSize::new(rect.width, rect.height)) } } -impl From for Rect { - fn from(rect: CGRect) -> Rect { +impl From for Rect { + fn from(rect: NSRect) -> Rect { Rect { top: rect.origin.y as f64, left: rect.origin.x as f64, - width: rect.size.width as f64, - height: rect.size.height as f64 + width: rect.size.width() as f64, + height: rect.size.height() as f64 } } } diff --git a/src/image/graphics_context.rs b/src/image/graphics_context.rs new file mode 100644 index 00000000..0d6fa9b6 --- /dev/null +++ b/src/image/graphics_context.rs @@ -0,0 +1,26 @@ +use std::ffi::c_void; + +use objc::rc::{Id, Shared}; +use objc::runtime::Object; +use objc::{class, msg_send, msg_send_id}; + +#[derive(Debug)] +pub(crate) struct GraphicsContext(pub Id); + +impl GraphicsContext { + pub(crate) fn current() -> Self { + Self(unsafe { msg_send_id![class!(NSGraphicsContext), currentContext] }) + } + + pub(crate) fn save(&self) { + unsafe { msg_send![&self.0, saveGraphicsState] } + } + + pub(crate) fn restore(&self) { + unsafe { msg_send![&self.0, restoreGraphicsState] } + } + + pub(crate) fn cg_context(&self) -> *mut c_void { + unsafe { msg_send![&self.0, CGContext] } + } +} diff --git a/src/image/image.rs b/src/image/image.rs index 1dcd2ebc..3fe99479 100644 --- a/src/image/image.rs +++ b/src/image/image.rs @@ -1,18 +1,16 @@ +use std::ffi::c_void; + +use objc::foundation::{CGFloat, NSPoint, NSRect, NSSize}; use objc::rc::{Id, Shared}; use objc::runtime::{Bool, Class, Object}; - use objc::{class, msg_send, msg_send_id, sel}; use block::ConcreteBlock; -use core_graphics::context::{CGContext, CGContextRef}; -use core_graphics::{ - base::CGFloat, - geometry::{CGPoint, CGRect, CGSize} -}; - +use super::graphics_context::GraphicsContext; use super::icons::*; use crate::foundation::{id, NSData, NSString, NSURL}; +use crate::geometry::Rect; use crate::utils::os; /// Specifies resizing behavior for image drawing. @@ -56,49 +54,47 @@ fn min_cgfloat(x: CGFloat, y: CGFloat) -> CGFloat { impl ResizeBehavior { /// Given a source and target rectangle, configures and returns a new rectangle configured with /// the resizing properties of this enum. - pub fn apply(&self, source: CGRect, target: CGRect) -> CGRect { + pub fn apply(&self, source: NSRect, target: NSRect) -> NSRect { // if equal, just return source - if source.origin.x == target.origin.x - && source.origin.y == target.origin.y - && source.size.width == target.size.width - && source.size.height == target.size.height - { + if source == target { return source; } - if source.origin.x == 0. && source.origin.y == 0. && source.size.width == 0. && source.size.height == 0. { + if source == NSRect::ZERO { return source; } - let mut scales = CGSize::new(0., 0.); - scales.width = (target.size.width / source.size.width).abs(); - scales.height = (target.size.height / source.size.height).abs(); + let mut scale_width = (target.size.width() / source.size.width()).abs(); + let mut scale_height = (target.size.height() / source.size.height()).abs(); match self { ResizeBehavior::AspectFit => { - scales.width = min_cgfloat(scales.width, scales.height); - scales.height = scales.width; + scale_width = min_cgfloat(scale_width, scale_height); + scale_height = scale_width; }, ResizeBehavior::AspectFill => { - scales.width = max_cgfloat(scales.width, scales.height); - scales.height = scales.width; + scale_width = max_cgfloat(scale_width, scale_height); + scale_height = scale_width; }, ResizeBehavior::Stretch => { /* will do this as default */ }, ResizeBehavior::Center => { - scales.width = 1.; - scales.height = 1.; + scale_width = 1.; + scale_height = 1.; } } - let mut result = source; - result.size.width *= scales.width; - result.size.height *= scales.height; - result.origin.x = target.origin.x + (target.size.width - result.size.width) / 2.; - result.origin.y = target.origin.y + (target.size.height - result.size.height) / 2.; - result + let result_size = NSSize::new(source.size.width() * scale_width, source.size.height() * scale_height); + + NSRect::new( + NSPoint::new( + target.origin.x + (target.size.width() - result_size.width()) / 2., + target.origin.y + (target.size.height() - result_size.height()) / 2. + ), + result_size + ) } } @@ -256,29 +252,34 @@ impl Image { #[cfg(feature = "appkit")] pub fn draw(config: DrawConfig, handler: F) -> Self where - F: Fn(CGRect, &CGContextRef) -> bool + 'static + F: Fn(Rect, (f64, f64), *mut c_void) -> bool + 'static { - let source_frame = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(config.source.0, config.source.1)); + let source_frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(config.source.0, config.source.1)); - let target_frame = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(config.target.0, config.target.1)); + let target_frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(config.target.0, config.target.1)); - let resized_frame = config.resize.apply(source_frame, target_frame); + let resized_frame: Rect = config.resize.apply(source_frame, target_frame).into(); - let block = ConcreteBlock::new(move |_destination: CGRect| unsafe { - let current_context: id = msg_send![class!(NSGraphicsContext), currentContext]; - let context_ptr: core_graphics::sys::CGContextRef = msg_send![current_context, CGContext]; - let context = CGContext::from_existing_context_ptr(context_ptr); - let _: () = msg_send![class!(NSGraphicsContext), saveGraphicsState]; + let block = ConcreteBlock::new(move |_destination: NSRect| { + let context = GraphicsContext::current(); + context.save(); - context.translate(resized_frame.origin.x, resized_frame.origin.y); - context.scale( - resized_frame.size.width / config.source.0, - resized_frame.size.height / config.source.1 - ); + let cg_context_ptr: *mut c_void = context.cg_context(); + + // TODO: Automatically scale for the user + // cg_context_ptr.translate(resized_frame.origin.x, resized_frame.origin.y); + // cg_context_ptr.scale( + // resized_frame.size.width() / config.source.0, + // resized_frame.size.height() / config.source.1 + // ); - let result = handler(resized_frame, &context); + let result = handler( + resized_frame, + (config.source.0 as f64, config.source.1 as f64), + cg_context_ptr + ); - let _: () = msg_send![class!(NSGraphicsContext), restoreGraphicsState]; + context.restore(); Bool::new(result) }); @@ -298,11 +299,11 @@ impl Image { #[test] fn test_image_from_bytes() { let image_bytes = include_bytes!("../../test-data/favicon.ico"); - let image = Image::with_data(image_bytes); + let _image = Image::with_data(image_bytes); } // It's unclear where the file is on the ios simulator. #[test] #[cfg(target_os = "macos")] fn test_image_from_file() { - let image = Image::with_contents_of_file("./test-data/favicon.ico"); + let _image = Image::with_contents_of_file("./test-data/favicon.ico"); } diff --git a/src/image/mod.rs b/src/image/mod.rs index 8b567235..a2d9b406 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -1,11 +1,9 @@ -use core_foundation::base::TCFType; - use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString}; use crate::layout::Layout; use crate::objc_access::ObjcAccess; use crate::utils::properties::ObjcProperty; @@ -26,6 +24,8 @@ mod uikit; #[cfg(all(feature = "uikit", not(feature = "appkit")))] use uikit::register_image_view_class; +mod graphics_context; + mod image; pub use image::{DrawConfig, Image, ResizeBehavior}; @@ -38,10 +38,10 @@ fn allocate_view(registration_fn: fn() -> &'static Class) -> id { let view: id = msg_send![registration_fn(), new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; view } @@ -151,7 +151,7 @@ impl ImageView { /// Call this to set the background color for the backing layer. pub fn set_background_color>(&self, color: C) { self.objc.with_mut(|obj| unsafe { - let cg = color.as_ref().cg_color().as_concrete_TypeRef(); + let cg = color.as_ref().cg_color(); let layer: id = msg_send![obj, layer]; let _: () = msg_send![layer, setBackgroundColor: cg]; }); diff --git a/src/image/uikit.rs b/src/image/uikit.rs index 1893abd1..8b02960e 100644 --- a/src/image/uikit.rs +++ b/src/image/uikit.rs @@ -6,5 +6,5 @@ use crate::foundation::load_or_register_class; /// 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_image_view_class() -> &'static Class { - load_or_register_class("UIImageView", "RSTImageView", |decl| unsafe {}) + load_or_register_class("UIImageView", "RSTImageView", |decl| {}) } diff --git a/src/input/mod.rs b/src/input/mod.rs index 3e1759e7..848bf705 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -43,15 +43,13 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. -use core_foundation::base::TCFType; - use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, sel}; use crate::color::Color; use crate::control::Control; -use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSInteger, NSString}; use crate::layout::Layout; use crate::objc_access::ObjcAccess; use crate::text::{Font, TextAlign}; @@ -83,10 +81,10 @@ fn common_init(class: &Class) -> id { let view: id = msg_send![class, new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; view } @@ -308,7 +306,7 @@ impl TextField { /// Call this to set the background color for the backing layer. pub fn set_background_color>(&self, color: C) { self.objc.with_mut(|obj| unsafe { - let cg = color.as_ref().cg_color().as_concrete_TypeRef(); + let cg = color.as_ref().cg_color(); let layer: id = msg_send![obj, layer]; let _: () = msg_send![layer, setBackgroundColor: cg]; }); @@ -353,10 +351,7 @@ impl TextField { pub fn set_uses_single_line(&self, uses_single_line: bool) { self.objc.with_mut(|obj| unsafe { let cell: id = msg_send![obj, cell]; - let _: () = msg_send![cell, setUsesSingleLineMode:match uses_single_line { - true => YES, - false => NO - }]; + let _: () = msg_send![cell, setUsesSingleLineMode: uses_single_line]; }); } @@ -364,10 +359,7 @@ impl TextField { pub fn set_wraps(&self, uses_single_line: bool) { self.objc.with_mut(|obj| unsafe { let cell: id = msg_send![obj, cell]; - let _: () = msg_send![cell, setWraps:match uses_single_line { - true => YES, - false => NO - }]; + let _: () = msg_send![cell, setWraps: uses_single_line]; }); } diff --git a/src/input/uikit.rs b/src/input/uikit.rs index 4f5e0b4b..858856ae 100644 --- a/src/input/uikit.rs +++ b/src/input/uikit.rs @@ -1,6 +1,6 @@ use std::sync::Once; -use objc::declare::ClassDecl; +use objc::declare::ClassBuilder; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, sel}; @@ -49,7 +49,7 @@ pub(crate) fn register_view_class() -> &'static Class { INIT.call_once(|| unsafe { let superclass = class!(UITextField); - let decl = ClassDecl::new("RSTTextInputField", superclass).unwrap(); + let decl = ClassBuilder::new("RSTTextInputField", superclass).unwrap(); VIEW_CLASS = Some(decl.register()); }); diff --git a/src/layer/mod.rs b/src/layer/mod.rs index c2023825..13014d91 100644 --- a/src/layer/mod.rs +++ b/src/layer/mod.rs @@ -12,8 +12,7 @@ //! view.layer.set_corner_radius(4.0); //! ``` -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; diff --git a/src/layout/animator.rs b/src/layout/animator.rs index 4fd1e3d4..471351a4 100644 --- a/src/layout/animator.rs +++ b/src/layout/animator.rs @@ -1,5 +1,4 @@ -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; diff --git a/src/layout/constraint.rs b/src/layout/constraint.rs index 76d6f7f0..1660522f 100644 --- a/src/layout/constraint.rs +++ b/src/layout/constraint.rs @@ -2,13 +2,12 @@ //! escape hatch, if you need it (we use it for things like width and height, which aren't handled //! by an axis). -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, sel}; -use crate::foundation::{id, NO, YES}; +use crate::foundation::id; #[cfg(all(feature = "appkit", target_os = "macos"))] use super::LayoutConstraintAnimatorProxy; @@ -84,10 +83,7 @@ impl LayoutConstraint { /// `LayoutConstraint::deactivate()`. pub fn set_active(&self, active: bool) { unsafe { - let _: () = msg_send![&*self.constraint, setActive:match active { - true => YES, - false => NO - }]; + let _: () = msg_send![&*self.constraint, setActive: active]; } } diff --git a/src/layout/dimension.rs b/src/layout/dimension.rs index d97fd3a9..ac9c4280 100644 --- a/src/layout/dimension.rs +++ b/src/layout/dimension.rs @@ -1,5 +1,4 @@ -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; diff --git a/src/layout/traits.rs b/src/layout/traits.rs index 6249b175..ead2f58e 100644 --- a/src/layout/traits.rs +++ b/src/layout/traits.rs @@ -1,14 +1,12 @@ //! Various traits related to controllers opting in to autolayout routines and support for view //! heirarchies. -use core_graphics::base::CGFloat; -use core_graphics::geometry::{CGPoint, CGRect, CGSize}; - +use objc::foundation::{CGFloat, NSRect}; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{msg_send, sel}; -use crate::foundation::{id, nil, to_bool, NSArray, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString}; use crate::geometry::Rect; use crate::objc_access::ObjcAccess; @@ -25,10 +23,7 @@ pub trait Layout: ObjcAccess { /// `false`. fn set_needs_display(&self, needs_display: bool) { self.with_backing_obj_mut(|obj| unsafe { - let _: () = msg_send![obj, setNeedsDisplay:match needs_display { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setNeedsDisplay: needs_display]; }); } @@ -53,8 +48,8 @@ pub trait Layout: ObjcAccess { /// 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(); + fn set_frame>(&self, rect: R) { + let frame: NSRect = rect.into(); self.with_backing_obj_mut(move |backing_node| unsafe { let _: () = msg_send![backing_node, setFrame: frame]; @@ -69,10 +64,7 @@ pub trait Layout: ObjcAccess { #[cfg(feature = "autolayout")] fn set_translates_autoresizing_mask_into_constraints(&self, translates: bool) { self.with_backing_obj_mut(|backing_node| unsafe { - let _: () = msg_send![backing_node, setTranslatesAutoresizingMaskIntoConstraints:match translates { - true => YES, - false => NO - }]; + let _: () = msg_send![backing_node, setTranslatesAutoresizingMaskIntoConstraints: translates]; }); } @@ -81,10 +73,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 { - let _: () = msg_send![obj, setHidden:match hide { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setHidden: hide]; }); } @@ -93,13 +82,13 @@ 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] })) + self.get_from_backing_obj(|obj| 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] })) + self.get_from_backing_obj(|obj| unsafe { msg_send![obj, isHiddenOrHasHiddenAncestor] }) } /// Register this view for drag and drop operations. @@ -141,10 +130,7 @@ pub trait Layout: ObjcAccess { #[cfg(feature = "appkit")] fn set_posts_frame_change_notifications(&self, posts: bool) { self.with_backing_obj_mut(|obj| unsafe { - let _: () = msg_send![obj, setPostsFrameChangedNotifications:match posts { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setPostsFrameChangedNotifications: posts]; }); } @@ -155,10 +141,7 @@ pub trait Layout: ObjcAccess { #[cfg(feature = "appkit")] fn set_posts_bounds_change_notifications(&self, posts: bool) { self.with_backing_obj_mut(|obj| unsafe { - let _: () = msg_send![obj, setPostsBoundsChangedNotifications:match posts { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setPostsBoundsChangedNotifications: posts]; }); } diff --git a/src/lib.rs b/src/lib.rs index cfe5f5e3..23843828 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,8 +92,6 @@ //! //! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section -pub use core_foundation; -pub use core_graphics; pub use lazy_static; pub use objc; pub use url; diff --git a/src/listview/appkit.rs b/src/listview/appkit.rs index f713abc0..2f808b76 100644 --- a/src/listview/appkit.rs +++ b/src/listview/appkit.rs @@ -30,11 +30,11 @@ extern "C" fn view_for_column( _table_column: id, item: NSInteger ) -> id { - /*use core_graphics::geometry::CGRect; + /*use objc::foundation::NSRect; unsafe { //let superview: id = msg_send![table_view, superview]; - let frame: CGRect = msg_send![table_view, frame]; - let _: () = msg_send![table_column, setWidth:frame.size.width]; + let frame: NSRect = msg_send![table_view, frame]; + let _: () = msg_send![table_column, setWidth:frame.size.width()]; }*/ let view = load::(this, LISTVIEW_DELEGATE_PTR); diff --git a/src/listview/mod.rs b/src/listview/mod.rs index 7f239be1..7eee449a 100644 --- a/src/listview/mod.rs +++ b/src/listview/mod.rs @@ -44,15 +44,13 @@ use std::collections::HashMap; -use core_foundation::base::TCFType; - -use core_graphics::base::CGFloat; +use objc::foundation::CGFloat; use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, msg_send_id, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger}; use crate::layout::Layout; #[cfg(feature = "autolayout")] @@ -61,7 +59,7 @@ use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY}; use crate::objc_access::ObjcAccess; use crate::scrollview::ScrollView; use crate::utils::properties::{ObjcProperty, PropertyNullable}; -use crate::utils::{os, CGSize, CellFactory}; +use crate::utils::{os, CellFactory}; use crate::view::{ViewAnimatorProxy, ViewDelegate}; #[cfg(feature = "appkit")] @@ -114,13 +112,13 @@ fn common_init(class: &Class) -> id { let _: () = msg_send![menu, setDelegate: tableview]; let _: () = msg_send![tableview, setMenu: menu]; - let _: () = msg_send![tableview, setWantsLayer: YES]; - let _: () = msg_send![tableview, setUsesAutomaticRowHeights: YES]; - let _: () = msg_send![tableview, setFloatsGroupRows: YES]; - //let _: () = msg_send![tableview, setIntercellSpacing:CGSize::new(0., 0.)]; + let _: () = msg_send![tableview, setWantsLayer: true]; + let _: () = msg_send![tableview, setUsesAutomaticRowHeights: true]; + let _: () = msg_send![tableview, setFloatsGroupRows: true]; + //let _: () = msg_send![tableview, setIntercellSpacing: NSSize::new(0., 0.)]; let _: () = msg_send![tableview, setColumnAutoresizingStyle:1]; //msg_send![tableview, setSelectionHighlightStyle:-1]; - //let _: () = msg_send![tableview, setAllowsMultipleSelection:NO]; + //let _: () = msg_send![tableview, setAllowsMultipleSelection: false]; let _: () = msg_send![tableview, setHeaderView: nil]; // NSTableView requires at least one column to be manually added if doing so by code. @@ -441,7 +439,7 @@ impl ListView { pub fn set_background_color>(&self, color: C) { // @TODO: This is wrong. self.objc.with_mut(|obj| unsafe { - let color = color.as_ref().cg_color().as_concrete_TypeRef(); + let color = color.as_ref().cg_color(); let layer: id = msg_send![obj, layer]; let _: () = msg_send![layer, setBackgroundColor: color]; }); @@ -469,10 +467,7 @@ impl ListView { #[cfg(feature = "appkit")] pub fn set_allows_empty_selection(&self, allows: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setAllowsEmptySelection:match allows { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setAllowsEmptySelection: allows]; }); } @@ -493,10 +488,7 @@ impl ListView { } self.objc.with_mut(|obj| { - let _: () = msg_send![obj, selectRowIndexes: &*index_set, byExtendingSelection: match extends_existing { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, selectRowIndexes: &*index_set, byExtendingSelection: extends_existing]; }); } } @@ -658,10 +650,7 @@ impl ListView { pub fn set_uses_automatic_row_heights(&self, uses: bool) { #[cfg(feature = "appkit")] self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setUsesAutomaticRowHeights:match uses { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setUsesAutomaticRowHeights: uses]; }); } @@ -671,10 +660,7 @@ impl ListView { pub fn set_uses_alternating_backgrounds(&self, uses: bool) { #[cfg(feature = "appkit")] self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setUsesAlternatingRowBackgroundColors:match uses { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setUsesAlternatingRowBackgroundColors: uses]; }); } @@ -682,10 +668,7 @@ impl ListView { pub fn set_row_actions_visible(&self, visible: bool) { #[cfg(feature = "appkit")] self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setRowActionsVisible:match visible { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setRowActionsVisible: visible]; }); } diff --git a/src/listview/row/appkit.rs b/src/listview/row/appkit.rs index d7ed7356..e989d681 100644 --- a/src/listview/row/appkit.rs +++ b/src/listview/row/appkit.rs @@ -18,7 +18,7 @@ use crate::utils::load; /// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though. extern "C" fn enforce_normalcy(_: &Object, _: Sel) -> Bool { - return Bool::YES; + Bool::YES } /// Called when a drag/drop operation has entered this view. @@ -69,7 +69,7 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, info: /// Called for layer updates. extern "C" fn update_layer(this: &Object, _: Sel) { unsafe { - let background_color: id = *this.get_ivar(BACKGROUND_COLOR); + let background_color: id = *this.ivar(BACKGROUND_COLOR); if background_color != nil { let layer: id = msg_send![this, layer]; @@ -86,7 +86,7 @@ extern "C" fn update_layer(this: &Object, _: Sel) { extern "C" fn dealloc(this: &Object, _: Sel) { // Load the Box pointer here, and just let it drop normally. unsafe { - let ptr: usize = *(&*this).get_ivar(LISTVIEW_ROW_DELEGATE_PTR); + let ptr: usize = *(&*this).ivar(LISTVIEW_ROW_DELEGATE_PTR); let obj = ptr as *mut T; let _x = Box::from_raw(obj); diff --git a/src/listview/row/mod.rs b/src/listview/row/mod.rs index ef6342d8..78954fd0 100644 --- a/src/listview/row/mod.rs +++ b/src/listview/row/mod.rs @@ -50,7 +50,7 @@ use objc::runtime::{Class, Object}; use objc::{class, msg_send, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString}; use crate::layer::Layer; use crate::layout::Layout; use crate::objc_access::ObjcAccess; @@ -82,10 +82,10 @@ fn allocate_view(registration_fn: fn() -> &'static Class) -> id { let view: id = msg_send![registration_fn(), new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; view } @@ -221,7 +221,7 @@ where pub(crate) fn from_cached(view: id) -> ListViewRow { // @TODO: Make this better. let delegate = unsafe { - let ptr: usize = *(&*view).get_ivar(LISTVIEW_ROW_DELEGATE_PTR); + let ptr: usize = *(&*view).ivar(LISTVIEW_ROW_DELEGATE_PTR); let obj = ptr as *mut T; Box::from_raw(obj) //&*obj diff --git a/src/listview/row/uikit.rs b/src/listview/row/uikit.rs index 72fcd4ec..ca58cc02 100644 --- a/src/listview/row/uikit.rs +++ b/src/listview/row/uikit.rs @@ -1,10 +1,9 @@ -use objc::declare::ClassDecl; -use objc::runtime::{Class, Object, Sel, BOOL}; -use objc::{class, sel}; use objc::rc::{Id, Owned}; +use objc::runtime::{Class, Object, Sel}; +use objc::{class, sel}; use crate::dragdrop::DragInfo; -use crate::foundation::{id, NSUInteger, NO, YES}; +use crate::foundation::{id, NSUInteger}; use crate::utils::load; use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; diff --git a/src/progress/mod.rs b/src/progress/mod.rs index 9de32950..802a8492 100644 --- a/src/progress/mod.rs +++ b/src/progress/mod.rs @@ -15,14 +15,13 @@ //! my_view.add_subview(&indicator); //! ``` -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, NSUInteger}; use crate::layout::Layout; use crate::objc_access::ObjcAccess; use crate::utils::properties::ObjcProperty; @@ -95,10 +94,10 @@ impl ProgressIndicator { let view: id = msg_send![class!(NSProgressIndicator), new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; view }; @@ -177,10 +176,7 @@ impl ProgressIndicator { /// Invert this to go back to a bar appearance. pub fn set_indeterminate(&self, is_indeterminate: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setIndeterminate:match is_indeterminate { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setIndeterminate: is_indeterminate]; }); } @@ -198,10 +194,7 @@ impl ProgressIndicator { /// Set whether this control is hidden or not. pub fn set_hidden(&self, hidden: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setHidden:match hidden { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setHidden: hidden]; }); } } diff --git a/src/quicklook/config.rs b/src/quicklook/config.rs index 773b5af3..19f10e1e 100644 --- a/src/quicklook/config.rs +++ b/src/quicklook/config.rs @@ -1,12 +1,11 @@ use std::path::Path; -use core_graphics::base::CGFloat; +use objc::foundation::{CGFloat, NSSize}; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, sel}; -use crate::foundation::{id, NSString, NSUInteger, YES}; -use crate::utils::CGSize; +use crate::foundation::{id, NSString, NSUInteger}; /// Describes the quality of the thumbnail you expect back from the /// generator service. @@ -107,7 +106,7 @@ impl ThumbnailConfig { } unsafe { - let size = CGSize::new(self.size.0, self.size.1); + let size = NSSize::new(self.size.0, self.size.1); // @TODO: Check nil here, or other bad conversion let from_url: id = msg_send![class!(NSURL), fileURLWithPath:&*file]; @@ -118,7 +117,7 @@ impl ThumbnailConfig { representationTypes:types]; if self.icon_mode { - let _: () = msg_send![request, setIconMode: YES]; + let _: () = msg_send![request, setIconMode: true]; } if self.minimum_dimension != 0. { diff --git a/src/scrollview/appkit.rs b/src/scrollview/appkit.rs index 4360ff82..8c4a201a 100644 --- a/src/scrollview/appkit.rs +++ b/src/scrollview/appkit.rs @@ -18,7 +18,7 @@ use crate::utils::load; /// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though. extern "C" fn enforce_normalcy(_: &Object, _: Sel) -> Bool { - return Bool::YES; + Bool::YES } /// Called when a drag/drop operation has entered this view. diff --git a/src/scrollview/mod.rs b/src/scrollview/mod.rs index e945c14d..783c5550 100644 --- a/src/scrollview/mod.rs +++ b/src/scrollview/mod.rs @@ -42,14 +42,12 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. -use core_foundation::base::TCFType; - use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString}; use crate::layout::Layout; use crate::objc_access::ObjcAccess; use crate::utils::properties::ObjcProperty; @@ -80,15 +78,15 @@ fn allocate_view(registration_fn: fn() -> &'static Class) -> id { let view: id = msg_send![registration_fn(), new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] { - let _: () = msg_send![view, setDrawsBackground: NO]; - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setDrawsBackground: false]; + let _: () = msg_send![view, setWantsLayer: true]; let _: () = msg_send![view, setBorderType:0]; let _: () = msg_send![view, setHorizontalScrollElasticity:1]; - let _: () = msg_send![view, setHasVerticalScroller: YES]; + let _: () = msg_send![view, setHasVerticalScroller: true]; } view @@ -298,7 +296,7 @@ impl ScrollView { pub fn set_background_color>(&self, color: C) { // @TODO: This is wrong. self.objc.with_mut(|obj| unsafe { - let color = color.as_ref().cg_color().as_concrete_TypeRef(); + let color = color.as_ref().cg_color(); let layer: id = msg_send![obj, layer]; let _: () = msg_send![layer, setBackgroundColor: color]; }); diff --git a/src/scrollview/uikit.rs b/src/scrollview/uikit.rs index 9f3bb849..88dbd2fa 100644 --- a/src/scrollview/uikit.rs +++ b/src/scrollview/uikit.rs @@ -9,7 +9,7 @@ use std::sync::Once; -use objc::declare::ClassDecl; +use objc::declare::ClassBuilder; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, sel}; @@ -77,7 +77,7 @@ pub(crate) fn register_scrollview_class() -> &'static Class { INIT.call_once(|| unsafe { let superclass = class!(UIScrollView); - let decl = ClassDecl::new("RSTScrollView", superclass).unwrap(); + let decl = ClassBuilder::new("RSTScrollView", superclass).unwrap(); VIEW_CLASS = Some(decl.register()); }); @@ -92,7 +92,7 @@ pub(crate) fn register_scrollview_class_with_delegate() - INIT.call_once(|| unsafe { let superclass = class!(UIScrollView); - let mut decl = ClassDecl::new("RSTScrollViewWithDelegate", superclass).unwrap(); + let mut decl = ClassBuilder::new("RSTScrollViewWithDelegate", superclass).unwrap(); // A pointer to the "view controller" on the Rust side. It's expected that this doesn't // move. diff --git a/src/select/mod.rs b/src/select/mod.rs index 02b1e0ed..49bf1102 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1,12 +1,12 @@ //! Implements a Select-style dropdown. By default this uses NSPopupSelect on macOS. -use core_graphics::geometry::CGRect; +use objc::foundation::NSRect; use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; use crate::control::Control; -use crate::foundation::{id, load_or_register_class, nil, NSInteger, NSString, NO, YES}; +use crate::foundation::{id, load_or_register_class, nil, NSInteger, NSString}; use crate::geometry::Rect; use crate::invoker::TargetActionHandler; use crate::layout::Layout; @@ -85,14 +85,14 @@ impl Select { /// Creates a new `Select` instance, configures it appropriately, /// and retains the necessary Objective-C runtime pointer. pub fn new() -> Self { - let zero: CGRect = Rect::zero().into(); + let zero: NSRect = Rect::zero().into(); let view: id = unsafe { let alloc: id = msg_send![register_class(), alloc]; - let select: id = msg_send![alloc, initWithFrame:zero pullsDown:NO]; + let select: id = msg_send![alloc, initWithFrame:zero, pullsDown: false]; #[cfg(feature = "autolayout")] - let _: () = msg_send![select, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![select, setTranslatesAutoresizingMaskIntoConstraints: false]; select }; @@ -150,10 +150,7 @@ impl Select { /// Sets whether this pulls down (dropdown) or pops up. pub fn set_pulls_down(&self, pulls_down: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setPullsDown:match pulls_down { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setPullsDown: pulls_down]; }); } diff --git a/src/switch.rs b/src/switch.rs index 601ac901..7111eed0 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -5,7 +5,7 @@ use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; -use crate::foundation::{id, load_or_register_class, nil, NSString, NO}; +use crate::foundation::{id, load_or_register_class, nil, NSString}; use crate::invoker::TargetActionHandler; use crate::layout::Layout; #[cfg(feature = "autolayout")] @@ -72,7 +72,7 @@ impl Switch { let button: id = msg_send![register_class(), buttonWithTitle: &*title, target: nil, action: nil]; #[cfg(feature = "autolayout")] - let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] let _: () = msg_send![button, setButtonType:3]; diff --git a/src/text/attributed_string.rs b/src/text/attributed_string.rs index e5b63666..54199592 100644 --- a/src/text/attributed_string.rs +++ b/src/text/attributed_string.rs @@ -3,13 +3,13 @@ use std::ops::{Deref, DerefMut, Range}; use std::os::raw::c_char; use std::{fmt, slice, str}; +use objc::foundation::NSRange; use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; use crate::color::Color; -use crate::foundation::{id, to_bool, NSString, BOOL, NO, YES}; -use crate::utils::CFRange; +use crate::foundation::{id, NSString}; use super::Font; @@ -43,9 +43,9 @@ impl AttributedString { } /// Sets the text (foreground) color for the specified range. - pub fn set_text_color>(&mut self, color: C, range: Range) { + pub fn set_text_color>(&mut self, color: C, range: Range) { let color: id = color.as_ref().into(); - let range = CFRange::init(range.start, range.end); + let range = NSRange::from(range); unsafe { let _: () = msg_send![ @@ -58,8 +58,8 @@ impl AttributedString { } /// Set the font for the specified range. - pub fn set_font(&mut self, font: Font, range: Range) { - let range = CFRange::init(range.start, range.end); + pub fn set_font(&mut self, font: Font, range: Range) { + let range = NSRange::from(range); unsafe { let _: () = msg_send![ diff --git a/src/text/font.rs b/src/text/font.rs index cfc2f87c..2c0072ce 100644 --- a/src/text/font.rs +++ b/src/text/font.rs @@ -2,13 +2,12 @@ use std::ops::Deref; -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, nil, NSArray, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSString}; use crate::utils::os; /// A `Font` can be constructed and applied to supported controls to control things like text diff --git a/src/text/label/mod.rs b/src/text/label/mod.rs index 23cb7de8..1d490d94 100644 --- a/src/text/label/mod.rs +++ b/src/text/label/mod.rs @@ -43,14 +43,12 @@ //! //! For more information on Autolayout, view the module or check out the examples folder. -use core_foundation::base::TCFType; - use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger}; use crate::layer::Layer; use crate::layout::Layout; use crate::objc_access::ObjcAccess; @@ -87,7 +85,7 @@ fn allocate_view(registration_fn: fn() -> &'static Class) -> id { let label: id = msg_send![registration_fn(), wrappingLabelWithString:&*blank]; // We sub this in to get the general expected behavior for 202*. - let _: () = msg_send![label, setSelectable: NO]; + let _: () = msg_send![label, setSelectable: false]; label }; @@ -96,10 +94,10 @@ fn allocate_view(registration_fn: fn() -> &'static Class) -> id { let view: id = msg_send![registration_fn(), new]; #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; view } @@ -326,7 +324,7 @@ impl Label { // @TODO: This is wrong. // Needs to set ivar and such, akin to View. self.objc.with_mut(|obj| unsafe { - let color = color.as_ref().cg_color().as_concrete_TypeRef(); + let color = color.as_ref().cg_color(); let layer: id = msg_send![obj, layer]; let _: () = msg_send![layer, setBackgroundColor: color]; }); @@ -409,10 +407,7 @@ impl Label { /// Set whether this is hidden or not. pub fn set_hidden(&self, hidden: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![obj, setHidden:match hidden { - true => YES, - false => NO - }]; + let _: () = msg_send![obj, setHidden: hidden]; }); } @@ -432,7 +427,7 @@ impl Label { self.objc.with_mut(|obj| unsafe { let cell: id = msg_send![obj, cell]; let mode = mode as NSUInteger; - let _: () = msg_send![cell, setTruncatesLastVisibleLine: YES]; + let _: () = msg_send![cell, setTruncatesLastVisibleLine: true]; let _: () = msg_send![cell, setLineBreakMode: mode]; }); } diff --git a/src/text/label/uikit.rs b/src/text/label/uikit.rs index d7e0e9a1..39a674fd 100644 --- a/src/text/label/uikit.rs +++ b/src/text/label/uikit.rs @@ -1,10 +1,10 @@ use std::sync::Once; -use objc::declare::ClassDecl; -use objc::runtime::{Class, Object, Sel, BOOL}; +use objc::declare::ClassBuilder; +use objc::runtime::{Class, Object, Sel}; use objc::{class, sel}; -use crate::foundation::{id, NSUInteger, NO, YES}; +use crate::foundation::{id, NSUInteger}; use crate::text::label::{LabelDelegate, LABEL_DELEGATE_PTR}; /// Injects an `UILabel` subclass. This is used for the default views that don't use delegates - we @@ -16,7 +16,7 @@ pub(crate) fn register_view_class() -> &'static Class { INIT.call_once(|| unsafe { let superclass = class!(UILabel); - let decl = ClassDecl::new("RSTTextField", superclass).unwrap(); + let decl = ClassBuilder::new("RSTTextField", superclass).unwrap(); VIEW_CLASS = Some(decl.register()); }); @@ -31,7 +31,7 @@ pub(crate) fn register_view_class_with_delegate() -> &'static INIT.call_once(|| unsafe { let superclass = class!(UIView); - let mut decl = ClassDecl::new("RSTTextFieldWithDelegate", superclass).unwrap(); + let mut decl = ClassBuilder::new("RSTTextFieldWithDelegate", superclass).unwrap(); // A pointer to the "view controller" on the Rust side. It's expected that this doesn't // move. diff --git a/src/uikit/app/delegate.rs b/src/uikit/app/delegate.rs index 8c736675..420c1391 100644 --- a/src/uikit/app/delegate.rs +++ b/src/uikit/app/delegate.rs @@ -19,9 +19,9 @@ use crate::uikit::scene::{SceneConnectionOptions, SceneSession}; /// A handy method for grabbing our `AppDelegate` from the pointer. This is different from our /// standard `utils` version as this doesn't require `RefCell` backing. -fn app(this: &Object) -> &T { +fn app(_this: &Object) -> &T { unsafe { - //let app_ptr: usize = *this.get_ivar(APP_DELEGATE); + //let app_ptr: usize = *this.ivar(APP_DELEGATE); let app = APP_DELEGATE as *const T; &*app } diff --git a/src/uikit/app/mod.rs b/src/uikit/app/mod.rs index eb9367ed..9da6d815 100644 --- a/src/uikit/app/mod.rs +++ b/src/uikit/app/mod.rs @@ -40,7 +40,7 @@ use std::ffi::CString; use objc::runtime::Object; use objc::{class, msg_send, sel}; -use crate::foundation::{id, nil, AutoReleasePool, NSString, NSUInteger, NO, YES}; +use crate::foundation::{id, nil, AutoReleasePool, NSString, NSUInteger}; use crate::notification_center::Dispatcher; use crate::uikit::scene::{register_window_scene_delegate_class, WindowSceneDelegate}; use crate::utils::activate_cocoa_multithreading; @@ -115,9 +115,9 @@ where activate_cocoa_multithreading(); let pool = AutoReleasePool::new(); - let cls = register_app_class(); - let dl = register_app_delegate_class::(); - let w = register_window_scene_delegate_class::(); + let _cls = register_app_class(); + let _dl = register_app_delegate_class::(); + let _w = register_window_scene_delegate_class::(); let app_delegate = Box::new(delegate); let vendor = Box::new(scene_delegate_vendor); diff --git a/src/uikit/scene/mod.rs b/src/uikit/scene/mod.rs index b54ee965..80a3cc93 100644 --- a/src/uikit/scene/mod.rs +++ b/src/uikit/scene/mod.rs @@ -3,8 +3,7 @@ //! This is required for things like having multiple instances of your app in the app switcher on //! iPad. In general, you probably won't need to tweak this though. -use core_graphics::geometry::CGRect; - +use objc::foundation::NSRect; use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, sel}; @@ -43,7 +42,7 @@ impl Scene { pub fn get_bounds(&self) -> Rect { unsafe { let coordinate_space: id = msg_send![&*self.0, coordinateSpace]; - let rect: CGRect = msg_send![coordinate_space, bounds]; + let rect: NSRect = msg_send![coordinate_space, bounds]; rect } .into() diff --git a/src/uikit/window/mod.rs b/src/uikit/window/mod.rs index 5431eb20..357fa1e5 100644 --- a/src/uikit/window/mod.rs +++ b/src/uikit/window/mod.rs @@ -1,5 +1,4 @@ -use core_graphics::geometry::CGRect; - +use objc::foundation::NSRect; use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; @@ -15,7 +14,7 @@ pub struct Window(pub Id); impl Window { pub fn new(frame: Rect) -> Self { Window(unsafe { - let rect: CGRect = frame.into(); + let rect: NSRect = frame.into(); let alloc = msg_send_id![class!(UIWindow), alloc]; msg_send_id![alloc, initWithFrame: rect] }) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index b709cf2b..2c9f019f 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,16 +2,12 @@ //! belong to. These are typically internal, and if you rely on them... well, don't be surprised if //! they go away one day. -use core_foundation::base::CFIndex; -use core_graphics::base::CGFloat; - -use objc::{class, msg_send, sel}; - use objc::rc::{Id, Shared}; use objc::runtime::Object; +use objc::{class, msg_send, sel}; use objc::{Encode, Encoding}; -use crate::foundation::{id, BOOL, NO, YES}; +use crate::foundation::id; mod cell_factory; pub use cell_factory::CellFactory; @@ -44,7 +40,7 @@ pub trait Controller { /// checking. pub fn load<'a, T>(this: &'a Object, ptr_name: &str) -> &'a T { unsafe { - let ptr: usize = *this.get_ivar(ptr_name); + let ptr: usize = *this.ivar(ptr_name); let obj = ptr as *const T; &*obj } @@ -68,54 +64,6 @@ where queue.exec_sync(method); } -/// Upstream core graphics does not implement Encode for certain things, so we wrap them here - -/// these are only used in reading certain types passed to us from some delegate methods. -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct CGSize { - /// The width of this size. - pub width: CGFloat, - - /// The height of this size. - pub height: CGFloat -} - -impl CGSize { - /// Create and return a new `CGSize`. - pub fn new(width: CGFloat, height: CGFloat) -> Self { - CGSize { width, height } - } - - /// Create and return a `CGSizeZero` equivalent. - pub fn zero() -> Self { - CGSize { width: 0., height: 0. } - } -} - -unsafe impl Encode for CGSize { - const ENCODING: Encoding = Encoding::Struct("CGSize", &[CGFloat::ENCODING, CGFloat::ENCODING]); -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct CFRange { - pub location: CFIndex, - pub length: CFIndex -} - -impl CFRange { - pub fn init(location: CFIndex, length: CFIndex) -> CFRange { - CFRange { - location: location, - length: length - } - } -} - -unsafe impl Encode for CFRange { - const ENCODING: Encoding = Encoding::Struct("CFRange", &[CFIndex::ENCODING, CFIndex::ENCODING]); -} - /// A helper method for ensuring that Cocoa is running in multi-threaded mode. /// /// Why do we need this? According to Apple, if you're going to make use of standard POSIX threads, diff --git a/src/view/animator.rs b/src/view/animator.rs index 3aca87b6..2dd12c37 100644 --- a/src/view/animator.rs +++ b/src/view/animator.rs @@ -1,5 +1,4 @@ -use core_graphics::base::CGFloat; - +use objc::foundation::CGFloat; use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; diff --git a/src/view/appkit.rs b/src/view/appkit.rs index 309a31ca..ded30df0 100644 --- a/src/view/appkit.rs +++ b/src/view/appkit.rs @@ -7,7 +7,6 @@ //! 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 objc::declare::ClassDecl; use objc::rc::{Id, Owned}; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, sel}; @@ -19,7 +18,7 @@ use crate::view::{ViewDelegate, BACKGROUND_COLOR, VIEW_DELEGATE_PTR}; /// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though. extern "C" fn enforce_normalcy(_: &Object, _: Sel) -> Bool { - return Bool::YES; + Bool::YES } /// Called when a drag/drop operation has entered this view. @@ -70,7 +69,7 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, info: /// Called for layer updates. extern "C" fn update_layer(this: &Object, _: Sel) { unsafe { - let background_color: id = *this.get_ivar(BACKGROUND_COLOR); + let background_color: id = *this.ivar(BACKGROUND_COLOR); if background_color != nil { let layer: id = msg_send![this, layer]; diff --git a/src/view/controller/appkit.rs b/src/view/controller/appkit.rs index d209dba8..a2a5e76c 100644 --- a/src/view/controller/appkit.rs +++ b/src/view/controller/appkit.rs @@ -2,7 +2,6 @@ use std::sync::Once; -use objc::declare::ClassDecl; use objc::runtime::{Class, Object, Sel}; use objc::{class, msg_send, sel}; diff --git a/src/view/controller/uikit.rs b/src/view/controller/uikit.rs index c5737773..5dbf4bf9 100644 --- a/src/view/controller/uikit.rs +++ b/src/view/controller/uikit.rs @@ -1,7 +1,6 @@ use std::sync::Once; use std::unreachable; -use objc::declare::ClassDecl; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, sel}; diff --git a/src/view/mod.rs b/src/view/mod.rs index c0e1a334..529f0748 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -46,7 +46,7 @@ use objc::runtime::{Class, Object}; use objc::{msg_send, msg_send_id, sel}; use crate::color::Color; -use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NO, YES}; +use crate::foundation::{id, nil, NSArray, NSInteger, NSString}; use crate::layer::Layer; use crate::layout::Layout; use crate::objc_access::ObjcAccess; @@ -172,12 +172,13 @@ impl View { /// This handles grabbing autolayout anchor pointers, as well as things related to layering and /// so on. It returns a generic `View`, which the caller can then customize as needed. pub(crate) fn init(view: id) -> View { + #[allow(unused_unsafe)] unsafe { #[cfg(feature = "autolayout")] - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; } View { @@ -341,10 +342,7 @@ impl View { #[cfg(feature = "appkit")] pub fn set_can_draw_subviews_into_layer(&self, can: bool) { self.objc.with_mut(|obj| unsafe { - let _: () = msg_send![&*obj, setCanDrawSubviewsIntoLayer:match can { - true => YES, - false => NO - }]; + let _: () = msg_send![&*obj, setCanDrawSubviewsIntoLayer: can]; }); } } diff --git a/src/view/popover/mod.rs b/src/view/popover/mod.rs index 1beeb129..d6ca3914 100644 --- a/src/view/popover/mod.rs +++ b/src/view/popover/mod.rs @@ -1,4 +1,4 @@ -use core_graphics::geometry::CGRect; +use objc::foundation::{NSRect, NSSize}; use objc::rc::{Id, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; @@ -13,7 +13,7 @@ use crate::appkit::App; use crate::foundation::{id, nil, NSString}; use crate::geometry::{Edge, Rect}; use crate::layout::Layout; -use crate::utils::{os, CGSize, Controller}; +use crate::utils::{os, Controller}; use crate::view::{View, ViewController, ViewDelegate}; #[derive(Debug, Eq, PartialEq)] @@ -29,7 +29,7 @@ pub enum PopoverBehaviour { #[derive(Debug)] pub struct PopoverConfig { - pub content_size: CGSize, + pub content_size: NSSize, pub animates: bool, pub behaviour: PopoverBehaviour } @@ -37,10 +37,7 @@ pub struct PopoverConfig { impl Default for PopoverConfig { fn default() -> Self { Self { - content_size: CGSize { - width: 320.0, - height: 320.0 - }, + content_size: NSSize::new(320.0, 320.0), animates: true, behaviour: PopoverBehaviour::Transient } @@ -79,7 +76,7 @@ where impl Popover { /// Show a popover relative to a view pub fn show_popover(&self, relative_to: Rect, view: &V, edge: Edge) { - let rect: CGRect = relative_to.into(); + let rect: NSRect = relative_to.into(); unsafe { view.with_backing_obj_mut(|obj| { let _: () = msg_send![&*self.objc, showRelativeToRect:rect ofView: &*obj preferredEdge: edge as u32]; @@ -93,7 +90,7 @@ impl Popover { let window = App::main_window(); unsafe { let content_view = window.content_view(); - let rect: CGRect = rect.into(); + let rect: NSRect = rect.into(); let _: () = msg_send![&*self.objc, showRelativeToRect:rect ofView: content_view preferredEdge: edge as u32]; } } diff --git a/src/view/splitviewcontroller/ios.rs b/src/view/splitviewcontroller/ios.rs index 744f3fdf..c65e5fef 100644 --- a/src/view/splitviewcontroller/ios.rs +++ b/src/view/splitviewcontroller/ios.rs @@ -1,4 +1,3 @@ -use objc::declare::ClassDecl; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, sel}; @@ -52,13 +51,7 @@ pub(crate) fn register_view_controller_class() -> &'s decl.add_method(sel!(viewWillAppear:), will_appear:: as extern "C" fn(_, _, _)); decl.add_method(sel!(viewDidAppear:), did_appear:: as extern "C" fn(_, _, _)); - decl.add_method( - sel!(viewWillDisappear:), - will_disappear:: as extern "C" fn(_, _, _) - ); - decl.add_method( - sel!(viewDidDisappear:), - did_disappear:: as extern "C" fn(_, _, _) - ); + decl.add_method(sel!(viewWillDisappear:), will_disappear:: as extern "C" fn(_, _, _)); + decl.add_method(sel!(viewDidDisappear:), did_disappear:: as extern "C" fn(_, _, _)); }) } diff --git a/src/view/splitviewcontroller/macos.rs b/src/view/splitviewcontroller/macos.rs index e5005170..dcc33429 100644 --- a/src/view/splitviewcontroller/macos.rs +++ b/src/view/splitviewcontroller/macos.rs @@ -2,13 +2,12 @@ use std::sync::Once; -use objc::declare::ClassDecl; use objc::runtime::{Class, Object, Sel}; use objc::{class, msg_send, sel}; use crate::foundation::load_or_register_class; -use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; use crate::utils::load; +use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; /// Called when the view controller receives a `viewWillAppear` message. extern "C" fn will_appear(this: &mut Object, _: Sel) { diff --git a/src/view/uikit.rs b/src/view/uikit.rs index 06ddc9e9..5c683fa4 100644 --- a/src/view/uikit.rs +++ b/src/view/uikit.rs @@ -1,10 +1,9 @@ -use objc::declare::ClassDecl; use objc::rc::{Id, Owned}; -use objc::runtime::{Class, Object, Sel, BOOL}; +use objc::runtime::{Class, Object, Sel}; use objc::{class, sel}; use crate::foundation::load_or_register_class; -use crate::foundation::{id, NSUInteger, NO, YES}; +use crate::foundation::{id, NSUInteger}; use crate::utils::load; use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; @@ -12,13 +11,13 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; /// 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() -> &'static Class { - load_or_register_class("UIView", "RSTView", |decl| unsafe {}) + load_or_register_class("UIView", "RSTView", |decl| {}) } /// Injects a `UIView` subclass, with some callback and pointer ivars for what we /// need to do. pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { - load_or_register_class("UIView", instance.subclass_name(), |decl| unsafe { + load_or_register_class("UIView", instance.subclass_name(), |decl| { decl.add_ivar::(VIEW_DELEGATE_PTR); }) } diff --git a/src/webview/actions.rs b/src/webview/actions.rs index d6e1f27b..b9ff2267 100644 --- a/src/webview/actions.rs +++ b/src/webview/actions.rs @@ -2,7 +2,7 @@ use objc::{msg_send, sel}; -use crate::foundation::{id, NSInteger, BOOL, NO, YES}; +use crate::foundation::{id, NSInteger}; use crate::networking::URLRequest; use crate::webview::enums::NavigationType; @@ -33,14 +33,7 @@ pub struct NavigationResponse { impl NavigationResponse { pub fn new(response: id) -> Self { NavigationResponse { - can_show_mime_type: unsafe { - let can_show: BOOL = msg_send![response, canShowMIMEType]; - if can_show == YES { - true - } else { - false - } - } + can_show_mime_type: unsafe { msg_send![response, canShowMIMEType] } } } } @@ -54,29 +47,9 @@ pub struct OpenPanelParameters { impl From for OpenPanelParameters { fn from(params: id) -> Self { OpenPanelParameters { - allows_directories: unsafe { - match msg_send![params, allowsDirectories] { - YES => true, - NO => false, + allows_directories: unsafe { msg_send![params, allowsDirectories] }, - #[cfg(not(target_arch = "aarch64"))] - _ => { - panic!("Invalid value from WKOpenPanelParameters:allowsDirectories"); - } - } - }, - - allows_multiple_selection: unsafe { - match msg_send![params, allowsMultipleSelection] { - YES => true, - NO => false, - - #[cfg(not(target_arch = "aarch64"))] - _ => { - panic!("Invalid value from WKOpenPanelParameters:allowsMultipleSelection"); - } - } - } + allows_multiple_selection: unsafe { msg_send![params, allowsMultipleSelection] } } } } diff --git a/src/webview/class.rs b/src/webview/class.rs index e14dbd3e..a4bf4a69 100644 --- a/src/webview/class.rs +++ b/src/webview/class.rs @@ -8,7 +8,6 @@ use std::sync::Once; use block::Block; -use objc::declare::ClassDecl; use objc::runtime::{Bool, Class, Object, Sel}; use objc::{class, msg_send, msg_send_id, sel}; @@ -31,7 +30,7 @@ extern "C" fn alert(_: &Object, _: Sel, _: id, _: id, _: id, } /*unsafe { - let ptr: usize = *this.get_ivar(WEBVIEW_DELEGATE_PTR); + let ptr: usize = *this.ivar(WEBVIEW_DELEGATE_PTR); let delegate = ptr as *const T; (*webview).alert(alert); }*/ @@ -151,7 +150,7 @@ extern "C" fn run_open_panel(this: &Object, _: Sel, _: id, p extern "C" fn handle_download(this: &Object, _: Sel, download: id, suggested_filename: id, handler: usize) { let delegate = load::(this, WEBVIEW_DELEGATE_PTR); - let handler = handler as *const Block<(objc::runtime::Bool, id), ()>; + let handler = handler as *const Block<(Bool, id), ()>; let filename = NSString::retain(suggested_filename); delegate.run_save_panel(filename.to_str(), move |can_overwrite, path| unsafe { diff --git a/src/webview/config.rs b/src/webview/config.rs index 95ab0315..afec7d3e 100644 --- a/src/webview/config.rs +++ b/src/webview/config.rs @@ -5,7 +5,7 @@ use objc::rc::{Id, Owned}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, NSInteger, NSString, NO, YES}; +use crate::foundation::{id, NSInteger, NSString}; use crate::webview::enums::InjectAt; /// A wrapper for `WKWebViewConfiguration`. Holds (retains) pointers for the Objective-C runtime @@ -48,10 +48,7 @@ impl WebViewConfig { alloc, initWithSource: &*source, injectionTime: at, - forMainFrameOnly: match main_frame_only { - true => YES, - false => NO - }, + forMainFrameOnly: main_frame_only, ]; let content_controller: id = msg_send![&*self.objc, userContentController]; @@ -70,7 +67,7 @@ impl WebViewConfig { let key = NSString::new("developerExtrasEnabled"); unsafe { - let yes: id = msg_send![class!(NSNumber), numberWithBool: YES]; + let yes: id = msg_send![class!(NSNumber), numberWithBool: true]; let preferences: id = msg_send![&*self.objc, preferences]; let _: () = msg_send![preferences, setValue: yes, forKey: &*key]; } diff --git a/src/webview/mod.rs b/src/webview/mod.rs index 8cbae491..41500e0f 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -13,13 +13,12 @@ //! Apple does not ship `WKWebView` on tvOS, and as a result this control is not provided on that //! platform. -use core_graphics::geometry::CGRect; - +use objc::foundation::NSRect; use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; use objc::{class, msg_send, msg_send_id, sel}; -use crate::foundation::{id, nil, NSString, NO, YES}; +use crate::foundation::{id, nil, NSString}; use crate::geometry::Rect; use crate::layer::Layer; use crate::layout::Layout; @@ -75,15 +74,15 @@ fn allocate_webview(mut config: WebViewConfig, objc_delegate: Option<&Object>) - } } - let zero: CGRect = Rect::zero().into(); + let zero: NSRect = Rect::zero().into(); let webview_alloc: id = msg_send![register_webview_class(), alloc]; let webview: id = msg_send![webview_alloc, initWithFrame:zero configuration: &*config.objc]; #[cfg(feature = "appkit")] - let _: () = msg_send![webview, setWantsLayer: YES]; + let _: () = msg_send![webview, setWantsLayer: true]; #[cfg(feature = "autolayout")] - let _: () = msg_send![webview, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![webview, setTranslatesAutoresizingMaskIntoConstraints: false]; if let Some(delegate) = &objc_delegate { let _: () = msg_send![webview, setNavigationDelegate:*delegate]; @@ -168,10 +167,10 @@ impl WebView { /// so on. It returns a generic `WebView`, which the caller can then customize as needed. pub(crate) fn init(view: id) -> WebView { unsafe { - let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO]; + let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: false]; #[cfg(feature = "appkit")] - let _: () = msg_send![view, setWantsLayer: YES]; + let _: () = msg_send![view, setWantsLayer: true]; } WebView { @@ -242,7 +241,7 @@ where let view = allocate_webview(config, Some(&objc_delegate)); let mut view = WebView::init(view); - &delegate.did_load(view.clone_as_handle()); + delegate.did_load(view.clone_as_handle()); view.delegate = Some(delegate); view } diff --git a/src/webview/process_pool.rs b/src/webview/process_pool.rs index 84e5ac02..622b9b32 100644 --- a/src/webview/process_pool.rs +++ b/src/webview/process_pool.rs @@ -6,11 +6,10 @@ use block::Block; use cocoa::foundation::{NSArray, NSInteger, NSPoint, NSRect, NSSize, NSString}; -use objc::declare::ClassDecl; -use objc::runtime::{Class, Object, Sel, BOOL}; +use objc::runtime::{Class, Object, Sel}; use objc::{class, msg_send, sel}; -use crate::foundation::{id, nil, NO, YES}; +use crate::foundation::{id, nil}; use crate::webview::traits::WebViewController; extern "C" fn download_delegate(this: &Object, _: Sel) -> id {