From e6bbe4f35de3f4fbde170b7a4e5062ab0df4ade2 Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Mon, 29 Apr 2019 22:44:34 -0400 Subject: [PATCH] Add dynamic dock menu with "Now Playing" section Inspired pretty heavily by iTunes. --- Persephone.xcodeproj/project.pbxproj | 7 +- Persephone/AppDelegate.swift | 81 +++++++++++++------ Persephone/Controllers/WindowController.swift | 7 +- .../Resources/Base.lproj/Main.storyboard | 38 +-------- 4 files changed, 63 insertions(+), 70 deletions(-) diff --git a/Persephone.xcodeproj/project.pbxproj b/Persephone.xcodeproj/project.pbxproj index 64aab1c..26e26c9 100644 --- a/Persephone.xcodeproj/project.pbxproj +++ b/Persephone.xcodeproj/project.pbxproj @@ -661,10 +661,11 @@ E408D3C1220E134F0006D9BE /* AlbumViewController.swift */, E47E2FD4222071FD00F747E6 /* AlbumViewItem.swift */, E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */, - E4E8CC912204F4B80024217A /* QueueViewController.swift */, - E465049921E94DF500A70F4C /* WindowController.swift */, - E4B11BB52275374B0075461B /* UserNotificationsController.swift */, E4405191227644340090CD6F /* MPDServerController.swift */, + E4E8CC932206097F0024217A /* NotificationsController.swift */, + E4E8CC912204F4B80024217A /* QueueViewController.swift */, + E4B11BB52275374B0075461B /* UserNotificationsController.swift */, + E465049921E94DF500A70F4C /* WindowController.swift */, ); path = Controllers; sourceTree = ""; diff --git a/Persephone/AppDelegate.swift b/Persephone/AppDelegate.swift index 0888409..5f65561 100644 --- a/Persephone/AppDelegate.swift +++ b/Persephone/AppDelegate.swift @@ -32,6 +32,57 @@ class AppDelegate: NSObject, App.mpdServerController.disconnect() } + func applicationDockMenu(_ sender: NSApplication) -> NSMenu? { + let dockMenu = NSMenu() + dockMenu.autoenablesItems = false + + guard let state = App.store.state.playerState.state else { return nil } + + if let currentSong = App.store.state.playerState.currentSong, + state.isOneOf([.playing, .paused]) { + + let nowPlayingItem = NSMenuItem(title: "Now Playing", action: nil, keyEquivalent: "") + let songItem = NSMenuItem(title: currentSong.title, action: nil, keyEquivalent: "") + let albumItem = NSMenuItem( + title: "\(currentSong.artist) — \(currentSong.album.title)", + action: nil, + keyEquivalent: "" + ) + + nowPlayingItem.isEnabled = false + songItem.indentationLevel = 1 + songItem.isEnabled = false + albumItem.indentationLevel = 1 + albumItem.isEnabled = false + + dockMenu.addItem(nowPlayingItem) + dockMenu.addItem(songItem) + dockMenu.addItem(albumItem) + dockMenu.addItem(NSMenuItem.separator()) + } + + let playPauseMenuItem = NSMenuItem( + title: state == .playing ? "Pause" : "Play", + action: #selector(playPauseMenuAction), + keyEquivalent: "" + ) + let stopMenuItem = NSMenuItem(title: "Stop", action: #selector(stopMenuAction), keyEquivalent: "") + let nextTrackMenuItem = NSMenuItem(title: "Next", action: #selector(nextTrackMenuAction), keyEquivalent: "") + let prevTrackMenuItem = NSMenuItem(title: "Previous", action: #selector(prevTrackMenuAction), keyEquivalent: "") + + playPauseMenuItem.isEnabled = state.isOneOf([.playing, .paused, .stopped]) + stopMenuItem.isEnabled = state.isOneOf([.playing, .paused]) + nextTrackMenuItem.isEnabled = state.isOneOf([.playing, .paused]) + prevTrackMenuItem.isEnabled = state.isOneOf([.playing, .paused]) + + dockMenu.addItem(playPauseMenuItem) + dockMenu.addItem(stopMenuItem) + dockMenu.addItem(nextTrackMenuItem) + dockMenu.addItem(prevTrackMenuItem) + + return dockMenu + } + func handle(mediaKey: MediaKey, event: KeyEvent) { switch mediaKey { case .playPause: @@ -43,46 +94,24 @@ class AppDelegate: NSObject, } } - func setDockTransportControlState(_ state: MPDClient.MPDStatus.State) { - playPauseMenuItem.isEnabled = state.isOneOf([.playing, .paused, .stopped]) - stopMenuItem.isEnabled = state.isOneOf([.playing, .paused]) - nextTrackMenuItem.isEnabled = state.isOneOf([.playing, .paused]) - prevTrackMenuItem.isEnabled = state.isOneOf([.playing, .paused]) - - if state.isOneOf([.paused, .stopped, .unknown]) { - playPauseMenuItem.title = "Play" - } else { - playPauseMenuItem.title = "Pause" - } - } - - @objc func enableUpdateDatabaseMenuItem() { - updateDatabaseMenuItem?.isEnabled = true - } - @IBAction func updateDatabase(_ sender: NSMenuItem) { App.store.dispatch(MPDUpdateDatabaseAction()) } @IBAction func playPauseMenuAction(_ sender: NSMenuItem) { - AppDelegate.mpdClient.playPause() + App.store.dispatch(MPDPlayPauseAction()) } @IBAction func stopMenuAction(_ sender: NSMenuItem) { - AppDelegate.mpdClient.stop() + App.store.dispatch(MPDStopAction()) } @IBAction func nextTrackMenuAction(_ sender: NSMenuItem) { - AppDelegate.mpdClient.nextTrack() + App.store.dispatch(MPDNextTrackAction()) } @IBAction func prevTrackMenuAction(_ sender: Any) { - AppDelegate.mpdClient.prevTrack() + App.store.dispatch(MPDPrevTrackAction()) } @IBOutlet weak var updateDatabaseMenuItem: NSMenuItem! - - @IBOutlet weak var playPauseMenuItem: NSMenuItem! - @IBOutlet weak var stopMenuItem: NSMenuItem! - @IBOutlet weak var nextTrackMenuItem: NSMenuItem! - @IBOutlet weak var prevTrackMenuItem: NSMenuItem! } extension AppDelegate: StoreSubscriber { diff --git a/Persephone/Controllers/WindowController.swift b/Persephone/Controllers/WindowController.swift index bcf15aa..8a9aa81 100644 --- a/Persephone/Controllers/WindowController.swift +++ b/Persephone/Controllers/WindowController.swift @@ -20,6 +20,7 @@ class WindowController: NSWindowController { override func windowDidLoad() { super.windowDidLoad() window?.titleVisibility = .hidden + window?.isExcludedFromWindowsMenu = true App.store.subscribe(self) { $0.select { $0.playerState } @@ -53,12 +54,6 @@ class WindowController: NSWindowController { } } - func setWindowTitle() { - guard let status = AppDelegate.mpdClient.status else { return } - - self.window?.title = status. - } - func setTrackProgressControls(_ playerState: PlayerState) { guard let state = playerState.state, let totalTime = playerState.totalTime, diff --git a/Persephone/Resources/Base.lproj/Main.storyboard b/Persephone/Resources/Base.lproj/Main.storyboard index df394b0..6922b61 100644 --- a/Persephone/Resources/Base.lproj/Main.storyboard +++ b/Persephone/Resources/Base.lproj/Main.storyboard @@ -90,6 +90,8 @@ + + @@ -116,49 +118,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -166,7 +134,7 @@ - +