1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00

Better keyboard shortcuts

* Override `window.sendEvent` to implement global [space] play/pause
* Add Controls menu to implement stop, prev, next as ⌘., ⌘← and ⌘→
This commit is contained in:
Daniel Barber 2020-03-07 17:47:00 -05:00
parent 34f941017f
commit 46dcd60ed1
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
6 changed files with 80 additions and 41 deletions

View File

@ -16,6 +16,11 @@ class AppDelegate: NSObject,
MediaKeyTapDelegate {
var mediaKeyTap: MediaKeyTap?
@IBOutlet weak var playPauseMenuItem: NSMenuItem!
@IBOutlet weak var stopMenuItem: NSMenuItem!
@IBOutlet weak var nextSongMenuItem: NSMenuItem!
@IBOutlet weak var previousSongMenuItem: NSMenuItem!
@IBOutlet weak var connectMenuItem: NSMenuItem!
@IBOutlet weak var disconnectMenuItem: NSMenuItem!
@IBOutlet weak var mainWindowMenuItem: NSMenuItem!
@ -30,7 +35,7 @@ class AppDelegate: NSObject,
App.store.subscribe(self) {
$0.select {
($0.serverState, $0.uiState)
($0.serverState, $0.playerState, $0.uiState)
}
}
@ -52,7 +57,11 @@ class AppDelegate: NSObject,
if let currentSong = App.store.state.playerState.currentSong,
state.isOneOf([.playing, .paused]) {
let nowPlayingItem = NSMenuItem(title: "Now Playing", action: nil, keyEquivalent: "")
let nowPlayingItem = NSMenuItem(
title: state == .playing ? "Now Playing" : "Paused",
action: nil,
keyEquivalent: ""
)
let songItem = NSMenuItem(title: currentSong.title, action: nil, keyEquivalent: "")
let albumItem = NSMenuItem(
title: "\(currentSong.artist)\(currentSong.album.title)",
@ -108,6 +117,21 @@ class AppDelegate: NSObject,
addSelectedSongToQueueMenuItem.isEnabled = selectedSong != nil
}
func setControlsMenuItemsState(state: PlayerState) {
guard let state = state.state else { return }
playPauseMenuItem.isEnabled = state.isOneOf([.playing, .paused, .stopped])
stopMenuItem.isEnabled = state.isOneOf([.playing, .paused])
nextSongMenuItem.isEnabled = state.isOneOf([.playing, .paused])
previousSongMenuItem.isEnabled = state.isOneOf([.playing, .paused])
if state.isOneOf([.paused, .stopped, .unknown]) {
playPauseMenuItem.title = "Play"
} else {
playPauseMenuItem.title = "Pause"
}
}
func setConnectMenuItemsState(connected: Bool) {
connectMenuItem.isEnabled = !connected
disconnectMenuItem.isEnabled = connected
@ -197,13 +221,14 @@ class AppDelegate: NSObject,
extension AppDelegate: StoreSubscriber {
typealias StoreSubscriberStateType = (
serverState: ServerState, uiState: UIState
serverState: ServerState, playerState: PlayerState, uiState: UIState
)
func newState(state: StoreSubscriberStateType) {
updateDatabaseMenuItem.isEnabled = !state.uiState.databaseUpdating
setMainWindowStateMenuItem(state: state.uiState.mainWindowState)
setSongMenuItemsState(selectedSong: state.uiState.selectedSong)
setControlsMenuItemsState(state: state.playerState)
setConnectMenuItemsState(connected: state.serverState.connected)
}
}

View File

@ -39,18 +39,6 @@ class QueueViewController: NSViewController {
App.store.unsubscribe(self)
}
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
nextResponder?.keyDown(with: event)
case NSEvent.keyCodeBS:
let queuePos = queueView.selectedRow
App.mpdClient.removeSong(at: queuePos)
default:
super.keyDown(with: event)
}
}
@objc func didConnect() {
App.mpdClient.fetchQueue()

View File

@ -176,6 +176,34 @@
</items>
</menu>
</menuItem>
<menuItem title="Controls" id="hB8-hX-gD5">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Controls" autoenablesItems="NO" id="61K-cL-XWL">
<items>
<menuItem title="Play" keyEquivalent=" " id="xXJ-ld-Y8C">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="playPauseMenuAction:" target="Voe-Tx-rLC" id="Rld-sw-gZY"/>
</connections>
</menuItem>
<menuItem title="Stop" keyEquivalent="." id="gWV-jG-Mxw">
<connections>
<action selector="stopMenuAction:" target="Voe-Tx-rLC" id="Bz3-r5-4bf"/>
</connections>
</menuItem>
<menuItem title="Next song" keyEquivalent="" id="NXq-Bk-4E0">
<connections>
<action selector="nextTrackMenuAction:" target="Voe-Tx-rLC" id="uhI-Rf-2WT"/>
</connections>
</menuItem>
<menuItem title="Previous song" keyEquivalent="" id="Ziz-Ge-r1Q">
<connections>
<action selector="prevTrackMenuAction:" target="Voe-Tx-rLC" id="05d-gm-3bo"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
@ -237,8 +265,12 @@
<outlet property="connectMenuItem" destination="VlA-Re-OZs" id="Zzt-yq-mtp"/>
<outlet property="disconnectMenuItem" destination="yjK-qU-C6d" id="qel-dM-Gbl"/>
<outlet property="mainWindowMenuItem" destination="1Sq-L7-znT" id="dC6-yY-6Ss"/>
<outlet property="nextSongMenuItem" destination="NXq-Bk-4E0" id="QEA-iy-BPE"/>
<outlet property="playPauseMenuItem" destination="xXJ-ld-Y8C" id="aeQ-wi-en7"/>
<outlet property="playSelectedSongMenuItem" destination="dyT-9E-DRY" id="UY2-SN-YMF"/>
<outlet property="playSelectedSongNextMenuItem" destination="Q8j-jr-IOp" id="Jqh-ia-sMK"/>
<outlet property="previousSongMenuItem" destination="Ziz-Ge-r1Q" id="Ufe-w4-alG"/>
<outlet property="stopMenuItem" destination="gWV-jG-Mxw" id="AkD-66-iWe"/>
<outlet property="updateDatabaseMenuItem" destination="EJg-93-1F6" id="gMf-SQ-lyI"/>
</connections>
</customObject>

View File

@ -9,12 +9,4 @@
import AppKit
class MainSplitViewController: NSSplitViewController {
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
nextResponder?.keyDown(with: event)
default:
super.keyDown(with: event)
}
}
}

View File

@ -9,12 +9,25 @@
import AppKit
class MainWindow: NSWindow {
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
nextResponder?.keyDown(with: event)
default:
super.keyDown(with: event)
override func sendEvent(_ event: NSEvent) {
guard let responder = firstResponder else { return }
if event.type == .keyDown &&
doesNotRequireSpace(responder) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
App.mpdClient.playPause()
default:
super.sendEvent(event)
}
} else {
super.sendEvent(event)
}
}
func doesNotRequireSpace(_ responder: NSResponder) -> Bool {
return !responder.isKind(of: NSText.self) &&
!responder.isKind(of: NSButton.self)
}
}

View File

@ -30,7 +30,7 @@ class WindowController: NSWindowController {
@IBOutlet var volumeState: NSButton!
@IBOutlet weak var searchQuery: NSSearchField!
override func windowDidLoad() {
super.windowDidLoad()
window?.titleVisibility = .hidden
@ -51,17 +51,6 @@ class WindowController: NSWindowController {
trackRemaining.font = .timerFont
}
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
if !event.isARepeat {
App.mpdClient.playPause()
}
default:
nextResponder?.keyDown(with: event)
}
}
func setTransportControlState(_ state: PlayerState) {
guard let state = state.state else { return }