mac.rs

  1//! Macos screen have a y axis that goings up from the bottom of the screen and
  2//! an origin at the bottom left of the main display.
  3mod dispatcher;
  4mod display;
  5mod display_link;
  6mod events;
  7
  8#[cfg(not(feature = "macos-blade"))]
  9mod metal_atlas;
 10#[cfg(not(feature = "macos-blade"))]
 11pub mod metal_renderer;
 12
 13#[cfg(not(feature = "macos-blade"))]
 14use metal_renderer as renderer;
 15
 16#[cfg(feature = "macos-blade")]
 17use crate::platform::blade as renderer;
 18
 19mod open_type;
 20mod platform;
 21mod text_system;
 22mod window;
 23mod window_appearance;
 24
 25use crate::{px, size, DevicePixels, Pixels, Size};
 26use cocoa::{
 27    base::{id, nil},
 28    foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
 29};
 30
 31use objc::runtime::{BOOL, NO, YES};
 32use std::ops::Range;
 33
 34pub(crate) use dispatcher::*;
 35pub(crate) use display::*;
 36pub(crate) use display_link::*;
 37pub(crate) use platform::*;
 38pub(crate) use text_system::*;
 39pub(crate) use window::*;
 40
 41trait BoolExt {
 42    fn to_objc(self) -> BOOL;
 43}
 44
 45impl BoolExt for bool {
 46    fn to_objc(self) -> BOOL {
 47        if self {
 48            YES
 49        } else {
 50            NO
 51        }
 52    }
 53}
 54
 55#[repr(C)]
 56#[derive(Copy, Clone, Debug)]
 57struct NSRange {
 58    pub location: NSUInteger,
 59    pub length: NSUInteger,
 60}
 61
 62impl NSRange {
 63    fn invalid() -> Self {
 64        Self {
 65            location: NSNotFound as NSUInteger,
 66            length: 0,
 67        }
 68    }
 69
 70    fn is_valid(&self) -> bool {
 71        self.location != NSNotFound as NSUInteger
 72    }
 73
 74    fn to_range(self) -> Option<Range<usize>> {
 75        if self.is_valid() {
 76            let start = self.location as usize;
 77            let end = start + self.length as usize;
 78            Some(start..end)
 79        } else {
 80            None
 81        }
 82    }
 83}
 84
 85impl From<Range<usize>> for NSRange {
 86    fn from(range: Range<usize>) -> Self {
 87        NSRange {
 88            location: range.start as NSUInteger,
 89            length: range.len() as NSUInteger,
 90        }
 91    }
 92}
 93
 94unsafe impl objc::Encode for NSRange {
 95    fn encode() -> objc::Encoding {
 96        let encoding = format!(
 97            "{{NSRange={}{}}}",
 98            NSUInteger::encode().as_str(),
 99            NSUInteger::encode().as_str()
100        );
101        unsafe { objc::Encoding::from_str(&encoding) }
102    }
103}
104
105unsafe fn ns_string(string: &str) -> id {
106    NSString::alloc(nil).init_str(string).autorelease()
107}
108
109impl From<NSSize> for Size<Pixels> {
110    fn from(value: NSSize) -> Self {
111        Size {
112            width: px(value.width as f32),
113            height: px(value.height as f32),
114        }
115    }
116}
117
118impl From<NSRect> for Size<Pixels> {
119    fn from(rect: NSRect) -> Self {
120        let NSSize { width, height } = rect.size;
121        size(width.into(), height.into())
122    }
123}
124
125impl From<NSRect> for Size<DevicePixels> {
126    fn from(rect: NSRect) -> Self {
127        let NSSize { width, height } = rect.size;
128        size(DevicePixels(width as i32), DevicePixels(height as i32))
129    }
130}