Add volume control
@ -55,6 +55,9 @@
|
|||||||
E450AD7E222620A10091BED3 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD7D222620A10091BED3 /* Album.swift */; };
|
E450AD7E222620A10091BED3 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD7D222620A10091BED3 /* Album.swift */; };
|
||||||
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */; };
|
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */; };
|
||||||
E451E36E22BD2501008BE9B2 /* DraggedSong.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */; };
|
E451E36E22BD2501008BE9B2 /* DraggedSong.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */; };
|
||||||
|
E453825223FA0186007F6BFC /* VolumeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E453825023FA0186007F6BFC /* VolumeControlView.swift */; };
|
||||||
|
E453825323FA0186007F6BFC /* VolumeControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E453825123FA0186007F6BFC /* VolumeControlView.xib */; };
|
||||||
|
E453825523FA347C007F6BFC /* MPDClient+Mixer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */; };
|
||||||
E45878382296173C00586A1C /* AlbumDetailSongRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */; };
|
E45878382296173C00586A1C /* AlbumDetailSongRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */; };
|
||||||
E45962C62241A78500FC1A1E /* MPDCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45962C52241A78500FC1A1E /* MPDCommand.swift */; };
|
E45962C62241A78500FC1A1E /* MPDCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45962C52241A78500FC1A1E /* MPDCommand.swift */; };
|
||||||
E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD722515D87004B537F /* CHANGELOG.md */; };
|
E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD722515D87004B537F /* CHANGELOG.md */; };
|
||||||
@ -259,6 +262,9 @@
|
|||||||
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; };
|
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; };
|
||||||
E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongType.swift; sourceTree = "<group>"; };
|
E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongType.swift; sourceTree = "<group>"; };
|
||||||
E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSong.swift; sourceTree = "<group>"; };
|
E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSong.swift; sourceTree = "<group>"; };
|
||||||
|
E453825023FA0186007F6BFC /* VolumeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeControlView.swift; sourceTree = "<group>"; };
|
||||||
|
E453825123FA0186007F6BFC /* VolumeControlView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VolumeControlView.xib; sourceTree = "<group>"; };
|
||||||
|
E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPDClient+Mixer.swift"; sourceTree = "<group>"; };
|
||||||
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongRowView.swift; sourceTree = "<group>"; };
|
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongRowView.swift; sourceTree = "<group>"; };
|
||||||
E45962C52241A78500FC1A1E /* MPDCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDCommand.swift; sourceTree = "<group>"; };
|
E45962C52241A78500FC1A1E /* MPDCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDCommand.swift; sourceTree = "<group>"; };
|
||||||
E45E4FD722515D87004B537F /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; };
|
E45E4FD722515D87004B537F /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; };
|
||||||
@ -446,14 +452,15 @@
|
|||||||
E42410B52241B956005ED6DF /* MPDClient+Database.swift */,
|
E42410B52241B956005ED6DF /* MPDClient+Database.swift */,
|
||||||
E41E5304223BFB0700173814 /* MPDClient+Error.swift */,
|
E41E5304223BFB0700173814 /* MPDClient+Error.swift */,
|
||||||
E41E5302223BF9C300173814 /* MPDClient+Idle.swift */,
|
E41E5302223BF9C300173814 /* MPDClient+Idle.swift */,
|
||||||
|
E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */,
|
||||||
E41E5300223BF99300173814 /* MPDClient+Queue.swift */,
|
E41E5300223BF99300173814 /* MPDClient+Queue.swift */,
|
||||||
E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */,
|
E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */,
|
||||||
E408D3BD220E03EE0006D9BE /* RawRepresentable.swift */,
|
|
||||||
E41E5306223C019100173814 /* MPDClient+Status.swift */,
|
E41E5306223C019100173814 /* MPDClient+Status.swift */,
|
||||||
E41E52FE223BF95E00173814 /* MPDClient+Transport.swift */,
|
E41E52FE223BF95E00173814 /* MPDClient+Transport.swift */,
|
||||||
E4DCCFAC23E4DB5D009A8113 /* MPDClientWrapper.h */,
|
|
||||||
E4DCCFAD23E4DB5D009A8113 /* MPDClientWrapper.c */,
|
E4DCCFAD23E4DB5D009A8113 /* MPDClientWrapper.c */,
|
||||||
|
E4DCCFAC23E4DB5D009A8113 /* MPDClientWrapper.h */,
|
||||||
E4DCCFAB23E4DB5D009A8113 /* Persephone-Bridging-Header.h */,
|
E4DCCFAB23E4DB5D009A8113 /* Persephone-Bridging-Header.h */,
|
||||||
|
E408D3BD220E03EE0006D9BE /* RawRepresentable.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -520,6 +527,7 @@
|
|||||||
E442CCC42347D5B900004E0C /* Components */ = {
|
E442CCC42347D5B900004E0C /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E453824D23F9F700007F6BFC /* VolumeControl */,
|
||||||
E442CCCB2347D77A00004E0C /* Browser */,
|
E442CCCB2347D77A00004E0C /* Browser */,
|
||||||
E4A83BEC2221F5DD0098FED6 /* Preferences */,
|
E4A83BEC2221F5DD0098FED6 /* Preferences */,
|
||||||
E442CCC62347D5E700004E0C /* Queue */,
|
E442CCC62347D5E700004E0C /* Queue */,
|
||||||
@ -603,6 +611,15 @@
|
|||||||
path = Browser;
|
path = Browser;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
E453824D23F9F700007F6BFC /* VolumeControl */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
E453825023FA0186007F6BFC /* VolumeControlView.swift */,
|
||||||
|
E453825123FA0186007F6BFC /* VolumeControlView.xib */,
|
||||||
|
);
|
||||||
|
path = VolumeControl;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
E4A642DB220912FA00067D21 /* MPDClient */ = {
|
E4A642DB220912FA00067D21 /* MPDClient */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -873,6 +890,7 @@
|
|||||||
files = (
|
files = (
|
||||||
E45E4FDB22515D87004B537F /* Brewfile in Resources */,
|
E45E4FDB22515D87004B537F /* Brewfile in Resources */,
|
||||||
E42A8F3B22176D6400A13ED9 /* LICENSE.md in Resources */,
|
E42A8F3B22176D6400A13ED9 /* LICENSE.md in Resources */,
|
||||||
|
E453825323FA0186007F6BFC /* VolumeControlView.xib in Resources */,
|
||||||
E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */,
|
E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */,
|
||||||
E43B67AB22909793007DCF55 /* AlbumDetailView.xib in Resources */,
|
E43B67AB22909793007DCF55 /* AlbumDetailView.xib in Resources */,
|
||||||
E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */,
|
E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */,
|
||||||
@ -979,6 +997,7 @@
|
|||||||
E419E2872249B96600216A8C /* Song.swift in Sources */,
|
E419E2872249B96600216A8C /* Song.swift in Sources */,
|
||||||
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */,
|
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */,
|
||||||
E4BBD2F323357C0700702C16 /* ArtistListState.swift in Sources */,
|
E4BBD2F323357C0700702C16 /* ArtistListState.swift in Sources */,
|
||||||
|
E453825223FA0186007F6BFC /* VolumeControlView.swift in Sources */,
|
||||||
E44051A0227BB0AB0090CD6F /* UIState.swift in Sources */,
|
E44051A0227BB0AB0090CD6F /* UIState.swift in Sources */,
|
||||||
E4FF718E2276010E00D4C412 /* PreferencesState.swift in Sources */,
|
E4FF718E2276010E00D4C412 /* PreferencesState.swift in Sources */,
|
||||||
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
|
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
|
||||||
@ -997,6 +1016,7 @@
|
|||||||
E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */,
|
E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */,
|
||||||
E4B5AE7E22F4C49600CCEC65 /* MPDServerDelegate.swift in Sources */,
|
E4B5AE7E22F4C49600CCEC65 /* MPDServerDelegate.swift in Sources */,
|
||||||
E4B11BB8227538FA0075461B /* CurrentCoverArtView.swift in Sources */,
|
E4B11BB8227538FA0075461B /* CurrentCoverArtView.swift in Sources */,
|
||||||
|
E453825523FA347C007F6BFC /* MPDClient+Mixer.swift in Sources */,
|
||||||
E4E8CC9A22075D370024217A /* MPDSong.swift in Sources */,
|
E4E8CC9A22075D370024217A /* MPDSong.swift in Sources */,
|
||||||
E41EA46C221636AF0068EF46 /* GeneralPrefsViewController.swift in Sources */,
|
E41EA46C221636AF0068EF46 /* GeneralPrefsViewController.swift in Sources */,
|
||||||
E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */,
|
E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */,
|
||||||
|
|||||||
25
Persephone/Assets.xcassets/speakerDisabled.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerDisabled.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerDisabled@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled.png
vendored
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 566 B |
25
Persephone/Assets.xcassets/speakerHigh.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerHigh.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerHigh@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh.png
vendored
Normal file
|
After Width: | Height: | Size: 428 B |
BIN
Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 800 B |
25
Persephone/Assets.xcassets/speakerLow.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerLow.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerLow@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Persephone/Assets.xcassets/speakerLow.imageset/speakerLow.png
vendored
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
Persephone/Assets.xcassets/speakerLow.imageset/speakerLow@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 531 B |
25
Persephone/Assets.xcassets/speakerMid.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerMid.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerMid@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Persephone/Assets.xcassets/speakerMid.imageset/speakerMid.png
vendored
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
Persephone/Assets.xcassets/speakerMid.imageset/speakerMid@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 648 B |
25
Persephone/Assets.xcassets/speakerOff.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerOff.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "speakerOff@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Persephone/Assets.xcassets/speakerOff.imageset/speakerOff.png
vendored
Normal file
|
After Width: | Height: | Size: 256 B |
BIN
Persephone/Assets.xcassets/speakerOff.imageset/speakerOff@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 383 B |
@ -15,4 +15,10 @@ extension NSImage {
|
|||||||
static let queuePauseIcon = NSImage(named: "queuePauseButton")
|
static let queuePauseIcon = NSImage(named: "queuePauseButton")
|
||||||
|
|
||||||
static let defaultCoverArt = NSImage(named: "defaultCoverArt")
|
static let defaultCoverArt = NSImage(named: "defaultCoverArt")
|
||||||
|
|
||||||
|
static let speakerDisabled = NSImage(named: "speakerDisabled")
|
||||||
|
static let speakerOff = NSImage(named: "speakerOff")
|
||||||
|
static let speakerLow = NSImage(named: "speakerLow")
|
||||||
|
static let speakerMid = NSImage(named: "speakerMid")
|
||||||
|
static let speakerHigh = NSImage(named: "speakerHigh")
|
||||||
}
|
}
|
||||||
|
|||||||
45
Persephone/Components/VolumeControl/VolumeControlView.swift
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// VolumeControlView.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2/16/20.
|
||||||
|
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AppKit
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
class VolumeControlView: NSViewController {
|
||||||
|
static let shared = VolumeControlView()
|
||||||
|
static let popover = NSPopover()
|
||||||
|
|
||||||
|
var currentVolume: Int = 0
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
App.store.subscribe(self) {
|
||||||
|
$0.select { $0.playerState }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func volumeSliderAction(_ sender: NSSlider) {
|
||||||
|
let newVolume = sender.integerValue
|
||||||
|
|
||||||
|
if newVolume != currentVolume {
|
||||||
|
App.mpdClient.setVolume(to: newVolume)
|
||||||
|
currentVolume = newVolume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBOutlet var volumeSlider: NSSlider!
|
||||||
|
}
|
||||||
|
|
||||||
|
extension VolumeControlView: StoreSubscriber {
|
||||||
|
typealias StoreSubscriberStateType = PlayerState
|
||||||
|
|
||||||
|
func newState(state: StoreSubscriberStateType) {
|
||||||
|
volumeSlider.integerValue = state.volume
|
||||||
|
currentVolume = state.volume
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Persephone/Components/VolumeControl/VolumeControlView.xib
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="VolumeControlView" customModule="Persephone" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||||
|
<outlet property="volumeSlider" destination="E78-vZ-qV0" id="7qP-Fm-MDY"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<customView id="Hz6-mo-xeY">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="36" height="145"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<slider horizontalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E78-vZ-qV0" userLabel="Volume Slider">
|
||||||
|
<rect key="frame" x="9" y="12" width="19" height="121"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<sliderCell key="cell" continuous="YES" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="right" sliderType="linear" id="22u-9w-IXT"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="volumeSliderAction:" target="-2" id="1yh-vH-sgN"/>
|
||||||
|
</connections>
|
||||||
|
</slider>
|
||||||
|
</subviews>
|
||||||
|
<point key="canvasLocation" x="-83" y="90.5"/>
|
||||||
|
</customView>
|
||||||
|
</objects>
|
||||||
|
</document>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16085" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16085"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
@ -208,7 +208,7 @@
|
|||||||
<rect key="frame" x="0.0" y="14" width="153" height="24"/>
|
<rect key="frame" x="0.0" y="14" width="153" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="momentary" id="EBk-sD-nG7">
|
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="momentary" id="EBk-sD-nG7">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment image="prevTrackButton" width="32" enabled="NO"/>
|
<segment image="prevTrackButton" width="32" enabled="NO"/>
|
||||||
<segment image="playButton" width="48" enabled="NO" tag="1"/>
|
<segment image="playButton" width="48" enabled="NO" tag="1"/>
|
||||||
@ -230,7 +230,7 @@
|
|||||||
<rect key="frame" x="16" y="14" width="55" height="17"/>
|
<rect key="frame" x="16" y="14" width="55" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" placeholderString="8:88:88" 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="label" size="13"/>
|
||||||
<color key="textColor" name="tertiaryLabelColor" 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>
|
||||||
@ -257,7 +257,7 @@
|
|||||||
<rect key="frame" x="16" y="14" width="60" height="17"/>
|
<rect key="frame" x="16" y="14" width="60" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="-8:88:88" 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="label" size="13"/>
|
||||||
<color key="textColor" name="tertiaryLabelColor" 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>
|
||||||
@ -277,9 +277,9 @@
|
|||||||
<button key="view" verticalHuggingPriority="750" id="E8L-uK-XT0">
|
<button key="view" verticalHuggingPriority="750" id="E8L-uK-XT0">
|
||||||
<rect key="frame" x="2" y="14" width="42" height="24"/>
|
<rect key="frame" x="2" y="14" width="42" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="shuffleButton" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" inset="2" id="YNb-hd-ax8">
|
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="shuffleButton" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" inset="2" id="YNb-hd-ax8">
|
||||||
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="handleShuffleButton:" target="B8D-0N-5wS" id="THd-0g-fmb"/>
|
<action selector="handleShuffleButton:" target="B8D-0N-5wS" id="THd-0g-fmb"/>
|
||||||
@ -295,7 +295,7 @@
|
|||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="repeatButton" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" inset="2" id="1bu-vK-3Hb">
|
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="repeatButton" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" inset="2" id="1bu-vK-3Hb">
|
||||||
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="handleRepeatButton:" target="B8D-0N-5wS" id="EN2-u4-DNl"/>
|
<action selector="handleRepeatButton:" target="B8D-0N-5wS" id="EN2-u4-DNl"/>
|
||||||
@ -308,7 +308,7 @@
|
|||||||
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
|
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="F3N-3P-tS3">
|
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="F3N-3P-tS3">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</searchFieldCell>
|
</searchFieldCell>
|
||||||
@ -317,6 +317,20 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</searchField>
|
</searchField>
|
||||||
</toolbarItem>
|
</toolbarItem>
|
||||||
|
<toolbarItem implicitItemIdentifier="01E8DA80-2BDE-49F9-B311-69876CF0AE8E" label="Volume" paletteLabel="Volume" image="speakerHigh" sizingBehavior="auto" id="cMg-Mj-j7q">
|
||||||
|
<nil key="toolTip"/>
|
||||||
|
<button key="view" verticalHuggingPriority="750" id="cfN-LI-Cab">
|
||||||
|
<rect key="frame" x="2" y="14" width="42" height="24"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="speakerHigh" imagePosition="overlaps" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bJh-X9-7q0">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="label" size="13"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="showVolumeControl:" target="B8D-0N-5wS" id="UoW-fa-jBM"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</toolbarItem>
|
||||||
</allowedToolbarItems>
|
</allowedToolbarItems>
|
||||||
<defaultToolbarItems>
|
<defaultToolbarItems>
|
||||||
<toolbarItem reference="p3r-ty-Pxf"/>
|
<toolbarItem reference="p3r-ty-Pxf"/>
|
||||||
@ -329,6 +343,8 @@
|
|||||||
<toolbarItem reference="s1h-EC-nvL"/>
|
<toolbarItem reference="s1h-EC-nvL"/>
|
||||||
<toolbarItem reference="5U7-UV-xn2"/>
|
<toolbarItem reference="5U7-UV-xn2"/>
|
||||||
<toolbarItem reference="9ol-aR-mzv"/>
|
<toolbarItem reference="9ol-aR-mzv"/>
|
||||||
|
<toolbarItem reference="cMg-Mj-j7q"/>
|
||||||
|
<toolbarItem reference="mhg-16-CNM"/>
|
||||||
<toolbarItem reference="FRe-rR-Ulo"/>
|
<toolbarItem reference="FRe-rR-Ulo"/>
|
||||||
</defaultToolbarItems>
|
</defaultToolbarItems>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
@ -345,6 +361,7 @@
|
|||||||
<outlet property="trackProgressBar" destination="KMy-xf-rmN" id="a67-JU-cyQ"/>
|
<outlet property="trackProgressBar" destination="KMy-xf-rmN" id="a67-JU-cyQ"/>
|
||||||
<outlet property="trackRemaining" destination="9WZ-ij-lrb" id="0pH-d7-wvD"/>
|
<outlet property="trackRemaining" destination="9WZ-ij-lrb" id="0pH-d7-wvD"/>
|
||||||
<outlet property="transportControls" destination="EBk-sD-nG7" id="yOo-58-Fby"/>
|
<outlet property="transportControls" destination="EBk-sD-nG7" id="yOo-58-Fby"/>
|
||||||
|
<outlet property="volumeState" destination="cfN-LI-Cab" id="hrE-SY-J9E"/>
|
||||||
<segue destination="fnD-7K-pHK" kind="relationship" relationship="window.shadowedContentViewController" id="fQQ-kB-KVc"/>
|
<segue destination="fnD-7K-pHK" kind="relationship" relationship="window.shadowedContentViewController" id="fQQ-kB-KVc"/>
|
||||||
</connections>
|
</connections>
|
||||||
</windowController>
|
</windowController>
|
||||||
@ -409,7 +426,7 @@
|
|||||||
<tabView key="tabView" type="noTabsNoBorder" id="6dC-M0-oC5">
|
<tabView key="tabView" type="noTabsNoBorder" id="6dC-M0-oC5">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="418" height="300"/>
|
<rect key="frame" x="0.0" y="0.0" width="418" height="300"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="zhe-qh-Mal" id="LUL-qN-JlP"/>
|
<outlet property="delegate" destination="zhe-qh-Mal" id="LUL-qN-JlP"/>
|
||||||
</connections>
|
</connections>
|
||||||
@ -439,7 +456,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<buttonCell key="cell" type="check" title="Fetch missing artwork from MusicBrainz" bezelStyle="regularSquare" imagePosition="left" enabled="NO" inset="2" id="LpD-Ew-HMd">
|
<buttonCell key="cell" type="check" title="Fetch missing artwork from MusicBrainz" bezelStyle="regularSquare" imagePosition="left" enabled="NO" inset="2" id="LpD-Ew-HMd">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="updateFetchMissingArtworkFromInternet:" target="3C9-vU-zjZ" id="I7x-9V-xJr"/>
|
<action selector="updateFetchMissingArtworkFromInternet:" target="3C9-vU-zjZ" id="I7x-9V-xJr"/>
|
||||||
@ -449,7 +466,7 @@
|
|||||||
<rect key="frame" x="78" y="21" width="185" height="32"/>
|
<rect key="frame" x="78" y="21" width="185" height="32"/>
|
||||||
<buttonCell key="cell" type="push" title="Clear album art cache..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="l81-SG-7mf">
|
<buttonCell key="cell" type="push" title="Clear album art cache..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="l81-SG-7mf">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="clearAlbumArtCache:" target="3C9-vU-zjZ" id="tXg-rz-lvh"/>
|
<action selector="clearAlbumArtCache:" target="3C9-vU-zjZ" id="tXg-rz-lvh"/>
|
||||||
@ -482,7 +499,7 @@
|
|||||||
<subviews>
|
<subviews>
|
||||||
<tabView type="noTabsNoBorder" initialItem="XgS-cX-SDH" translatesAutoresizingMaskIntoConstraints="NO" id="ARv-cj-xlz">
|
<tabView type="noTabsNoBorder" initialItem="XgS-cX-SDH" translatesAutoresizingMaskIntoConstraints="NO" id="ARv-cj-xlz">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="478" height="558"/>
|
<rect key="frame" x="0.0" y="0.0" width="478" height="558"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<tabViewItems>
|
<tabViewItems>
|
||||||
<tabViewItem label="Albums" identifier="" id="XgS-cX-SDH">
|
<tabViewItem label="Albums" identifier="" id="XgS-cX-SDH">
|
||||||
<view key="view" id="hB7-hN-SbB">
|
<view key="view" id="hB7-hN-SbB">
|
||||||
@ -547,7 +564,7 @@
|
|||||||
<real key="minimum" value="0.0"/>
|
<real key="minimum" value="0.0"/>
|
||||||
<real key="maximum" value="65535"/>
|
<real key="maximum" value="65535"/>
|
||||||
</numberFormatter>
|
</numberFormatter>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -558,7 +575,7 @@
|
|||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kvB-99-zwY">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kvB-99-zwY">
|
||||||
<rect key="frame" x="76" y="61" width="80" height="16"/>
|
<rect key="frame" x="76" y="61" width="80" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Server Host:" id="AVi-g9-Irz">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Server Host:" id="AVi-g9-Irz">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -569,7 +586,7 @@
|
|||||||
<constraint firstAttribute="width" constant="72" id="Of6-Ls-knP"/>
|
<constraint firstAttribute="width" constant="72" id="Of6-Ls-knP"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Server Port:" id="DgA-xT-2ir">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Server Port:" id="DgA-xT-2ir">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -624,7 +641,7 @@
|
|||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="99v-Rb-3kv">
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="99v-Rb-3kv">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -669,7 +686,7 @@
|
|||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="zb2-QK-DhK">
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="zb2-QK-DhK">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -690,7 +707,7 @@
|
|||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="i0h-bn-auJ" userLabel="Song Title View">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="i0h-bn-auJ" userLabel="Song Title View">
|
||||||
<rect key="frame" x="1" y="23" width="211" height="16"/>
|
<rect key="frame" x="1" y="23" width="211" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Song Title" id="ei8-1e-ErK">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Song Title" id="ei8-1e-ErK">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -717,7 +734,7 @@
|
|||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="JOa-Mc-ceQ">
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="JOa-Mc-ceQ">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -734,7 +751,7 @@
|
|||||||
<constraint firstAttribute="height" constant="17" id="grB-CG-1vJ"/>
|
<constraint firstAttribute="height" constant="17" id="grB-CG-1vJ"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="right" title="88:88" id="JnJ-sF-vCP">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="right" title="88:88" id="JnJ-sF-vCP">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="label" size="13"/>
|
||||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
@ -883,6 +900,7 @@
|
|||||||
<image name="prevTrackButton" width="17" height="17"/>
|
<image name="prevTrackButton" width="17" height="17"/>
|
||||||
<image name="repeatButton" width="17" height="17"/>
|
<image name="repeatButton" width="17" height="17"/>
|
||||||
<image name="shuffleButton" width="17" height="17"/>
|
<image name="shuffleButton" width="17" height="17"/>
|
||||||
|
<image name="speakerHigh" width="21" height="17"/>
|
||||||
<image name="stopButton" width="17" height="17"/>
|
<image name="stopButton" width="17" height="17"/>
|
||||||
</resources>
|
</resources>
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@ -27,6 +27,8 @@ class WindowController: NSWindowController {
|
|||||||
@IBOutlet var shuffleState: NSButton!
|
@IBOutlet var shuffleState: NSButton!
|
||||||
@IBOutlet var repeatState: NSButton!
|
@IBOutlet var repeatState: NSButton!
|
||||||
|
|
||||||
|
@IBOutlet var volumeState: NSButton!
|
||||||
|
|
||||||
@IBOutlet weak var searchQuery: NSSearchField!
|
@IBOutlet weak var searchQuery: NSSearchField!
|
||||||
|
|
||||||
override func windowDidLoad() {
|
override func windowDidLoad() {
|
||||||
@ -121,6 +123,25 @@ class WindowController: NSWindowController {
|
|||||||
trackRemaining.stringValue = time.formattedTime
|
trackRemaining.stringValue = time.formattedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setVolumeControlIcon(_ state: PlayerState) {
|
||||||
|
volumeState.isEnabled = state.volume != -1
|
||||||
|
|
||||||
|
switch state.volume {
|
||||||
|
case -1:
|
||||||
|
volumeState.image = .speakerDisabled
|
||||||
|
case 0..<5:
|
||||||
|
volumeState.image = .speakerOff
|
||||||
|
case 5..<40:
|
||||||
|
volumeState.image = .speakerLow
|
||||||
|
case 40..<70:
|
||||||
|
volumeState.image = .speakerMid
|
||||||
|
case 70...100:
|
||||||
|
volumeState.image = .speakerHigh
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc func willDisconnect() {
|
@objc func willDisconnect() {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
App.store.dispatch(SetSearchQuery(searchQuery: ""))
|
App.store.dispatch(SetSearchQuery(searchQuery: ""))
|
||||||
@ -176,6 +197,16 @@ class WindowController: NSWindowController {
|
|||||||
@IBAction func handleSearchQuery(_ sender: NSSearchField) {
|
@IBAction func handleSearchQuery(_ sender: NSSearchField) {
|
||||||
App.store.dispatch(SetSearchQuery(searchQuery: sender.stringValue))
|
App.store.dispatch(SetSearchQuery(searchQuery: sender.stringValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func showVolumeControl(_ sender: NSButton) {
|
||||||
|
VolumeControlView.popover.contentViewController = VolumeControlView.shared
|
||||||
|
VolumeControlView.popover.behavior = .transient
|
||||||
|
VolumeControlView.popover.show(
|
||||||
|
relativeTo: sender.bounds,
|
||||||
|
of: sender,
|
||||||
|
preferredEdge: .maxY
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension WindowController: NSWindowDelegate {
|
extension WindowController: NSWindowDelegate {
|
||||||
@ -201,6 +232,7 @@ extension WindowController: StoreSubscriber {
|
|||||||
self.setShuffleRepeatState(state.playerState)
|
self.setShuffleRepeatState(state.playerState)
|
||||||
self.setTrackProgressControls(state.playerState)
|
self.setTrackProgressControls(state.playerState)
|
||||||
self.setDatabaseUpdatingIndicator(state.uiState)
|
self.setDatabaseUpdatingIndicator(state.uiState)
|
||||||
|
self.setVolumeControlIcon(state.playerState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,11 @@ extension MPDClient {
|
|||||||
else { return }
|
else { return }
|
||||||
sendRepeatState(repeatState: repeatState)
|
sendRepeatState(repeatState: repeatState)
|
||||||
|
|
||||||
|
case .setVolume:
|
||||||
|
guard let volume = userData["volume"] as? Int
|
||||||
|
else { return }
|
||||||
|
sendSetVolume(to: volume)
|
||||||
|
|
||||||
// Database commands
|
// Database commands
|
||||||
case .updateDatabase:
|
case .updateDatabase:
|
||||||
sendUpdateDatabase()
|
sendUpdateDatabase()
|
||||||
|
|||||||
@ -64,7 +64,9 @@ extension MPDClient {
|
|||||||
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
|
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mpdIdle.contains(.player) || mpdIdle.contains(.options) {
|
if mpdIdle.contains(.player) ||
|
||||||
|
mpdIdle.contains(.options) ||
|
||||||
|
mpdIdle.contains(.mixer) {
|
||||||
self.fetchStatus()
|
self.fetchStatus()
|
||||||
|
|
||||||
if let status = self.status {
|
if let status = self.status {
|
||||||
|
|||||||
24
Persephone/MPDClient/Extensions/MPDClient+Mixer.swift
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// MPDClient+Mixer.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2/16/20.
|
||||||
|
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import mpdclient
|
||||||
|
|
||||||
|
extension MPDClient {
|
||||||
|
func setVolume(to volume: Int) {
|
||||||
|
enqueueCommand(
|
||||||
|
command: .setVolume,
|
||||||
|
priority: .high,
|
||||||
|
userData: ["volume": volume]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendSetVolume(to volume: Int) {
|
||||||
|
mpd_run_set_volume(connection, UInt32(volume))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,8 @@ extension MPDClient {
|
|||||||
case setShuffleState
|
case setShuffleState
|
||||||
case setRepeatState
|
case setRepeatState
|
||||||
|
|
||||||
|
case setVolume
|
||||||
|
|
||||||
// Database commands
|
// Database commands
|
||||||
case updateDatabase
|
case updateDatabase
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,10 @@ extension MPDClient {
|
|||||||
return mpd_status_get_repeat(status)
|
return mpd_status_get_repeat(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var volume: Int {
|
||||||
|
return Int(mpd_status_get_volume(status))
|
||||||
|
}
|
||||||
|
|
||||||
var updating: Bool {
|
var updating: Bool {
|
||||||
let updating = mpd_status_get_update_id(status)
|
let updating = mpd_status_get_update_id(status)
|
||||||
|
|
||||||
|
|||||||
@ -20,3 +20,7 @@ struct UpdateElapsedTimeAction: Action {
|
|||||||
struct UpdateStatusAction: Action {
|
struct UpdateStatusAction: Action {
|
||||||
var status: MPDClient.MPDStatus
|
var status: MPDClient.MPDStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct UpdateVolumeAction: Action {
|
||||||
|
var volume: Int
|
||||||
|
}
|
||||||
|
|||||||
@ -17,16 +17,19 @@ struct PlayerState: StateType {
|
|||||||
var shuffleState: Bool = false
|
var shuffleState: Bool = false
|
||||||
var repeatState: Bool = false
|
var repeatState: Bool = false
|
||||||
|
|
||||||
|
var volume: Int = 0
|
||||||
|
|
||||||
var totalTime: UInt?
|
var totalTime: UInt?
|
||||||
var elapsedTimeMs: UInt?
|
var elapsedTimeMs: UInt?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PlayerState: Equatable {
|
extension PlayerState: Equatable {
|
||||||
static func == (lhs: PlayerState, rhs: PlayerState) -> Bool {
|
static func == (lhs: PlayerState, rhs: PlayerState) -> Bool {
|
||||||
return (lhs.state == rhs.state) &&
|
return lhs.state == rhs.state &&
|
||||||
(lhs.totalTime == rhs.totalTime) &&
|
lhs.totalTime == rhs.totalTime &&
|
||||||
(lhs.elapsedTimeMs == rhs.elapsedTimeMs) &&
|
lhs.elapsedTimeMs == rhs.elapsedTimeMs &&
|
||||||
(lhs.shuffleState == rhs.shuffleState) &&
|
lhs.shuffleState == rhs.shuffleState &&
|
||||||
(lhs.repeatState == rhs.repeatState)
|
lhs.repeatState == rhs.repeatState &&
|
||||||
|
lhs.volume == rhs.volume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState {
|
|||||||
state.elapsedTimeMs = action.status.elapsedTimeMs
|
state.elapsedTimeMs = action.status.elapsedTimeMs
|
||||||
state.shuffleState = action.status.shuffleState
|
state.shuffleState = action.status.shuffleState
|
||||||
state.repeatState = action.status.repeatState
|
state.repeatState = action.status.repeatState
|
||||||
|
state.volume = action.status.volume
|
||||||
|
|
||||||
if state.state == .playing {
|
if state.state == .playing {
|
||||||
App.trackTimer.start(elapsedTimeMs: state.elapsedTimeMs)
|
App.trackTimer.start(elapsedTimeMs: state.elapsedTimeMs)
|
||||||
|
|||||||
BIN
Resources/export/speakerDisabled.pdf
Normal file
BIN
Resources/export/speakerDisabled.png
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
Resources/export/speakerDisabled@2x.png
Normal file
|
After Width: | Height: | Size: 566 B |
BIN
Resources/export/speakerHigh.pdf
Normal file
BIN
Resources/export/speakerHigh.png
Normal file
|
After Width: | Height: | Size: 428 B |
BIN
Resources/export/speakerHigh@2x.png
Normal file
|
After Width: | Height: | Size: 800 B |
BIN
Resources/export/speakerLow.pdf
Normal file
BIN
Resources/export/speakerLow.png
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
Resources/export/speakerLow@2x.png
Normal file
|
After Width: | Height: | Size: 531 B |
BIN
Resources/export/speakerMid.pdf
Normal file
BIN
Resources/export/speakerMid.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
Resources/export/speakerMid@2x.png
Normal file
|
After Width: | Height: | Size: 648 B |
BIN
Resources/export/speakerOff.pdf
Normal file
BIN
Resources/export/speakerOff.png
Normal file
|
After Width: | Height: | Size: 256 B |
BIN
Resources/export/speakerOff@2x.png
Normal file
|
After Width: | Height: | Size: 383 B |