Skip to content

Commit

Permalink
Remove dependency on core-graphics
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Jul 24, 2022
1 parent ed05094 commit 73403d1
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 39 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 3 additions & 4 deletions src/color/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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]
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/image/graphics_context.rs
Original file line number Diff line number Diff line change
@@ -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<Object, Shared>);

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] }
}
}
28 changes: 11 additions & 17 deletions src/image/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -216,31 +216,25 @@ impl Image {
/// Draw a custom image and get it back as a returned `Image`.
pub fn draw<F>(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));

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 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 block = ConcreteBlock::new(move |_destination: NSRect| {
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
}
Expand Down
7 changes: 4 additions & 3 deletions src/image/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core_foundation::base::TCFType;

use objc::rc::{Id, Shared};
use objc::runtime::{Class, Object};
use objc::{msg_send, sel};
Expand All @@ -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};

Expand Down Expand Up @@ -144,7 +145,7 @@ impl ImageView {
/// Call this to set the background color for the backing layer.
pub fn set_background_color<C: AsRef<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];
});
Expand Down
4 changes: 1 addition & 3 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -297,7 +295,7 @@ impl<T> TextField<T> {
/// Call this to set the background color for the backing layer.
pub fn set_background_color<C: AsRef<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];
});
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 1 addition & 3 deletions src/listview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -440,7 +438,7 @@ impl<T> ListView<T> {
pub fn set_background_color<C: AsRef<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];
});
Expand Down
4 changes: 1 addition & 3 deletions src/scrollview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -298,7 +296,7 @@ impl<T> ScrollView<T> {
pub fn set_background_color<C: AsRef<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];
});
Expand Down
4 changes: 1 addition & 3 deletions src/text/label/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -347,7 +345,7 @@ impl<T> Label<T> {
// @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];
});
Expand Down

0 comments on commit 73403d1

Please sign in to comment.