diff --git a/Persephone/Assets.xcassets/playButtonLarge.imageset/Contents.json b/Persephone/Assets.xcassets/playButtonLarge.imageset/Contents.json new file mode 100644 index 0000000..15f9f85 --- /dev/null +++ b/Persephone/Assets.xcassets/playButtonLarge.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "playButtonLarge.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "playButtonLarge@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.png b/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.png new file mode 100644 index 0000000..a489b7b Binary files /dev/null and b/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.png differ diff --git a/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge@2x.png b/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge@2x.png new file mode 100644 index 0000000..109a9ca Binary files /dev/null and b/Persephone/Assets.xcassets/playButtonLarge.imageset/playButtonLarge@2x.png differ diff --git a/Persephone/Controllers/AlbumItem.swift b/Persephone/Controllers/AlbumItem.swift index e9a3be4..0bec18a 100644 --- a/Persephone/Controllers/AlbumItem.swift +++ b/Persephone/Controllers/AlbumItem.swift @@ -10,6 +10,7 @@ import Cocoa class AlbumItem: NSCollectionViewItem { var observer: NSKeyValueObservation? + var album: MPDClient.Album? override func viewDidLoad() { super.viewDidLoad() @@ -27,6 +28,7 @@ class AlbumItem: NSCollectionViewItem { } func setAlbum(_ album: MPDClient.Album) { + self.album = album albumTitle.stringValue = album.title albumArtist.stringValue = album.artist } @@ -42,6 +44,12 @@ class AlbumItem: NSCollectionViewItem { } } + @IBAction func playAlbum(_ sender: Any) { + guard let album = album else { return } + + AppDelegate.mpdClient.playAlbum(album) + } + @IBOutlet var albumCoverView: NSImageView! @IBOutlet var albumTitle: NSTextField! @IBOutlet var albumArtist: NSTextField! diff --git a/Persephone/Controllers/QueueViewController.swift b/Persephone/Controllers/QueueViewController.swift index cd09b36..7499bdd 100644 --- a/Persephone/Controllers/QueueViewController.swift +++ b/Persephone/Controllers/QueueViewController.swift @@ -9,7 +9,13 @@ import Cocoa class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate { - var queue: [MPDClient.Song] = [] + struct SongItem { + var song: MPDClient.Song + var queuePos: Int + var isPlaying: Bool + } + + var queue: [SongItem] = [] var queuePos: Int = -1 var queueIcon: NSImage? = nil @@ -20,11 +26,6 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV let playIcon = NSImage(named: "playButton") let pauseIcon = NSImage(named: "pauseButton") - struct SongItem { - var song: MPDClient.Song - var queuePos: Int - } - override func viewDidLoad() { super.viewDidLoad() @@ -74,8 +75,14 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV guard let queue = notification.userInfo?[Notification.queueKey] as? [MPDClient.Song] else { return } - self.queue = queue + var newQueue: [SongItem] = [] + for (index, mpdSong) in queue.enumerated() { + let songItem = SongItem(song: mpdSong, queuePos: index, isPlaying: index == queuePos) + newQueue.append(songItem) + } + + self.queue = newQueue queueView.reloadData() } @@ -83,16 +90,13 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV guard let queuePos = notification.userInfo?[Notification.queuePosKey] as? Int else { return } - let oldSongRowPos = self.queuePos + 1 - let newSongRowPos = queuePos + 1 + let oldSongRowPos = self.queuePos + let newSongRowPos = queuePos self.queuePos = queuePos setQueuePos(oldSongRowPos: oldSongRowPos, newSongRowPos: newSongRowPos) - queueView.reloadData( - forRowIndexes: [oldSongRowPos, newSongRowPos], - columnIndexes: [0, 1] - ) + queueView.reloadData() } func setQueueIcon(_ state: MPDClient.Status.State) { @@ -107,30 +111,11 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV } func setQueuePos(oldSongRowPos: Int, newSongRowPos: Int) { - if oldSongRowPos > 0 { - guard let oldSongRow = queueView.rowView(atRow: oldSongRowPos, makeIfNecessary: true), - let oldSongTitleCell = oldSongRow.view(atColumn: 0) as? NSTableCellView - else { return } - - setRowFont(rowView: oldSongRow, font: systemFontRegular) - oldSongTitleCell.imageView?.image = nil + if oldSongRowPos >= 0 { + queue[oldSongRowPos].isPlaying = false } - guard let songRow = queueView.rowView(atRow: newSongRowPos, makeIfNecessary: true), - let newSongTitleCell = songRow.view(atColumn: 0) as? NSTableCellView - else { return } - - setRowFont(rowView: songRow, font: systemFontBold) - newSongTitleCell.imageView?.image = self.queueIcon - } - - func setRowFont(rowView: NSTableRowView, font: NSFont) { - guard let songTitleCell = rowView.view(atColumn: 0) as? NSTableCellView, - let songArtistCell = rowView.view(atColumn: 1) as? NSTableCellView - else { return } - - songTitleCell.textField?.font = font - songArtistCell.textField?.font = font + queue[newSongRowPos].isPlaying = true } func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int { @@ -143,7 +128,7 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { if index > 0 { - return SongItem(song: queue[index - 1], queuePos: index - 1) + return queue[index - 1] } else { return false } @@ -159,6 +144,13 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV ) as! NSTableCellView cellView.textField?.stringValue = songItem.song.getTag(.title) + if songItem.isPlaying { + cellView.textField?.font = systemFontBold + cellView.imageView?.image = self.queueIcon + } else { + cellView.textField?.font = systemFontRegular + cellView.imageView?.image = nil + } return cellView case "songArtistColumn": @@ -168,6 +160,11 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV ) as! NSTableCellView cellView.textField?.stringValue = songItem.song.getTag(.artist) + if songItem.isPlaying { + cellView.textField?.font = systemFontBold + } else { + cellView.textField?.font = systemFontRegular + } return cellView default: diff --git a/Persephone/MPDClient/MPDClient.swift b/Persephone/MPDClient/MPDClient.swift index 35cc66c..2787264 100644 --- a/Persephone/MPDClient/MPDClient.swift +++ b/Persephone/MPDClient/MPDClient.swift @@ -109,6 +109,27 @@ class MPDClient { idle() } + func playAlbum(_ album: Album) { + noIdle() + commandQueue.async { [unowned self] in + var songs: [Song] = [] + + mpd_run_clear(self.connection) + mpd_search_db_songs(self.connection, true) + mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album.title) + mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM_ARTIST, album.artist) + mpd_search_commit(self.connection) + while let mpdSong = mpd_recv_song(self.connection) { + songs.append(Song(mpdSong)) + } + for song in songs { + mpd_run_add(self.connection, song.uri) + } + mpd_run_play_pos(self.connection, 0) + } + idle() + } + func queueCommand(command: Command) { noIdle() commandQueue.async { [unowned self] in diff --git a/Persephone/MPDClient/Models/Song.swift b/Persephone/MPDClient/Models/Song.swift index 3b43d5b..902dd21 100644 --- a/Persephone/MPDClient/Models/Song.swift +++ b/Persephone/MPDClient/Models/Song.swift @@ -41,6 +41,10 @@ extension MPDClient { mpd_song_free(mpdSong) } + var uri: UnsafePointer { + return mpd_song_get_uri(mpdSong) + } + func getTag(_ tagType: TagType) -> String { let mpdTagType = mpd_tag_type(rawValue: Int32(tagType.rawValue)) diff --git a/Persephone/Resources/AlbumItem.xib b/Persephone/Resources/AlbumItem.xib index db3a041..a58c678 100644 --- a/Persephone/Resources/AlbumItem.xib +++ b/Persephone/Resources/AlbumItem.xib @@ -47,10 +47,13 @@ - + + + + @@ -77,6 +80,6 @@ - + diff --git a/Resources/export/playButtonLarge.pdf b/Resources/export/playButtonLarge.pdf new file mode 100644 index 0000000..a04b172 Binary files /dev/null and b/Resources/export/playButtonLarge.pdf differ diff --git a/Resources/export/playButtonLarge.png b/Resources/export/playButtonLarge.png new file mode 100644 index 0000000..a489b7b Binary files /dev/null and b/Resources/export/playButtonLarge.png differ diff --git a/Resources/export/playButtonLarge@2x.png b/Resources/export/playButtonLarge@2x.png new file mode 100644 index 0000000..109a9ca Binary files /dev/null and b/Resources/export/playButtonLarge@2x.png differ diff --git a/Resources/icons.sketch b/Resources/icons.sketch index 70a35a3..1631adf 100644 Binary files a/Resources/icons.sketch and b/Resources/icons.sketch differ