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;
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_link::*;
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}