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

Compare commits

...

2 Commits

Author SHA1 Message Date
7d390f45c6
Move some things into extensions 2019-02-19 19:34:08 -05:00
8749be7544
Finish up number display and add seek function 2019-02-19 19:16:44 -05:00
8 changed files with 98 additions and 33 deletions

View File

@ -22,6 +22,8 @@
E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (Required, ); }; }; E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (Required, ); }; };
E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41B22C521FB932700D544F6 /* MPDClient.swift */; }; E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41B22C521FB932700D544F6 /* MPDClient.swift */; };
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = E435E3E1221CD4E200184CFC /* NSFont.swift */; };
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E435E3E3221CD75D00184CFC /* NSImage.swift */; };
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; }; E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; };
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; }; E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; };
E4A642DA22090CBE00067D21 /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A642D922090CBE00067D21 /* Status.swift */; }; E4A642DA22090CBE00067D21 /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A642D922090CBE00067D21 /* Status.swift */; };
@ -122,6 +124,8 @@
E41B22E921FB966C00D544F6 /* capabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = capabilities.h; sourceTree = "<group>"; }; E41B22E921FB966C00D544F6 /* capabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = capabilities.h; sourceTree = "<group>"; };
E41B22EA21FB966C00D544F6 /* queue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = queue.h; sourceTree = "<group>"; }; E41B22EA21FB966C00D544F6 /* queue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = queue.h; sourceTree = "<group>"; };
E41B22EB21FB966C00D544F6 /* playlist.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = playlist.h; sourceTree = "<group>"; }; E41B22EB21FB966C00D544F6 /* playlist.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = playlist.h; sourceTree = "<group>"; };
E435E3E1221CD4E200184CFC /* NSFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFont.swift; sourceTree = "<group>"; };
E435E3E3221CD75D00184CFC /* NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = "<group>"; };
E465049921E94DF500A70F4C /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; }; E465049921E94DF500A70F4C /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; }; E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; };
E4A642D922090CBE00067D21 /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; }; E4A642D922090CBE00067D21 /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; };
@ -222,6 +226,8 @@
E4928E0A2218D62A001D4BEA /* CGColor.swift */, E4928E0A2218D62A001D4BEA /* CGColor.swift */,
E408D3B5220DD8970006D9BE /* Notification.swift */, E408D3B5220DD8970006D9BE /* Notification.swift */,
E408D3B8220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift */, E408D3B8220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift */,
E435E3E1221CD4E200184CFC /* NSFont.swift */,
E435E3E3221CD75D00184CFC /* NSImage.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -516,6 +522,8 @@
E408D3BE220E03EE0006D9BE /* RawRepresentable.swift in Sources */, E408D3BE220E03EE0006D9BE /* RawRepresentable.swift in Sources */,
E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */, E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */,
E4EB237B220F7CF1008C70C0 /* Album.swift in Sources */, E4EB237B220F7CF1008C70C0 /* Album.swift in Sources */,
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */,
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -14,12 +14,6 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV
var queueIcon: NSImage? = nil var queueIcon: NSImage? = nil
let systemFontRegular = NSFont.systemFont(ofSize: 13, weight: .regular)
let systemFontBold = NSFont.systemFont(ofSize: 13, weight: .bold)
let playIcon = NSImage(named: "playButton")
let pauseIcon = NSImage(named: "pauseButton")
struct SongItem { struct SongItem {
var song: MPDClient.Song var song: MPDClient.Song
var queuePos: Int var queuePos: Int
@ -98,9 +92,9 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV
func setQueueIcon(_ state: MPDClient.Status.State) { func setQueueIcon(_ state: MPDClient.Status.State) {
switch state { switch state {
case .playing: case .playing:
self.queueIcon = playIcon self.queueIcon = .playIcon
case .paused: case .paused:
self.queueIcon = pauseIcon self.queueIcon = .pauseIcon
default: default:
self.queueIcon = nil self.queueIcon = nil
} }
@ -112,7 +106,7 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV
let oldSongTitleCell = oldSongRow.view(atColumn: 0) as? NSTableCellView let oldSongTitleCell = oldSongRow.view(atColumn: 0) as? NSTableCellView
else { return } else { return }
setRowFont(rowView: oldSongRow, font: systemFontRegular) setRowFont(rowView: oldSongRow, font: .systemFontRegular)
oldSongTitleCell.imageView?.image = nil oldSongTitleCell.imageView?.image = nil
} }
@ -120,7 +114,7 @@ class QueueViewController: NSViewController, NSOutlineViewDataSource, NSOutlineV
let newSongTitleCell = songRow.view(atColumn: 0) as? NSTableCellView let newSongTitleCell = songRow.view(atColumn: 0) as? NSTableCellView
else { return } else { return }
setRowFont(rowView: songRow, font: systemFontBold) setRowFont(rowView: songRow, font: .systemFontBold)
newSongTitleCell.imageView?.image = self.queueIcon newSongTitleCell.imageView?.image = self.queueIcon
} }

