KeyboardShortcuts: Better organization
This commit is contained in:
@@ -28,113 +28,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
return UISceneConfiguration(name: "Browser", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
|
||||
static func appMenuShortcuts() -> [UIKeyCommand] {
|
||||
[
|
||||
// Preferences
|
||||
UIKeyCommand(
|
||||
modifiers: .command,
|
||||
input: ",",
|
||||
title: "Preferences",
|
||||
action: #selector(ShortcutResponder.showPreferences)
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
static func fileMenuShortcuts() -> [UIKeyCommand] {
|
||||
[
|
||||
// Open Location...
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "L",
|
||||
title: "Open Location",
|
||||
action: #selector(ShortcutResponder.focusURLBar)
|
||||
),
|
||||
|
||||
// Focus Web View
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "e",
|
||||
title: "Focus Web View",
|
||||
action: #selector(ShortcutResponder.focusWebView)
|
||||
),
|
||||
|
||||
// Go Back
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "[",
|
||||
title: "Go Back",
|
||||
action: #selector(ShortcutResponder.goBack)
|
||||
),
|
||||
|
||||
// Go Forward
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "]",
|
||||
title: "Go Forward",
|
||||
action: #selector(ShortcutResponder.goForward)
|
||||
),
|
||||
|
||||
// Create Tab
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "T",
|
||||
title: "New Tab",
|
||||
action: #selector(ShortcutResponder.createTab)
|
||||
),
|
||||
|
||||
// Previous Tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command, .shift], input: "[",
|
||||
title: "Previous Tab",
|
||||
action: #selector(ShortcutResponder.previousTab)
|
||||
),
|
||||
|
||||
// Close tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "W",
|
||||
title: "Close Tab",
|
||||
action: #selector(ShortcutResponder.closeTab)
|
||||
),
|
||||
|
||||
// Next Tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command, .shift], input: "]",
|
||||
title: "Next Tab",
|
||||
action: #selector(ShortcutResponder.nextTab)
|
||||
),
|
||||
|
||||
// Find on page
|
||||
(FindOnPageViewController.isEnabled() ?
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "F",
|
||||
title: "Find on Page",
|
||||
action: #selector(ShortcutResponder.findOnPage)
|
||||
)
|
||||
: UIKeyCommand.null()
|
||||
),
|
||||
|
||||
// Refresh
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "R",
|
||||
title: "Refresh",
|
||||
action: #selector(ShortcutResponder.refresh)
|
||||
),
|
||||
|
||||
// Toggle Dark Mode
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "M",
|
||||
title: "Toggle Dark Mode",
|
||||
action: #selector(ShortcutResponder.toggleDarkMode)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
override var keyCommands: [UIKeyCommand]? {
|
||||
get { return Self.fileMenuShortcuts() + Self.appMenuShortcuts() }
|
||||
get { KeyboardShortcuts.allKeyCommands() }
|
||||
}
|
||||
|
||||
override func buildMenu(with builder: UIMenuBuilder) {
|
||||
// File
|
||||
builder.replaceChildren(ofMenu: .file) { children in
|
||||
return Self.fileMenuShortcuts() + children
|
||||
return KeyboardShortcuts.menu(for: .file) + children
|
||||
}
|
||||
|
||||
// X Format X
|
||||
builder.remove(menu: .format)
|
||||
|
||||
// Application
|
||||
builder.replaceChildren(ofMenu: .application, from: { children in
|
||||
let index = children.firstIndex(where: { elem in
|
||||
if let elem = elem as? UIMenu {
|
||||
@@ -144,14 +51,23 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
})
|
||||
|
||||
var newChildren = children
|
||||
let shortcuts = KeyboardShortcuts.menu(for: .application)
|
||||
if let index = index {
|
||||
newChildren.insert(contentsOf: Self.appMenuShortcuts(), at: index + 1)
|
||||
newChildren.insert(contentsOf: shortcuts, at: index + 1)
|
||||
} else {
|
||||
newChildren.append(contentsOf: Self.appMenuShortcuts())
|
||||
newChildren.append(contentsOf: shortcuts)
|
||||
}
|
||||
|
||||
return newChildren
|
||||
})
|
||||
|
||||
// Go
|
||||
builder.insertSibling(UIMenu(title: "Go", children: KeyboardShortcuts.menu(for: .go)), beforeMenu: .view)
|
||||
|
||||
// View
|
||||
builder.replaceChildren(ofMenu: .view) { children in
|
||||
KeyboardShortcuts.menu(for: .view) + children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,173 @@ protocol ShortcutResponder: AnyObject {
|
||||
@objc
|
||||
optional func refresh(_ sender: Any?)
|
||||
|
||||
@objc
|
||||
optional func stop(_ sender: Any?)
|
||||
|
||||
@objc
|
||||
optional func showPreferences(_ sender: Any?)
|
||||
|
||||
@objc
|
||||
optional func toggleDarkMode(_ sender: Any?)
|
||||
}
|
||||
|
||||
public class KeyboardShortcuts {
|
||||
public enum Category: CaseIterable {
|
||||
case application
|
||||
case file
|
||||
case go
|
||||
case view
|
||||
}
|
||||
|
||||
public static func menu(for category: Category) -> [UIMenuElement] {
|
||||
switch category {
|
||||
case .application:
|
||||
return [
|
||||
// Preferences
|
||||
UIKeyCommand(
|
||||
modifiers: .command,
|
||||
input: ",",
|
||||
title: "Preferences",
|
||||
action: #selector(ShortcutResponder.showPreferences)
|
||||
)
|
||||
]
|
||||
|
||||
case .file:
|
||||
return [
|
||||
// Open Location...
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "L",
|
||||
title: "Open Location",
|
||||
action: #selector(ShortcutResponder.focusURLBar)
|
||||
),
|
||||
|
||||
// Tabs
|
||||
UIMenu(options: .displayInline, children: [
|
||||
// Create Tab
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "T",
|
||||
title: "New Tab",
|
||||
action: #selector(ShortcutResponder.createTab)
|
||||
),
|
||||
|
||||
// Close tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "W",
|
||||
title: "Close Tab",
|
||||
action: #selector(ShortcutResponder.closeTab)
|
||||
),
|
||||
]),
|
||||
|
||||
// Find on page
|
||||
(FindOnPageViewController.isEnabled() ?
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "F",
|
||||
title: "Find on Page",
|
||||
action: #selector(ShortcutResponder.findOnPage)
|
||||
)
|
||||
: UIKeyCommand.null()
|
||||
),
|
||||
|
||||
UIMenu(options: .displayInline, children: [
|
||||
// Refresh
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "R",
|
||||
title: "Refresh",
|
||||
action: #selector(ShortcutResponder.refresh)
|
||||
),
|
||||
|
||||
// Stop
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: ".",
|
||||
title: "Stop",
|
||||
action: #selector(ShortcutResponder.stop)
|
||||
)
|
||||
]),
|
||||
]
|
||||
|
||||
case .go:
|
||||
return [
|
||||
// Focus Web View
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "e",
|
||||
title: "Focus Web View",
|
||||
action: #selector(ShortcutResponder.focusWebView)
|
||||
),
|
||||
|
||||
// Back/Forward
|
||||
UIMenu(options: .displayInline, children: [
|
||||
// Go Back
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "[",
|
||||
title: "Go Back",
|
||||
action: #selector(ShortcutResponder.goBack)
|
||||
),
|
||||
|
||||
// Go Forward
|
||||
UIKeyCommand(
|
||||
modifiers: .command, input: "]",
|
||||
title: "Go Forward",
|
||||
action: #selector(ShortcutResponder.goForward)
|
||||
),
|
||||
]),
|
||||
|
||||
// Tab Navigation
|
||||
UIMenu(options: .displayInline, children: [
|
||||
// Previous Tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command, .shift], input: "[",
|
||||
title: "Previous Tab",
|
||||
action: #selector(ShortcutResponder.previousTab)
|
||||
),
|
||||
|
||||
// Next Tab
|
||||
UIKeyCommand(
|
||||
modifiers: [.command, .shift], input: "]",
|
||||
title: "Next Tab",
|
||||
action: #selector(ShortcutResponder.nextTab)
|
||||
),
|
||||
])
|
||||
]
|
||||
|
||||
case .view:
|
||||
return [
|
||||
// Toggle Dark Mode
|
||||
UIKeyCommand(
|
||||
modifiers: [.command], input: "M",
|
||||
title: "Toggle Dark Mode",
|
||||
action: #selector(ShortcutResponder.toggleDarkMode)
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
public static func hiddenKeyCommands() -> [UIKeyCommand] {
|
||||
return [
|
||||
// Go Back
|
||||
UIKeyCommand(input: UIKeyCommand.inputLeftArrow,
|
||||
modifierFlags: [.command, .control],
|
||||
action: #selector(ShortcutResponder.goBack)),
|
||||
|
||||
// Go Forward
|
||||
UIKeyCommand(input: UIKeyCommand.inputRightArrow,
|
||||
modifierFlags: [.command, .control],
|
||||
action: #selector(ShortcutResponder.goForward)),
|
||||
]
|
||||
}
|
||||
|
||||
public static func allKeyCommands() -> [UIKeyCommand] {
|
||||
var commands: [UIKeyCommand] = []
|
||||
for category in Category.allCases {
|
||||
let menuElements = menu(for: category)
|
||||
for element in menuElements {
|
||||
if let command = element as? UIKeyCommand {
|
||||
commands.append(command)
|
||||
} else if let menu = element as? UIMenu {
|
||||
commands.append(contentsOf: menu.children as! [UIKeyCommand])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return commands + Self.hiddenKeyCommands()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user