Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/platform/mac/utils.rs
1use core_foundation::base::TCFType;
2use core_graphics::base::CGFloat;
3use core_graphics::color::CGColor;
4use core_graphics::sys::CGColorRef;
5use objc::runtime::Object;
6use objc::{msg_send, sel, sel_impl};
7use pathfinder_color::ColorU;
8use std::os::raw::c_char;
9use std::slice;
10use std::str::Utf8Error;
11 
12use cocoa::appkit::{
13 NSDeleteFunctionKey as DELETE_KEY, NSDownArrowFunctionKey as ARROW_DOWN_KEY,
14 NSEndFunctionKey as END_KEY, NSF10FunctionKey as F10_FUNCTION_KEY,
15 NSF11FunctionKey as F11_FUNCTION_KEY, NSF12FunctionKey as F12_FUNCTION_KEY,
16 NSF13FunctionKey as F13_FUNCTION_KEY, NSF14FunctionKey as F14_FUNCTION_KEY,
17 NSF15FunctionKey as F15_FUNCTION_KEY, NSF16FunctionKey as F16_FUNCTION_KEY,
18 NSF17FunctionKey as F17_FUNCTION_KEY, NSF18FunctionKey as F18_FUNCTION_KEY,
19 NSF19FunctionKey as F19_FUNCTION_KEY, NSF1FunctionKey as F1_FUNCTION_KEY,
20 NSF20FunctionKey as F20_FUNCTION_KEY, NSF2FunctionKey as F2_FUNCTION_KEY,
21 NSF3FunctionKey as F3_FUNCTION_KEY, NSF4FunctionKey as F4_FUNCTION_KEY,
22 NSF5FunctionKey as F5_FUNCTION_KEY, NSF6FunctionKey as F6_FUNCTION_KEY,
23 NSF7FunctionKey as F7_FUNCTION_KEY, NSF8FunctionKey as F8_FUNCTION_KEY,
24 NSF9FunctionKey as F9_FUNCTION_KEY, NSHelpFunctionKey as HELP_KEY,
25 NSHomeFunctionKey as HOME_KEY, NSInsertFunctionKey as INSERT_KEY,
26 NSLeftArrowFunctionKey as ARROW_LEFT_KEY, NSPageDownFunctionKey as PAGE_DOWN_KEY,
27 NSPageUpFunctionKey as PAGE_UP_KEY, NSRightArrowFunctionKey as ARROW_RIGHT_KEY,
28 NSUpArrowFunctionKey as ARROW_UP_KEY,
29};
30 
31const BACKSPACE_KEY: u16 = 0x7f;
32const ENTER_KEY: u16 = 0x0d;
33const NUMPAD_ENTER_KEY: u16 = 0x03;
34const ESCAPE_KEY: u16 = 0x1b;
35const TAB_KEY: u16 = '\t' as u16;
36const SHIFTED_TAB_KEY: u16 = 0x19;
37extern "C" {
38 fn CGColorGetComponents(color: CGColorRef) -> *const CGFloat;
39}
40 
41pub fn unicode_char_to_key(char: u16) -> Option<&'static str> {
42 // Control character naming needs to be in sync with the corresponding
43 // objective-c definition in `keycode.m`. See:
44 // https://github.com/warpdotdev/warp-internal/blob/master/ui/src/platform/mac/objc/keycode.m#L17
45 match char {
46 ARROW_UP_KEY => Some("up"),
47 ARROW_DOWN_KEY => Some("down"),
48 ARROW_LEFT_KEY => Some("left"),
49 ARROW_RIGHT_KEY => Some("right"),
50 HOME_KEY => Some("home"),
51 END_KEY => Some("end"),
52 PAGE_UP_KEY => Some("pageup"),
53 PAGE_DOWN_KEY => Some("pagedown"),
54 BACKSPACE_KEY => Some("backspace"),
55 ENTER_KEY => Some("enter"),
56 // Mac treats the help key as synonymous with the insert key.
57 HELP_KEY | INSERT_KEY => Some("insert"),
58 DELETE_KEY => Some("delete"),
59 ESCAPE_KEY => Some("escape"),
60 TAB_KEY => Some("tab"),
61 SHIFTED_TAB_KEY => Some("tab"),
62 NUMPAD_ENTER_KEY => Some("numpadenter"),
63 F1_FUNCTION_KEY => Some("f1"),
64 F2_FUNCTION_KEY => Some("f2"),
65 F3_FUNCTION_KEY => Some("f3"),
66 F4_FUNCTION_KEY => Some("f4"),
67 F5_FUNCTION_KEY => Some("f5"),
68 F6_FUNCTION_KEY => Some("f6"),
69 F7_FUNCTION_KEY => Some("f7"),
70 F8_FUNCTION_KEY => Some("f8"),
71 F9_FUNCTION_KEY => Some("f9"),
72 F10_FUNCTION_KEY => Some("f10"),
73 F11_FUNCTION_KEY => Some("f11"),
74 F12_FUNCTION_KEY => Some("f12"),
75 F13_FUNCTION_KEY => Some("f13"),
76 F14_FUNCTION_KEY => Some("f14"),
77 F15_FUNCTION_KEY => Some("f15"),
78 F16_FUNCTION_KEY => Some("f16"),
79 F17_FUNCTION_KEY => Some("f17"),
80 F18_FUNCTION_KEY => Some("f18"),
81 F19_FUNCTION_KEY => Some("f19"),
82 F20_FUNCTION_KEY => Some("f20"),
83 _ => None,
84 }
85}
86 
87/// # Safety
88///
89/// This code is only unsafe since it requires interfacing with platform code.
90pub unsafe fn nsstring_as_str<'a>(nsstring: *const Object) -> Result<&'a str, Utf8Error> {
91 const UTF8_ENCODING: usize = 4;
92 
93 let cstr: *const c_char = msg_send![nsstring, UTF8String];
94 let len: usize = msg_send![nsstring, lengthOfBytesUsingEncoding: UTF8_ENCODING];
95 std::str::from_utf8(slice::from_raw_parts(cstr as *const u8, len))
96}
97 
98pub fn color_u_to_cg_color(color: ColorU) -> CGColor {
99 CGColor::rgb(
100 f64::from(color.r) / 255.,
101 f64::from(color.g) / 255.,
102 f64::from(color.b) / 255.,
103 f64::from(color.a) / 255.,
104 )
105}
106 
107pub fn cg_color_to_color_u(color: CGColor) -> ColorU {
108 unsafe {
109 let components = CGColorGetComponents(color.as_concrete_TypeRef());
110 
111 ColorU::new(
112 (*components.offset(0) * 255.) as u8,
113 (*components.offset(1) * 255.) as u8,
114 (*components.offset(2) * 255.) as u8,
115 (*components.offset(3) * 255.) as u8,
116 )
117 }
118}
119