StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.
| 1 | use core_foundation::base::TCFType; |
| 2 | use core_graphics::base::CGFloat; |
| 3 | use core_graphics::color::CGColor; |
| 4 | use core_graphics::sys::CGColorRef; |
| 5 | use objc::runtime::Object; |
| 6 | use objc::{msg_send, sel, sel_impl}; |
| 7 | use pathfinder_color::ColorU; |
| 8 | use std::os::raw::c_char; |
| 9 | use std::slice; |
| 10 | use std::str::Utf8Error; |
| 11 | |
| 12 | use 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 | |
| 31 | const BACKSPACE_KEY: u16 = 0x7f; |
| 32 | const ENTER_KEY: u16 = 0x0d; |
| 33 | const NUMPAD_ENTER_KEY: u16 = 0x03; |
| 34 | const ESCAPE_KEY: u16 = 0x1b; |
| 35 | const TAB_KEY: u16 = '\t' as u16; |
| 36 | const SHIFTED_TAB_KEY: u16 = 0x19; |
| 37 | extern "C" { |
| 38 | fn CGColorGetComponents(color: CGColorRef) -> *const CGFloat; |
| 39 | } |
| 40 | |
| 41 | pub 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. |
| 90 | pub 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 | |
| 98 | pub 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 | |
| 107 | pub 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 |