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