Implement keyboard shortcut infrastructure and first shortcuts
This commit is contained in:
parent
68143aa2c5
commit
8758d28cd7
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// KeyboardManager.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 9/4/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum KeyboardType: String {
|
||||
case global = "GlobalKeyboardShortcuts"
|
||||
case sidebar = "SidebarKeyboardShortcuts"
|
||||
case timeline = "TimelineKeyboardShortcuts"
|
||||
case detail = "DetailKeyboardShortcuts"
|
||||
}
|
||||
|
||||
class KeyboardManager {
|
||||
|
||||
private let coordinator: SceneCoordinator
|
||||
private(set) var keyCommands: [UIKeyCommand]?
|
||||
|
||||
init(type: KeyboardType, coordinator: SceneCoordinator) {
|
||||
self.coordinator = coordinator
|
||||
load(type: type)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension KeyboardManager {
|
||||
|
||||
func load(type: KeyboardType) {
|
||||
let globalFile = Bundle.main.path(forResource: KeyboardType.global.rawValue, ofType: "plist")!
|
||||
let globalEntries = NSArray(contentsOfFile: globalFile)! as! [[String: Any]]
|
||||
var globalCommands = globalEntries.compactMap { createKeyCommand(keyEntry: $0) }
|
||||
|
||||
let specificFile = Bundle.main.path(forResource: type.rawValue, ofType: "plist")!
|
||||
let specificEntries = NSArray(contentsOfFile: specificFile)! as! [[String: Any]]
|
||||
let specificCommands = specificEntries.compactMap { createKeyCommand(keyEntry: $0) }
|
||||
|
||||
globalCommands.append(contentsOf: specificCommands)
|
||||
keyCommands = globalCommands
|
||||
}
|
||||
|
||||
func createKeyCommand(keyEntry: [String: Any]) -> UIKeyCommand? {
|
||||
guard let input = createKeyCommandInput(keyEntry: keyEntry) else { return nil }
|
||||
let modifiers = createKeyModifierFlags(keyEntry: keyEntry)
|
||||
let action = NSSelectorFromString(keyEntry["action"] as! String)
|
||||
|
||||
if let title = keyEntry["title"] as? String {
|
||||
return UIKeyCommand(title: title, image: nil, action: action, input: input, modifierFlags: modifiers, propertyList: nil, alternates: [], discoverabilityTitle: nil, attributes: [], state: .on)
|
||||
} else {
|
||||
return UIKeyCommand(input: input, modifierFlags: modifiers, action: action)
|
||||
}
|
||||
}
|
||||
|
||||
func createKeyCommandInput(keyEntry: [String: Any]) -> String? {
|
||||
guard let key = keyEntry["key"] as? String else { return nil }
|
||||
|
||||
switch(key) {
|
||||
case "[space]":
|
||||
return " "
|
||||
case "[uparrow]":
|
||||
return UIKeyCommand.inputUpArrow
|
||||
case "[downarrow]":
|
||||
return UIKeyCommand.inputDownArrow
|
||||
case "[leftarrow]":
|
||||
return UIKeyCommand.inputLeftArrow
|
||||
case "[rightarrow]":
|
||||
return UIKeyCommand.inputRightArrow
|
||||
case "[return]":
|
||||
return "\r"
|
||||
case "[enter]":
|
||||
return nil
|
||||
case "[delete]":
|
||||
return "\u{8}"
|
||||
case "[deletefunction]":
|
||||
return nil
|
||||
case "[tab]":
|
||||
return "\t"
|
||||
default:
|
||||
return key
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createKeyModifierFlags(keyEntry: [String: Any]) -> UIKeyModifierFlags {
|
||||
var flags = UIKeyModifierFlags()
|
||||
|
||||
if keyEntry["shiftModifier"] as? Bool ?? false {
|
||||
flags.insert(.shift)
|
||||
}
|
||||
|
||||
if keyEntry["optionModifier"] as? Bool ?? false {
|
||||
flags.insert(.alternate)
|
||||
}
|
||||
|
||||
if keyEntry["commandModifier"] as? Bool ?? false {
|
||||
flags.insert(.command)
|
||||
}
|
||||
|
||||
if keyEntry["controlModifier"] as? Bool ?? false {
|
||||
flags.insert(.control)
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue