Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220import AppKitimport Carbon
struct MenuBandShortcut: Equatable { let keyCode: UInt32 let modifiers: UInt32
static let defaultFocus = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_K), modifiers: UInt32(cmdKey | controlKey | optionKey) )
static let defaultPlayPalette = MenuBandShortcut( keyCode: UInt32(kVK_Space), modifiers: UInt32(cmdKey | controlKey | optionKey) )
static let defaultExitFocus = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_E), modifiers: UInt32(cmdKey | controlKey | optionKey) )
static let defaultLayoutToggle = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_L), modifiers: UInt32(cmdKey | controlKey | optionKey) )
static let typeMode = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_P), modifiers: UInt32(cmdKey | controlKey | optionKey) )
/// Toggle the right-hand percussion split. ⌘⌃⌥D ("D" for drums) — /// same modifier family as the other Menu Band global toggles. static let defaultPercussionToggle = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_D), modifiers: UInt32(cmdKey | controlKey | optionKey) )
/// Toggle voice squawk. ⌘⌃⌥` — the `` ` `` key already means "mic" /// in Menu Band (hold it to sample), so it carries over to talking. static let squawk = MenuBandShortcut( keyCode: UInt32(kVK_ANSI_Grave), modifiers: UInt32(cmdKey | controlKey | optionKey) )
static let layoutToggle = defaultLayoutToggle
var isValidForRecording: Bool { (modifiers & UInt32(cmdKey | controlKey | optionKey)) != 0 }
var isReservedForTypeMode: Bool { self == Self.typeMode }
var displayString: String { var parts = "" if (modifiers & UInt32(controlKey)) != 0 { parts += "⌃" } if (modifiers & UInt32(optionKey)) != 0 { parts += "⌥" } if (modifiers & UInt32(shiftKey)) != 0 { parts += "⇧" } if (modifiers & UInt32(cmdKey)) != 0 { parts += "⌘" } return parts + Self.keyLabel(for: keyCode) }
func matches(event: NSEvent) -> Bool { matches(keyCode: UInt32(event.keyCode), modifiers: Self.carbonModifiers(from: event.modifierFlags)) }
func matches(keyCode: UInt32, modifiers: UInt32) -> Bool { self.keyCode == keyCode && self.modifiers == modifiers }
static func carbonModifiers(from flags: NSEvent.ModifierFlags) -> UInt32 { var mask: UInt32 = 0 if flags.contains(.command) { mask |= UInt32(cmdKey) } if flags.contains(.control) { mask |= UInt32(controlKey) } if flags.contains(.option) { mask |= UInt32(optionKey) } if flags.contains(.shift) { mask |= UInt32(shiftKey) } return mask }
private static func keyLabel(for keyCode: UInt32) -> String { if let label = ansiKeyLabels[keyCode] { return label } if let label = specialKeyLabels[keyCode] { return label } return "Key \(keyCode)" }
private static let ansiKeyLabels: [UInt32: String] = [ 0: "A", 1: "S", 2: "D", 3: "F", 4: "H", 5: "G", 6: "Z", 7: "X", 8: "C", 9: "V", 11: "B", 12: "Q", 13: "W", 14: "E", 15: "R", 16: "Y", 17: "T", 18: "1", 19: "2", 20: "3", 21: "4", 22: "6", 23: "5", 24: "=", 25: "9", 26: "7", 27: "-", 28: "8", 29: "0", 30: "]", 31: "O", 32: "U", 33: "[", 34: "I", 35: "P", 37: "L", 38: "J", 39: "'", 40: "K", 41: ";", 42: "\\", 43: ",", 44: "/", 45: "N", 46: "M", 47: ".", 50: "`" ]
private static let specialKeyLabels: [UInt32: String] = [ UInt32(kVK_Space): "Space", UInt32(kVK_Return): "Return", UInt32(kVK_Tab): "Tab", UInt32(kVK_Escape): "Esc", UInt32(kVK_Delete): "Delete", UInt32(kVK_ForwardDelete): "FwdDel", UInt32(kVK_Home): "Home", UInt32(kVK_End): "End", UInt32(kVK_PageUp): "PgUp", UInt32(kVK_PageDown): "PgDn", UInt32(kVK_LeftArrow): "←", UInt32(kVK_RightArrow): "→", UInt32(kVK_UpArrow): "↑", UInt32(kVK_DownArrow): "↓", UInt32(kVK_F1): "F1", UInt32(kVK_F2): "F2", UInt32(kVK_F3): "F3", UInt32(kVK_F4): "F4", UInt32(kVK_F5): "F5", UInt32(kVK_F6): "F6", UInt32(kVK_F7): "F7", UInt32(kVK_F8): "F8", UInt32(kVK_F9): "F9", UInt32(kVK_F10): "F10", UInt32(kVK_F11): "F11", UInt32(kVK_F12): "F12" ]}
enum MenuBandShortcutPreferences { private static let focusKeyCodeKey = "notepat.focusShortcut.keyCode" private static let focusModifiersKey = "notepat.focusShortcut.modifiers" private static let playPaletteKeyCodeKey = "notepat.playPaletteShortcut.keyCode" private static let playPaletteModifiersKey = "notepat.playPaletteShortcut.modifiers" private static let exitFocusKeyCodeKey = "notepat.exitFocusShortcut.keyCode" private static let exitFocusModifiersKey = "notepat.exitFocusShortcut.modifiers" private static let layoutKeyCodeKey = "notepat.layoutShortcut.keyCode" private static let layoutModifiersKey = "notepat.layoutShortcut.modifiers"
private static func loadShortcut( keyCodeKey: String, modifiersKey: String, fallback: MenuBandShortcut ) -> MenuBandShortcut { let defaults = UserDefaults.standard guard defaults.object(forKey: keyCodeKey) != nil, defaults.object(forKey: modifiersKey) != nil else { return fallback } let shortcut = MenuBandShortcut( keyCode: UInt32(defaults.integer(forKey: keyCodeKey)), modifiers: UInt32(defaults.integer(forKey: modifiersKey)) ) return shortcut.isValidForRecording && !shortcut.isReservedForTypeMode ? shortcut : fallback }
private static func saveShortcut( _ shortcut: MenuBandShortcut, keyCodeKey: String, modifiersKey: String ) { UserDefaults.standard.set(Int(shortcut.keyCode), forKey: keyCodeKey) UserDefaults.standard.set(Int(shortcut.modifiers), forKey: modifiersKey) }
static var focusShortcut: MenuBandShortcut { get { loadShortcut( keyCodeKey: focusKeyCodeKey, modifiersKey: focusModifiersKey, fallback: .defaultFocus ) } set { saveShortcut(newValue, keyCodeKey: focusKeyCodeKey, modifiersKey: focusModifiersKey) } }
static var playPaletteShortcut: MenuBandShortcut { get { loadShortcut( keyCodeKey: playPaletteKeyCodeKey, modifiersKey: playPaletteModifiersKey, fallback: .defaultPlayPalette ) } set { saveShortcut(newValue, keyCodeKey: playPaletteKeyCodeKey, modifiersKey: playPaletteModifiersKey) } }
static var exitFocusShortcut: MenuBandShortcut { get { loadShortcut( keyCodeKey: exitFocusKeyCodeKey, modifiersKey: exitFocusModifiersKey, fallback: .defaultExitFocus ) } set { saveShortcut(newValue, keyCodeKey: exitFocusKeyCodeKey, modifiersKey: exitFocusModifiersKey) } }
static var layoutShortcut: MenuBandShortcut { get { loadShortcut( keyCodeKey: layoutKeyCodeKey, modifiersKey: layoutModifiersKey, fallback: .defaultLayoutToggle ) } set { saveShortcut(newValue, keyCodeKey: layoutKeyCodeKey, modifiersKey: layoutModifiersKey) } }}