1mod appearance;
2mod atlas;
3mod dispatcher;
4mod event;
5mod fonts;
6mod geometry;
7mod image_cache;
8mod platform;
9mod renderer;
10mod screen;
11mod sprite_cache;
12mod status_item;
13mod window;
14
15use cocoa::{
16 base::{id, nil, BOOL, NO, YES},
17 foundation::{NSAutoreleasePool, NSNotFound, NSString, NSUInteger},
18};
19pub use dispatcher::Dispatcher;
20pub use fonts::FontSystem;
21use platform::{MacForegroundPlatform, MacPlatform};
22pub use renderer::Surface;
23use std::{ops::Range, rc::Rc, sync::Arc};
24use window::Window;
25
26pub(crate) fn platform() -> Arc<dyn super::Platform> {
27 Arc::new(MacPlatform::new())
28}
29
30pub(crate) fn foreground_platform() -> Rc<dyn super::ForegroundPlatform> {
31 Rc::new(MacForegroundPlatform::default())
32}
33
34trait BoolExt {
35 fn to_objc(self) -> BOOL;
36}
37
38impl BoolExt for bool {
39 fn to_objc(self) -> BOOL {
40 if self {
41 YES
42 } else {
43 NO
44 }
45 }
46}
47
48#[repr(C)]
49#[derive(Copy, Clone, Debug)]
50struct NSRange {
51 pub location: NSUInteger,
52 pub length: NSUInteger,
53}
54
55impl NSRange {
56 fn invalid() -> Self {
57 Self {
58 location: NSNotFound as NSUInteger,
59 length: 0,
60 }
61 }
62
63 fn is_valid(&self) -> bool {
64 self.location != NSNotFound as NSUInteger
65 }
66
67 fn to_range(self) -> Option<Range<usize>> {
68 if self.is_valid() {
69 let start = self.location as usize;
70 let end = start + self.length as usize;
71 Some(start..end)
72 } else {
73 None
74 }
75 }
76}
77
78impl From<Range<usize>> for NSRange {
79 fn from(range: Range<usize>) -> Self {
80 NSRange {
81 location: range.start as NSUInteger,
82 length: range.len() as NSUInteger,
83 }
84 }
85}
86
87unsafe impl objc::Encode for NSRange {
88 fn encode() -> objc::Encoding {
89 let encoding = format!(
90 "{{NSRange={}{}}}",
91 NSUInteger::encode().as_str(),
92 NSUInteger::encode().as_str()
93 );
94 unsafe { objc::Encoding::from_str(&encoding) }
95 }
96}
97
98unsafe fn ns_string(string: &str) -> id {
99 NSString::alloc(nil).init_str(string).autorelease()
100}