From 634d0852f2dee82044ff364e580066e0a683c2f9 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 11 Jul 2022 02:20:07 +0200 Subject: [PATCH] Remove dependency on core-graphics --- Cargo.toml | 1 - README.md | 2 +- src/color/mod.rs | 7 +++---- src/image/graphics_context.rs | 20 ++++++++++++++++++++ src/image/image.rs | 26 ++++++++++---------------- src/image/mod.rs | 7 ++++--- src/input/mod.rs | 4 +--- src/lib.rs | 1 - src/listview/mod.rs | 4 +--- src/scrollview/mod.rs | 4 +--- src/text/label/mod.rs | 4 +--- 11 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 src/image/graphics_context.rs diff --git a/Cargo.toml b/Cargo.toml index f60926e8..7553bc5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ objc2-foundation = "=0.2.0-alpha.6" # Temporary: Patched versions that implement `Encode` for common types # Branch: `objc2` core-foundation = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "c506e7d70da010c0070048e9471ff0b441506e65", features = ["with-chrono"] } -core-graphics = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "c506e7d70da010c0070048e9471ff0b441506e65" } dispatch = "0.2.0" infer = { version = "0.4", optional = true } lazy_static = "1.4.0" diff --git a/README.md b/README.md index 5ff8caba..261c5d95 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ The following are a list of [Cargo features][cargo-features] that can be enabled ## 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. +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` is used internally and re-exported for general use. **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/src/color/mod.rs b/src/color/mod.rs index 722d135a..157150e5 100644 --- a/src/color/mod.rs +++ b/src/color/mod.rs @@ -15,8 +15,6 @@ /// @TODO: bundle iOS/tvOS support. use std::sync::{Arc, RwLock}; -use core_foundation::base::TCFType; -use core_graphics::color::CGColor; use objc2_foundation::CGFloat; use objc::rc::{Id, Owned}; @@ -411,10 +409,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/image/graphics_context.rs b/src/image/graphics_context.rs new file mode 100644 index 00000000..26330670 --- /dev/null +++ b/src/image/graphics_context.rs @@ -0,0 +1,20 @@ +use objc::rc::{Id, Shared}; +use objc::runtime::Object; +use objc::{class, msg_send, msg_send_id}; + +#[derive(Debug)] +pub struct GraphicsContext(pub Id); + +impl GraphicsContext { + pub fn current() -> Self { + Self(unsafe { msg_send_id![class!(NSGraphicsContext), currentContext].unwrap() }) + } + + pub fn save(&self) { + unsafe { msg_send![&self.0, saveGraphicsState] } + } + + pub fn restore(&self) { + unsafe { msg_send![&self.0, restoreGraphicsState] } + } +} diff --git a/src/image/image.rs b/src/image/image.rs index 07532cae..6e3ab7b4 100644 --- a/src/image/image.rs +++ b/src/image/image.rs @@ -5,10 +5,10 @@ use objc::{class, msg_send, msg_send_id, sel}; use block::ConcreteBlock; -use core_graphics::context::{CGContext, CGContextRef}; use objc2_foundation::{CGFloat, NSPoint, NSRect, NSSize}; use super::icons::*; +use super::GraphicsContext; use crate::foundation::{id, NSData, NSString, NO, YES}; use crate::utils::os; @@ -216,7 +216,7 @@ impl Image { /// Draw a custom image and get it back as a returned `Image`. pub fn draw(config: DrawConfig, handler: F) -> Self where - F: Fn(NSRect, &CGContextRef) -> bool + 'static + F: Fn(NSRect, (f64, f64), GraphicsContext) -> bool + 'static { let source_frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(config.source.0, config.source.1)); @@ -225,22 +225,16 @@ impl Image { let resized_frame = config.resize.apply(source_frame, target_frame); let block = ConcreteBlock::new(move |_destination: NSRect| 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 context = GraphicsContext::current(); - 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 - ); + // 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 result = handler(resized_frame, &context); - - let _: () = msg_send![class!(NSGraphicsContext), restoreGraphicsState]; - - match result { + // TODO: Unsure what would be appropriate to pass to this handler? + match handler(resized_frame, config.source, context) { true => YES, false => NO } diff --git a/src/image/mod.rs b/src/image/mod.rs index 8c625b75..8aaf6f82 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -1,5 +1,3 @@ -use core_foundation::base::TCFType; - use objc::rc::{Id, Shared}; use objc::runtime::{Class, Object}; use objc::{msg_send, sel}; @@ -25,6 +23,9 @@ use appkit::register_image_view_class; //#[cfg(feature = "uikit")] //use uikit::register_image_view_class; +mod graphics_context; +pub use graphics_context::GraphicsContext; + mod image; pub use image::{DrawConfig, Image, ResizeBehavior}; @@ -144,7 +145,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/input/mod.rs b/src/input/mod.rs index 19426d23..d105a63b 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -40,8 +40,6 @@ //! //! 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}; @@ -297,7 +295,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]; }); diff --git a/src/lib.rs b/src/lib.rs index cfc96edc..12eb003d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,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/mod.rs b/src/listview/mod.rs index 2ce7ee57..c3f56f53 100644 --- a/src/listview/mod.rs +++ b/src/listview/mod.rs @@ -43,8 +43,6 @@ use std::collections::HashMap; -use core_foundation::base::TCFType; - use objc::rc::{Id, Owned, Shared}; use objc::runtime::{Class, Object}; use objc::{class, msg_send, msg_send_id, sel}; @@ -440,7 +438,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]; }); diff --git a/src/scrollview/mod.rs b/src/scrollview/mod.rs index 5158a5c4..6eebf6a3 100644 --- a/src/scrollview/mod.rs +++ b/src/scrollview/mod.rs @@ -41,8 +41,6 @@ //! //! 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}; @@ -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/text/label/mod.rs b/src/text/label/mod.rs index 97c53d1b..d3c38840 100644 --- a/src/text/label/mod.rs +++ b/src/text/label/mod.rs @@ -40,8 +40,6 @@ //! //! 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}; @@ -347,7 +345,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]; });