97 lines
3.4 KiB
Rust
97 lines
3.4 KiB
Rust
use cocoa::{
|
|
appkit::NSWindow,
|
|
base::id,
|
|
foundation::{NSPoint, NSRect, NSSize},
|
|
};
|
|
use objc::{msg_send, sel, sel_impl};
|
|
use pathfinder_geometry::{
|
|
rect::RectF,
|
|
vector::{vec2f, Vector2F},
|
|
};
|
|
|
|
///! Macos screen have a y axis that goings up from the bottom of the screen and
|
|
///! an origin at the bottom left of the main display.
|
|
|
|
pub trait Vector2FExt {
|
|
/// Converts self to an NSPoint with y axis pointing up.
|
|
fn to_screen_ns_point(&self, native_window: id, window_height: f64) -> NSPoint;
|
|
}
|
|
impl Vector2FExt for Vector2F {
|
|
fn to_screen_ns_point(&self, native_window: id, window_height: f64) -> NSPoint {
|
|
unsafe {
|
|
let point = NSPoint::new(self.x() as f64, window_height - self.y() as f64);
|
|
msg_send![native_window, convertPointToScreen: point]
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait RectFExt {
|
|
/// Converts self to an NSRect with y axis pointing up.
|
|
/// The resulting NSRect will have an origin at the bottom left of the rectangle.
|
|
/// Also takes care of converting from window scaled coordinates to screen coordinates
|
|
fn to_screen_ns_rect(&self, native_window: id) -> NSRect;
|
|
|
|
/// Converts self to an NSRect with y axis point up.
|
|
/// The resulting NSRect will have an origin at the bottom left of the rectangle.
|
|
/// Unlike to_screen_ns_rect, coordinates are not converted and are assumed to already be in screen scale
|
|
fn to_ns_rect(&self) -> NSRect;
|
|
}
|
|
impl RectFExt for RectF {
|
|
fn to_screen_ns_rect(&self, native_window: id) -> NSRect {
|
|
unsafe { native_window.convertRectToScreen_(self.to_ns_rect()) }
|
|
}
|
|
|
|
fn to_ns_rect(&self) -> NSRect {
|
|
NSRect::new(
|
|
NSPoint::new(
|
|
self.origin_x() as f64,
|
|
-(self.origin_y() + self.height()) as f64,
|
|
),
|
|
NSSize::new(self.width() as f64, self.height() as f64),
|
|
)
|
|
}
|
|
}
|
|
|
|
pub trait NSRectExt {
|
|
/// Converts self to a RectF with y axis pointing down.
|
|
/// The resulting RectF will have an origin at the top left of the rectangle.
|
|
/// Also takes care of converting from screen scale coordinates to window coordinates
|
|
fn to_window_rectf(&self, native_window: id) -> RectF;
|
|
|
|
/// Converts self to a RectF with y axis pointing down.
|
|
/// The resulting RectF will have an origin at the top left of the rectangle.
|
|
/// Unlike to_screen_ns_rect, coordinates are not converted and are assumed to already be in screen scale
|
|
fn to_rectf(&self) -> RectF;
|
|
|
|
fn intersects(&self, other: Self) -> bool;
|
|
}
|
|
impl NSRectExt for NSRect {
|
|
fn to_window_rectf(&self, native_window: id) -> RectF {
|
|
unsafe {
|
|
self.origin.x;
|
|
let rect: NSRect = native_window.convertRectFromScreen_(*self);
|
|
rect.to_rectf()
|
|
}
|
|
}
|
|
|
|
fn to_rectf(&self) -> RectF {
|
|
RectF::new(
|
|
vec2f(
|
|
self.origin.x as f32,
|
|
-(self.origin.y + self.size.height) as f32,
|
|
),
|
|
vec2f(self.size.width as f32, self.size.height as f32),
|
|
)
|
|
}
|
|
|
|
fn intersects(&self, other: Self) -> bool {
|
|
self.size.width > 0.
|
|
&& self.size.height > 0.
|
|
&& other.size.width > 0.
|
|
&& other.size.height > 0.
|
|
&& self.origin.x <= other.origin.x + other.size.width
|
|
&& self.origin.x + self.size.width >= other.origin.x
|
|
&& self.origin.y <= other.origin.y + other.size.height
|
|
&& self.origin.y + self.size.height >= other.origin.y
|
|
}
|
|
}
|