View File

@ -18,9 +18,6 @@ class WindowController: NSWindowController {
var elapsedTimeMs: UInt? var elapsedTimeMs: UInt?
var trackTimer: Timer? var trackTimer: Timer?
let playIcon = NSImage(named: "playButton")
let pauseIcon = NSImage(named: "pauseButton")
override func windowDidLoad() { override func windowDidLoad() {
super.windowDidLoad() super.windowDidLoad()
window?.titleVisibility = .hidden window?.titleVisibility = .hidden
@ -38,6 +35,9 @@ class WindowController: NSWindowController {
name: Notification.timeChanged, name: Notification.timeChanged,
object: AppDelegate.mpdClient object: AppDelegate.mpdClient
) )
trackProgress.font = .timerFont
trackRemaining.font = .timerFont
} }
@objc func stateChanged(_ notification: Notification) { @objc func stateChanged(_ notification: Notification) {
@ -58,9 +58,9 @@ class WindowController: NSWindowController {
transportControls.setEnabled(state.isOneOf([.playing, .paused]), forSegment: 3) transportControls.setEnabled(state.isOneOf([.playing, .paused]), forSegment: 3)
if state.isOneOf([.paused, .stopped, .unknown]) { if state.isOneOf([.paused, .stopped, .unknown]) {
transportControls.setImage(playIcon, forSegment: 1) transportControls.setImage(.playIcon, forSegment: 1)
} else { } else {
transportControls.setImage(pauseIcon, forSegment: 1) transportControls.setImage(.pauseIcon, forSegment: 1)
} }
} }
@ -83,6 +83,7 @@ class WindowController: NSWindowController {
trackProgressBar.maxValue = Double(totalTime * 1000) trackProgressBar.maxValue = Double(totalTime * 1000)
trackProgressBar.integerValue = Int(elapsedTimeMs) trackProgressBar.integerValue = Int(elapsedTimeMs)
setTimeElapsed() setTimeElapsed()
setTimeRemaining()
trackProgressBar.isEnabled = [.playing, .paused].contains(state) trackProgressBar.isEnabled = [.playing, .paused].contains(state)
@ -108,6 +109,7 @@ class WindowController: NSWindowController {
trackProgressBar.integerValue = Int(elapsedTimeMs!) trackProgressBar.integerValue = Int(elapsedTimeMs!)
setTimeElapsed() setTimeElapsed()
setTimeRemaining()
} }
func setTimeElapsed() { func setTimeElapsed() {
@ -118,6 +120,16 @@ class WindowController: NSWindowController {
trackProgress.stringValue = time.formattedTime trackProgress.stringValue = time.formattedTime
} }
func setTimeRemaining() {
guard let elapsedTimeMs = elapsedTimeMs,
let totalTime = totalTime
else { return }
let time = Time(timeInSeconds: -(Int(totalTime) - Int(elapsedTimeMs) / 1000))
trackRemaining.stringValue = time.formattedTime
}
@IBAction func handleTransportControl(_ sender: NSSegmentedControl) { @IBAction func handleTransportControl(_ sender: NSSegmentedControl) {
guard let transportAction = TransportAction(rawValue: sender.selectedSegment) guard let transportAction = TransportAction(rawValue: sender.selectedSegment)
else { return } else { return }
@ -134,6 +146,12 @@ class WindowController: NSWindowController {
} }
} }
@IBAction func changeTrackProgress(_ sender: NSSlider) {
let seekTime = Float(sender.integerValue) / 1000
AppDelegate.mpdClient.seekCurrentSong(timeInSeconds: seekTime)
}
@IBOutlet var transportControls: NSSegmentedCell! @IBOutlet var transportControls: NSSegmentedCell!
@IBOutlet var trackProgress: NSTextField! @IBOutlet var trackProgress: NSTextField!

View File

@ -0,0 +1,16 @@
//
// NSFont.swift
// Persephone
//
// Created by Daniel Barber on 2019/2/19.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Cocoa
extension NSFont {
static let systemFontRegular = systemFont(ofSize: 13, weight: .regular)
static let systemFontBold = systemFont(ofSize: 13, weight: .bold)
static let timerFont = monospacedDigitSystemFont(ofSize: 13, weight: .regular)
}

View File

@ -0,0 +1,14 @@
//
// NSImage.swift
// Persephone
//
// Created by Daniel Barber on 2019/2/19.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Cocoa
extension NSImage {
static let playIcon = NSImage(named: "playButton")
static let pauseIcon = NSImage(named: "pauseButton")
}

View File

@ -9,11 +9,11 @@
import Foundation import Foundation
extension Notification { extension Notification {
static let stateChanged = Notification.Name("MPDClientStateChanged") static let stateChanged = Name("MPDClientStateChanged")
static let timeChanged = Notification.Name("MPDClientTimeChanged") static let timeChanged = Name("MPDClientTimeChanged")
static let queueChanged = Notification.Name("MPDClientQueueChanged") static let queueChanged = Name("MPDClientQueueChanged")
static let queuePosChanged = Notification.Name("MPDClientQueuePosChanged") static let queuePosChanged = Name("MPDClientQueuePosChanged")
static let loadedAlbums = Notification.Name("MPDClientLoadedAlbums") static let loadedAlbums = Name("MPDClientLoadedAlbums")
static let stateKey = "state" static let stateKey = "state"
static let queueKey = "queue" static let queueKey = "queue"

View File

@ -110,6 +110,14 @@ class MPDClient {
idle() idle()
} }
func seekCurrentSong(timeInSeconds: Float) {
noIdle()
commandQueue.async { [unowned self] in
mpd_run_seek_current(self.connection, timeInSeconds, false)
}
idle()
}
func queueCommand(command: Command) { func queueCommand(command: Command) {
noIdle() noIdle()
commandQueue.async { [unowned self] in commandQueue.async { [unowned self] in

View File

@ -139,14 +139,16 @@
</segmentedControl> </segmentedControl>
</toolbarItem> </toolbarItem>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="9ol-aR-mzv"/> <toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="9ol-aR-mzv"/>
<toolbarItem implicitItemIdentifier="D72AC4FE-1D0A-420A-8EA8-F28DBFCE9A8E" explicitItemIdentifier="trackProgress" label="Track progress" paletteLabel="Track progress" sizingBehavior="auto" id="n52-8S-6kR"> <toolbarItem implicitItemIdentifier="D72AC4FE-1D0A-420A-8EA8-F28DBFCE9A8E" explicitItemIdentifier="trackProgress" label="Track progress" paletteLabel="Track progress" id="n52-8S-6kR">
<nil key="toolTip"/> <nil key="toolTip"/>
<textField key="view" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="kx6-xm-TAN"> <size key="minSize" width="50" height="17"/>
<rect key="frame" x="14" y="14" width="59" height="17"/> <size key="maxSize" width="55" height="17"/>
<textField key="view" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="50" id="kx6-xm-TAN">
<rect key="frame" x="16" y="14" width="55" height="17"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" placeholderString="00:00" id="g0c-k5-wCA"> <textFieldCell key="cell" lineBreakMode="clipping" alignment="right" placeholderString="8:88:88" id="g0c-k5-wCA">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="tertiaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
@ -154,21 +156,26 @@
<toolbarItem implicitItemIdentifier="71780196-F7F7-466C-8DED-D4AB25336BD1" explicitItemIdentifier="trackProgressBar" label="Track progress bar" paletteLabel="Track progress bar" id="s1h-EC-nvL"> <toolbarItem implicitItemIdentifier="71780196-F7F7-466C-8DED-D4AB25336BD1" explicitItemIdentifier="trackProgressBar" label="Track progress bar" paletteLabel="Track progress bar" id="s1h-EC-nvL">
<nil key="toolTip"/> <nil key="toolTip"/>
<size key="minSize" width="96" height="17"/> <size key="minSize" width="96" height="17"/>
<size key="maxSize" width="1000" height="17"/> <size key="maxSize" width="540" height="17"/>
<slider key="view" verticalHuggingPriority="750" id="KMy-xf-rmN"> <slider key="view" verticalHuggingPriority="750" id="KMy-xf-rmN">
<rect key="frame" x="5" y="14" width="96" height="17"/> <rect key="frame" x="5" y="14" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<sliderCell key="cell" controlSize="small" enabled="NO" state="on" alignment="left" maxValue="100" tickMarkPosition="above" sliderType="linear" id="zAF-pq-e9g"/> <sliderCell key="cell" controlSize="small" enabled="NO" state="on" alignment="left" maxValue="100" tickMarkPosition="above" sliderType="linear" id="zAF-pq-e9g"/>
<connections>
<action selector="changeTrackProgress:" target="B8D-0N-5wS" id="Dkh-9b-A5y"/>
</connections>
</slider> </slider>
</toolbarItem> </toolbarItem>
<toolbarItem implicitItemIdentifier="1FD81C0E-71C5-41A5-9EAE-A6B12A08FA13" label="Track remaining" paletteLabel="Track remaining" sizingBehavior="auto" id="5U7-UV-xn2"> <toolbarItem implicitItemIdentifier="1FD81C0E-71C5-41A5-9EAE-A6B12A08FA13" label="Track remaining" paletteLabel="Track remaining" id="5U7-UV-xn2">
<nil key="toolTip"/> <nil key="toolTip"/>
<textField key="view" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="9WZ-ij-lrb"> <size key="minSize" width="58" height="17"/>
<rect key="frame" x="20" y="14" width="52" height="17"/> <size key="maxSize" width="60" height="17"/>
<textField key="view" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="58" id="9WZ-ij-lrb">
<rect key="frame" x="16" y="14" width="60" height="17"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" placeholderString="-00:00" id="XUa-pD-s5c"> <textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="-8:88:88" id="XUa-pD-s5c">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="tertiaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
@ -176,11 +183,11 @@
</allowedToolbarItems> </allowedToolbarItems>
<defaultToolbarItems> <defaultToolbarItems>
<toolbarItem reference="p3r-ty-Pxf"/> <toolbarItem reference="p3r-ty-Pxf"/>
<toolbarItem reference="mhg-16-CNM"/> <toolbarItem reference="9ol-aR-mzv"/>
<toolbarItem reference="n52-8S-6kR"/> <toolbarItem reference="n52-8S-6kR"/>
<toolbarItem reference="s1h-EC-nvL"/> <toolbarItem reference="s1h-EC-nvL"/>
<toolbarItem reference="5U7-UV-xn2"/> <toolbarItem reference="5U7-UV-xn2"/>
<toolbarItem reference="mhg-16-CNM"/> <toolbarItem reference="9ol-aR-mzv"/>
</defaultToolbarItems> </defaultToolbarItems>
</toolbar> </toolbar>
<connections> <connections>