Add now playing item
This commit is contained in:
parent
88e8d606b4
commit
4b17e0d361
|
@ -14,8 +14,8 @@
|
|||
D6B35B4E22DA479E00F262A2 /* TouchBarItemIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B35B4D22DA479E00F262A2 /* TouchBarItemIdentifiers.swift */; };
|
||||
D6B35B5122DA4A2A00F262A2 /* DFRFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6B35B5022DA4A2A00F262A2 /* DFRFoundation.framework */; };
|
||||
D6B35B5522DA64AD00F262A2 /* RootTouchBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B35B5422DA64AD00F262A2 /* RootTouchBarController.swift */; };
|
||||
D6B35B5A22DA66A400F262A2 /* TouchBarWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B35B5922DA66A400F262A2 /* TouchBarWidget.swift */; };
|
||||
D6B35B5E22DA687E00F262A2 /* NowPlayingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B35B5D22DA687E00F262A2 /* NowPlayingWidget.swift */; };
|
||||
D6B35B6222DA6B2100F262A2 /* NowPlayingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B35B6122DA6B2100F262A2 /* NowPlayingItem.swift */; };
|
||||
D6B35B6522DA6ECC00F262A2 /* MediaRemote.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6B35B6422DA6ECC00F262A2 /* MediaRemote.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
@ -31,8 +31,9 @@
|
|||
D6B35B4D22DA479E00F262A2 /* TouchBarItemIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBarItemIdentifiers.swift; sourceTree = "<group>"; };
|
||||
D6B35B5022DA4A2A00F262A2 /* DFRFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DFRFoundation.framework; path = ../../../../System/Library/PrivateFrameworks/DFRFoundation.framework; sourceTree = "<group>"; };
|
||||
D6B35B5422DA64AD00F262A2 /* RootTouchBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootTouchBarController.swift; sourceTree = "<group>"; };
|
||||
D6B35B5922DA66A400F262A2 /* TouchBarWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBarWidget.swift; sourceTree = "<group>"; };
|
||||
D6B35B5D22DA687E00F262A2 /* NowPlayingWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingWidget.swift; sourceTree = "<group>"; };
|
||||
D6B35B6122DA6B2100F262A2 /* NowPlayingItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingItem.swift; sourceTree = "<group>"; };
|
||||
D6B35B6322DA6E5700F262A2 /* MRMediaRemote.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRMediaRemote.h; sourceTree = "<group>"; };
|
||||
D6B35B6422DA6ECC00F262A2 /* MediaRemote.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaRemote.framework; path = ../../../../System/Library/PrivateFrameworks/MediaRemote.framework; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -41,6 +42,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D6B35B5122DA4A2A00F262A2 /* DFRFoundation.framework in Frameworks */,
|
||||
D6B35B6522DA6ECC00F262A2 /* MediaRemote.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -67,16 +69,16 @@
|
|||
D6B35B3722DA1B3C00F262A2 /* Underbar */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6B35B4A22DA1C8400F262A2 /* Underbar-Bridging-Header.h */,
|
||||
D6B35B3822DA1B3C00F262A2 /* AppDelegate.swift */,
|
||||
D6B35B4D22DA479E00F262A2 /* TouchBarItemIdentifiers.swift */,
|
||||
D6B35B5F22DA6AD500F262A2 /* Private */,
|
||||
D6B35B5722DA669000F262A2 /* Controllers */,
|
||||
D6B35B5822DA669400F262A2 /* Widgets */,
|
||||
D6B35B6022DA6B0400F262A2 /* Items */,
|
||||
D6B35B3C22DA1B3C00F262A2 /* Assets.xcassets */,
|
||||
D6B35B3E22DA1B3C00F262A2 /* Main.storyboard */,
|
||||
D6B35B4122DA1B3C00F262A2 /* Info.plist */,
|
||||
D6B35B4222DA1B3C00F262A2 /* Underbar.entitlements */,
|
||||
D6B35B4822DA1B8D00F262A2 /* NSTouchBar.h */,
|
||||
D6B35B4A22DA1C8400F262A2 /* Underbar-Bridging-Header.h */,
|
||||
);
|
||||
path = Underbar;
|
||||
sourceTree = "<group>";
|
||||
|
@ -84,6 +86,7 @@
|
|||
D6B35B4F22DA4A2A00F262A2 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6B35B6422DA6ECC00F262A2 /* MediaRemote.framework */,
|
||||
D6B35B5022DA4A2A00F262A2 /* DFRFoundation.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
|
@ -98,13 +101,21 @@
|
|||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6B35B5822DA669400F262A2 /* Widgets */ = {
|
||||
D6B35B5F22DA6AD500F262A2 /* Private */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6B35B5922DA66A400F262A2 /* TouchBarWidget.swift */,
|
||||
D6B35B5D22DA687E00F262A2 /* NowPlayingWidget.swift */,
|
||||
D6B35B4822DA1B8D00F262A2 /* NSTouchBar.h */,
|
||||
D6B35B6322DA6E5700F262A2 /* MRMediaRemote.h */,
|
||||
);
|
||||
path = Widgets;
|
||||
path = Private;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6B35B6022DA6B0400F262A2 /* Items */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6B35B6122DA6B2100F262A2 /* NowPlayingItem.swift */,
|
||||
);
|
||||
path = Items;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
@ -177,10 +188,9 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D6B35B5A22DA66A400F262A2 /* TouchBarWidget.swift in Sources */,
|
||||
D6B35B4E22DA479E00F262A2 /* TouchBarItemIdentifiers.swift in Sources */,
|
||||
D6B35B4C22DA466600F262A2 /* TouchBarController.swift in Sources */,
|
||||
D6B35B5E22DA687E00F262A2 /* NowPlayingWidget.swift in Sources */,
|
||||
D6B35B6222DA6B2100F262A2 /* NowPlayingItem.swift in Sources */,
|
||||
D6B35B3922DA1B3C00F262A2 /* AppDelegate.swift in Sources */,
|
||||
D6B35B5522DA64AD00F262A2 /* RootTouchBarController.swift in Sources */,
|
||||
);
|
||||
|
|
|
@ -10,15 +10,11 @@ import Cocoa
|
|||
|
||||
class RootTouchBarController: TouchBarController {
|
||||
|
||||
let nowPlaying = NowPlayingWidget()
|
||||
let nowPlaying = NowPlayingItem(identifier: .nowPlaying)
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
widgets = [
|
||||
nowPlaying
|
||||
]
|
||||
|
||||
touchBar.defaultItemIdentifiers = [
|
||||
.closeUnderbar,
|
||||
.flexibleSpace,
|
||||
|
@ -31,7 +27,7 @@ class RootTouchBarController: TouchBarController {
|
|||
case .closeUnderbar:
|
||||
return createCloseItem()
|
||||
case .nowPlaying:
|
||||
return nowPlaying.item
|
||||
return nowPlaying
|
||||
default:
|
||||
return super.touchBar(touchBar, makeItemForIdentifier: identifier)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import Cocoa
|
|||
class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
let touchBar = NSTouchBar()
|
||||
|
||||
var widgets: [TouchBarWidget] = []
|
||||
|
||||
var isVisible = false
|
||||
|
||||
override init() {
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// NowPlayingItem.swift
|
||||
// Underbar
|
||||
//
|
||||
// Created by Shadowfacts on 7/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import MediaToolbox
|
||||
|
||||
class NowPlayingItem: NSCustomTouchBarItem {
|
||||
|
||||
var nowPlayingTitle: String?
|
||||
var nowPlayingArtist: String?
|
||||
var nowPlayingAlbum: String?
|
||||
var nowPlayingArtwork: Data?
|
||||
|
||||
var button: NSButton!
|
||||
|
||||
var lastPressTime: Date? = nil
|
||||
var multiPressCount: Int = 0
|
||||
var multiPressWorkItem: DispatchWorkItem? = nil
|
||||
|
||||
override init(identifier: NSTouchBarItem.Identifier) {
|
||||
super.init(identifier: identifier)
|
||||
|
||||
button = NSButton(title: "Test\nline 2", target: self, action: #selector(buttonPressed))
|
||||
button.alignment = .left
|
||||
|
||||
button.widthAnchor.constraint(equalToConstant: 200).isActive = true
|
||||
|
||||
view = button
|
||||
|
||||
MRMediaRemoteRegisterForNowPlayingNotifications(.global(qos: .utility))
|
||||
registerForNotifications()
|
||||
|
||||
updateMediaInfo()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func registerForNotifications() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateMediaInfo), name: .init(kMRMediaRemoteNowPlayingApplicationClientStateDidChange), object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateMediaInfo), name: .mrNowPlayingPlaybackQueueChanged, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateMediaInfo), name: .mrNowPlayingPlaybackQueueChanged, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateMediaInfo), name: .mrMediaRemoteNowPlayingApplicationIsPlayingDidChange, object: nil)
|
||||
}
|
||||
|
||||
@objc func updateMediaInfo() {
|
||||
MRMediaRemoteGetNowPlayingInfo(.main) { [weak self] (info) in
|
||||
guard let self = self, let info = info else { return }
|
||||
|
||||
self.nowPlayingTitle = info[kMRMediaRemoteNowPlayingInfoTitle] as? String
|
||||
self.nowPlayingArtist = info[kMRMediaRemoteNowPlayingInfoArtist] as? String
|
||||
self.nowPlayingAlbum = info[kMRMediaRemoteNowPlayingInfoAlbum] as? String
|
||||
self.nowPlayingArtwork = info[kMRMediaRemoteNowPlayingInfoArtworkData] as? Data
|
||||
|
||||
self.updateButtonTitle()
|
||||
self.updateButtonImage()
|
||||
}
|
||||
}
|
||||
|
||||
func updateButtonTitle() {
|
||||
let attributedStr = NSMutableAttributedString()
|
||||
|
||||
|
||||
|
||||
let line1 = NSAttributedString(string: nowPlayingTitle ?? "Unknown")
|
||||
attributedStr.append(line1)
|
||||
attributedStr.setAttributes([.font: NSFont.systemFont(ofSize: 12)], range: NSRange(location: 0, length: line1.length))
|
||||
|
||||
attributedStr.append(NSAttributedString(string: "\n"))
|
||||
|
||||
let line2 = NSAttributedString(string: (nowPlayingArtist ?? "Unknown") + " | " + (nowPlayingAlbum ?? "Unknown"))
|
||||
attributedStr.append(line2)
|
||||
attributedStr.setAttributes([.font: NSFont.systemFont(ofSize: 10)], range: NSRange(location: line1.length + 1, length: line2.length))
|
||||
|
||||
button.attributedTitle = attributedStr
|
||||
}
|
||||
|
||||
func updateButtonImage() {
|
||||
if let data = nowPlayingArtwork,
|
||||
let image = NSImage(data: data) {
|
||||
button.image = image
|
||||
button.imagePosition = .imageLeft
|
||||
} else {
|
||||
button.image = nil
|
||||
}
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
if let lastPressTime = lastPressTime,
|
||||
lastPressTime.timeIntervalSinceNow < 0.2 {
|
||||
multiPressCount += 1
|
||||
multiPressWorkItem?.cancel()
|
||||
} else {
|
||||
self.lastPressTime = Date()
|
||||
multiPressCount = 1
|
||||
}
|
||||
|
||||
multiPressWorkItem = DispatchWorkItem {
|
||||
self.handleMultiPress(presses: self.multiPressCount)
|
||||
self.lastPressTime = nil
|
||||
self.multiPressCount = 0
|
||||
self.multiPressWorkItem = nil
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: multiPressWorkItem!)
|
||||
|
||||
}
|
||||
|
||||
func handleMultiPress(presses: Int) {
|
||||
switch presses {
|
||||
case 1:
|
||||
MRMediaRemoteSendCommand(kMRTogglePlayPause, nil)
|
||||
case 2:
|
||||
MRMediaRemoteSendCommand(kMRNextTrack, nil)
|
||||
case 3:
|
||||
MRMediaRemoteSendCommand(kMRPreviousTrack, nil)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// MRMediaRemote.h
|
||||
// Underbar
|
||||
//
|
||||
// Created by Shadowfacts on 7/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
// Copied from https://github.com/pigigaldi/Pock/blob/852679a4882d0e9c5b3d8473eb9b9fbf7bef837f/Pock/Private/MRMediaRemote.h
|
||||
|
||||
typedef void (^MRMediaRemoteGetNowPlayingInfoBlock)(NSDictionary *info);
|
||||
typedef void (^MRMediaRemoteGetNowPlayingClientBlock)(id clientObj);
|
||||
typedef void (^MRMediaRemoteGetNowPlayingApplicationIsPlayingBlock)(BOOL playing);
|
||||
|
||||
extern void MRMediaRemoteRegisterForNowPlayingNotifications(dispatch_queue_t queue);
|
||||
extern void MRMediaRemoteGetNowPlayingClient(dispatch_queue_t queue, MRMediaRemoteGetNowPlayingClientBlock block);
|
||||
extern void MRMediaRemoteGetNowPlayingClients(dispatch_queue_t queue, MRMediaRemoteGetNowPlayingClientBlock block);
|
||||
extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t queue, MRMediaRemoteGetNowPlayingInfoBlock block);
|
||||
extern void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, MRMediaRemoteGetNowPlayingApplicationIsPlayingBlock block);
|
||||
|
||||
extern NSString *MRNowPlayingClientGetBundleIdentifier(id clientObj);
|
||||
extern NSString *MRNowPlayingClientGetParentAppBundleIdentifier(id clientObj);
|
||||
|
||||
extern NSString *kMRMediaRemoteNowPlayingApplicationIsPlayingDidChangeNotification;
|
||||
extern NSString *kMRMediaRemoteNowPlayingApplicationClientStateDidChange;
|
||||
extern NSString *kMRNowPlayingPlaybackQueueChangedNotification;
|
||||
extern NSString *kMRPlaybackQueueContentItemsChangedNotification;
|
||||
extern NSString *kMRMediaRemoteNowPlayingApplicationDidChangeNotification;
|
||||
|
||||
extern NSString *kMRMediaRemoteNowPlayingInfoAlbum;
|
||||
extern NSString *kMRMediaRemoteNowPlayingInfoArtist;
|
||||
extern NSString *kMRMediaRemoteNowPlayingInfoTitle;
|
||||
extern NSString *kMRMediaRemoteNowPlayingInfoArtworkData;
|
||||
|
||||
typedef enum {
|
||||
kMRPlay = 0,
|
||||
kMRPause = 1,
|
||||
kMRTogglePlayPause = 2,
|
||||
kMRNextTrack = 4,
|
||||
kMRPreviousTrack = 5,
|
||||
} MRCommand;
|
||||
|
||||
extern Boolean MRMediaRemoteSendCommand(MRCommand command, id userInfo);
|
|
@ -6,6 +6,8 @@
|
|||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
// Copied from https://github.com/pigigaldi/Pock/blob/852679a4882d0e9c5b3d8473eb9b9fbf7bef837f/Pock/Private/NSTouchBar.h
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
extern void DFRElementSetControlStripPresenceForIdentifier(_Nonnull NSTouchBarItemIdentifier, BOOL);
|
|
@ -7,3 +7,4 @@
|
|||
//
|
||||
|
||||
#import "NSTouchBar.h"
|
||||
#import "MRMediaRemote.h"
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// NowPlayingWidget.swift
|
||||
// Underbar
|
||||
//
|
||||
// Created by Shadowfacts on 7/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class NowPlayingWidget: TouchBarWidget {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
item = NSButtonTouchBarItem(identifier: .nowPlaying, title: "Test", target: nil, action: nil)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
//
|
||||
// TouchBarWidget.swift
|
||||
// Underbar
|
||||
//
|
||||
// Created by Shadowfacts on 7/13/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class TouchBarWidget: NSObject {
|
||||
|
||||
var item: NSTouchBarItem!
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
convenience init(item: NSTouchBarItem) {
|
||||
self.init()
|
||||
self.item = item
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue