Add KeyboardKey and KeyboardShortcut structs.

This commit is contained in:
Brent Simmons 2017-12-20 12:54:01 -08:00
parent f53275daa5
commit 035702d403
1 changed files with 129 additions and 1 deletions

View File

@ -6,7 +6,7 @@
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import Cocoa
// To get, for instance, the keyboard integer value for "\r": "\r".keyboardIntegerValue (returns 13)
@ -14,6 +14,7 @@ public struct KeyboardConstant {
public static let lineFeedKey = "\n".keyboardIntegerValue
public static let returnKey = "\r".keyboardIntegerValue
public static let spaceKey = " ".keyboardIntegerValue
}
public extension String {
@ -22,3 +23,130 @@ public extension String {
return Int(utf8[utf8.startIndex])
}
}
public struct KeyboardShortcut: Hashable {
public let key: KeyboardKey
public let actionString: String
public let hashValue: Int
public init?(dictionary: [String: Any]) {
guard let key = KeyboardKey(dictionary: dictionary) else {
return nil
}
guard let actionString = dictionary["action"] as? String else {
return nil
}
self.key = key
self.actionString = actionString
self.hashValue = key.hashValue + self.actionString.hashValue
}
public func perform(with view: NSView) {
let action = NSSelectorFromString(actionString)
NSApplication.shared.sendAction(action, to: nil, from: view)
}
public static func findMatchingShortcut(in shortcuts: Set<KeyboardShortcut>, key: KeyboardKey) -> KeyboardShortcut? {
for shortcut in shortcuts {
if shortcut.key == key {
return shortcut
}
}
return nil
}
public static func ==(lhs: KeyboardShortcut, rhs: KeyboardShortcut) -> Bool {
return lhs.hashValue == rhs.hashValue && lhs.key == rhs.key && lhs.actionString == rhs.actionString
}
}
public struct KeyboardKey: Hashable {
public let shiftKeyDown: Bool
public let optionKeyDown: Bool
public let commandKeyDown: Bool
public let controlKeyDown: Bool
public let integerValue: Int // unmodified character as Int
public var isModified: Bool {
return !shiftKeyDown && !optionKeyDown && !commandKeyDown && !controlKeyDown
}
public var hashValue: Int {
return integerValue
}
init(integerValue: Int, shiftKeyDown: Bool, optionKeyDown: Bool, commandKeyDown: Bool, controlKeyDown: Bool) {
self.integerValue = integerValue
self.shiftKeyDown = shiftKeyDown
self.optionKeyDown = optionKeyDown
self.commandKeyDown = commandKeyDown
self.controlKeyDown = controlKeyDown
}
public init(with event: NSEvent) {
let flags = event.modifierFlags
let shiftKeyDown = flags.contains(.shift)
let optionKeyDown = flags.contains(.option)
let commandKeyDown = flags.contains(.command)
let controlKeyDown = flags.contains(.control)
let integerValue = event.charactersIgnoringModifiers?.keyboardIntegerValue ?? 0
self.init(integerValue: integerValue, shiftKeyDown: shiftKeyDown, optionKeyDown: optionKeyDown, commandKeyDown: commandKeyDown, controlKeyDown: controlKeyDown)
}
public init?(dictionary: [String: Any]) {
guard let s = dictionary["key"] as? String else {
return nil
}
var integerValue = 0
switch(s) {
case "[space]":
integerValue = " ".keyboardIntegerValue
case "[uparrow]":
integerValue = NSUpArrowFunctionKey
case "[downarrow]":
integerValue = NSDownArrowFunctionKey
case "[leftarrow]":
integerValue = NSLeftArrowFunctionKey
case "[rightarrow]":
integerValue = NSRightArrowFunctionKey
case "[return]":
integerValue = NSCarriageReturnCharacter
case "[enter]":
integerValue = NSEnterCharacter
case "[delete]":
integerValue = Int(kDeleteKeyCode)
case "[deletefunction]":
integerValue = NSDeleteFunctionKey
default:
integerValue = s.keyboardIntegerValue
}
let shiftKeyDown = dictionary["shiftModifier"] as? Bool ?? false
let optionKeyDown = dictionary["optionModifier"] as? Bool ?? false
let commandKeyDown = dictionary["commandModifier"] as? Bool ?? false
let controlKeyDown = dictionary["controlModifier"] as? Bool ?? false
self.init(integerValue: integerValue, shiftKeyDown: shiftKeyDown, optionKeyDown: optionKeyDown, commandKeyDown: commandKeyDown, controlKeyDown: controlKeyDown)
}
public static func ==(lhs: KeyboardKey, rhs: KeyboardKey) -> Bool {
return lhs.integerValue == rhs.integerValue && lhs.shiftKeyDown == rhs.shiftKeyDown && lhs.optionKeyDown == rhs.optionKeyDown && lhs.commandKeyDown == rhs.commandKeyDown && lhs.controlKeyDown == rhs.controlKeyDown
}
}