├── .gitignore ├── AMIndeterminateProgressIndicatorCell.h ├── AMIndeterminateProgressIndicatorCell.m ├── AccountRemovalViewController.h ├── AccountRemovalViewController.m ├── AccountRemovalViewController.xib ├── AccountServiceViewController.h ├── AccountServiceViewController.m ├── AccountServiceViewController.xib ├── AccountsIcon.png ├── AccountsIcon@2x.png ├── AdvancedPane.h ├── AdvancedPane.m ├── AdvancedPane.xib ├── Album.h ├── Album.m ├── Albums.png ├── Albums@2x.png ├── AlbumsBrowserLevel.h ├── AlbumsBrowserLevel.m ├── AppDelegate.h ├── AppDelegate.m ├── ArtModeIcon.png ├── ArtModeIcon@2x.png ├── ArtModeModelBackground.png ├── ArtModePane.h ├── ArtModePane.m ├── Artist.h ├── Artist.m ├── Artists.png ├── Artists@2x.png ├── ArtistsBrowserLevel.h ├── ArtistsBrowserLevel.m ├── ArtworkCache.h ├── ArtworkCache.m ├── AudioPlayer.h ├── AudioPlayer.m ├── BackButton.png ├── BackButton@2x.png ├── BackgroundArtworkDisplayView.h ├── BackgroundArtworkDisplayView.m ├── BottomBarButtonCell.h ├── BottomBarButtonCell.m ├── BottomWindowTexture.png ├── BottomWindowTexture@2x.png ├── BrowserModeMatrix.h ├── BrowserModeMatrix.m ├── BrowserSearchField.h ├── BrowserSearchField.m ├── BrowserSearchFieldCell.h ├── BrowserSearchFieldCell.m ├── Common ├── Account.h ├── Account.m ├── AccountManager.h ├── AccountManager.m ├── ExfmSession+CachedSongs.h ├── ExfmSession+CachedSongs.m ├── ExfmSession.h ├── ExfmSession.m ├── SSKeychain.h ├── SSKeychain.m ├── Service.h ├── ServiceAuthorizationPresenter.h ├── ServiceDescriptor.h └── ServiceDescriptor.m ├── EXFMLogo.png ├── EXFMLogo@2x.png ├── English.lproj ├── ArtModePane.xib ├── GeneralPane.xib ├── InfoPlist.strings ├── MainMenu.xib ├── MainWindow.xib └── PreferencesWindow.xib ├── ErrorBannerButtonCell.h ├── ErrorBannerButtonCell.m ├── ErrorBannerView.h ├── ErrorBannerView.m ├── ErrorPresentationView.xib ├── EtchedTextFieldCell.h ├── EtchedTextFieldCell.m ├── ExFMPopoverHeader.png ├── ExFMPopoverHeader@2x.png ├── ExFMPopoverLogo.png ├── ExFMPopoverSelectionBackground.png ├── ExFMPopoverSelectionBackground@2x.png ├── ExFMTrendingSource.xib ├── ExFMTrendingSourceController.h ├── ExFMTrendingSourceController.m ├── ExfmAccountServiceViewController.h ├── ExfmAccountServiceViewController.m ├── Explore.png ├── Explore@2x.png ├── ExploreBrowserLevel.h ├── ExploreBrowserLevel.m ├── External └── RoundaboutKit │ ├── LICENSE │ ├── README.md │ ├── RoundaboutKit.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── RoundaboutKit.xccheckout │ │ └── xcuserdata │ │ │ └── km.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── km.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── RoundaboutKit.xcscheme │ │ ├── RoundaboutKitMac.xcscheme │ │ ├── RoundaboutKitMacTests.xcscheme │ │ └── xcschememanagement.plist │ ├── RoundaboutKit │ ├── RKActivityManager.h │ ├── RKActivityManager.m │ ├── RKConnectivityManager.h │ ├── RKConnectivityManager.m │ ├── RKDefaults.h │ ├── RKDefaults.m │ ├── RKFileSystemCacheManager.h │ ├── RKFileSystemCacheManager.m │ ├── RKImageLoader.h │ ├── RKImageLoader.m │ ├── RKPossibility.h │ ├── RKPossibility.m │ ├── RKPrelude.h │ ├── RKPrelude.m │ ├── RKPromise.h │ ├── RKPromise.m │ ├── RKQueueManager.h │ ├── RKQueueManager.m │ ├── RKRequestFactory.h │ ├── RKRequestFactory.m │ ├── RKURLRequestPromise.h │ ├── RKURLRequestPromise.m │ ├── RoundaboutKit-Prefix.pch │ └── RoundaboutKit.h │ ├── RoundaboutKitMac │ ├── RoundaboutKitMac-Info.plist │ ├── RoundaboutKitMac-Prefix.pch │ └── en.lproj │ │ └── InfoPlist.strings │ └── Tests │ ├── RKActivityManagerTests.h │ ├── RKActivityManagerTests.m │ ├── RKDefaultsTests.h │ ├── RKDefaultsTests.m │ ├── RKFileSystemCacheManagerTests.h │ ├── RKFileSystemCacheManagerTests.m │ ├── RKMockPromise.h │ ├── RKMockPromise.m │ ├── RKMockURLProtocol.h │ ├── RKMockURLProtocol.m │ ├── RKMockURLRequestPromiseCacheManager.h │ ├── RKMockURLRequestPromiseCacheManager.m │ ├── RKPossibilityTests.h │ ├── RKPossibilityTests.m │ ├── RKPostProcessorTestImage.png │ ├── RKPreludeTests.h │ ├── RKPreludeTests.m │ ├── RKPromiseTests.h │ ├── RKPromiseTests.m │ ├── RKURLRequestPromiseTests.h │ ├── RKURLRequestPromiseTests.m │ ├── RunLoopHelper.h │ ├── RunLoopHelper.m │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ └── en.lproj │ └── InfoPlist.strings ├── FileEnumerator.h ├── FlatPreset.plist ├── FriendActivityBrowserLevel.h ├── FriendActivityBrowserLevel.m ├── GeneralIcon.png ├── GeneralIcon@2x.png ├── GeneralPane.h ├── GeneralPane.m ├── Genres.plist ├── HeaderLabelView.h ├── HeaderLabelView.m ├── HotKeyDispatcher.h ├── HotKeyDispatcher.m ├── HotKeysIcon.png ├── HotKeysIcon@2x.png ├── HotKeysPane.h ├── HotKeysPane.m ├── HotKeysPane.xib ├── LICENSE ├── LastFMDefines.h ├── LastFMDefines.m ├── LastFMLogo.png ├── LastFMLogo@2x.png ├── LastFMSession.h ├── LastFMSession.m ├── LastfmAccountServiceViewController.h ├── LastfmAccountServiceViewController.m ├── LastfmAccountServiceViewController.xib ├── Library.h ├── Library.m ├── LinkArrow.png ├── LinkArrow@2x.png ├── LoveItemButton.png ├── LoveItemButton@2x.png ├── LoveItemButton_Busy.png ├── LoveItemButton_Busy@2x.png ├── LoveItemButton_Full.png ├── LoveItemButton_Full@2x.png ├── LoveItemButton_Full_Presed@2x.png ├── LoveItemButton_Full_Pressed.png ├── LoveItemButton_Full_Pressed@2x.png ├── LoveItemButton_Presed@2x.png ├── LoveItemButton_Pressed.png ├── LoveItemButton_Pressed@2x.png ├── Lyrics.html ├── Lyrics.xib ├── LyricsCache.h ├── LyricsCache.m ├── LyricsViewController.h ├── LyricsViewController.m ├── MainWindow.h ├── MainWindow.m ├── MainWindowSplitView.h ├── MainWindowSplitView.m ├── MavenProBold.otf ├── MavenProMedium.otf ├── MavenProRegular.otf ├── MenuGenerator.h ├── MenuGenerator.m ├── MenuNotificationView.h ├── MenuNotificationView.m ├── NS(Attributed)String+Geometrics.h ├── NS(Attributed)String+Geometrics.m ├── NSObject+AssociatedValues.h ├── NSObject+AssociatedValues.m ├── NSView+Convenience.h ├── NSView+Convenience.m ├── NextTrack_Button.png ├── NextTrack_Button@2x.png ├── NextTrack_ButtonPressed.png ├── NextTrack_ButtonPressed@2x.png ├── NoArtwork.png ├── NotificationBarShadow.png ├── NotificationBarShadow@2x.png ├── NotificationIcon_Paused.png ├── NotificationIcon_Paused@2x.png ├── NotificationIcon_Playing.png ├── NotificationIcon_Playing@2x.png ├── NowPlayingBackgroundTexture.png ├── NowPlayingLowerLayer.png ├── NowPlayingLowerLayer@2x.png ├── NowPlayingPane.h ├── NowPlayingPane.m ├── NowPlayingPane.xib ├── NowPlayingShadow.png ├── NowPlayingShadow@2x.png ├── NowPlayingTextFieldCell.h ├── NowPlayingTextFieldCell.m ├── NowPlayingToggle_Off.png ├── NowPlayingToggle_Off_Pressed.png ├── NowPlayingToggle_On.png ├── NowPlayingToggle_On_Pressed.png ├── NowPlayingUpperLayer.png ├── NowPlayingUpperLayer@2x.png ├── Pause_Button.png ├── Pause_Button@2x.png ├── Pause_ButtonPressed.png ├── Pause_ButtonPressed@2x.png ├── PlayItemButton.png ├── PlayItemButton@2x.png ├── PlayItemButton_Pressed.png ├── PlayItemButton_Pressed@2x.png ├── PlayKeys ├── PlayKeys.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── PlayKeys.xccheckout │ │ └── xcuserdata │ │ │ └── km.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── km.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints.xcbkptlist │ │ └── xcschemes │ │ ├── PlayKeys.xcscheme │ │ └── xcschememanagement.plist └── PlayKeys │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── BackgroundArtworkDisplayView.h │ ├── BackgroundArtworkDisplayView.m │ ├── HeadsUpWindowController.h │ ├── HeadsUpWindowController.m │ ├── HeadsUpWindowController.xib │ ├── Icon.icns │ ├── MavenProBold.otf │ ├── MavenProMedium.otf │ ├── MavenProRegular.otf │ ├── MediaKeyEventTap.h │ ├── MediaKeyEventTap.m │ ├── NSString+SymlinksAndAliases.h │ ├── NSString+SymlinksAndAliases.m │ ├── PFMoveApplication.h │ ├── PFMoveApplication.m │ ├── Pinna.h │ ├── Pinna.m │ ├── PlayKeys-Info.plist │ ├── PlayKeys-Prefix.pch │ ├── PlayMode.png │ ├── PlayMode@2x.png │ ├── ShuffleMode.png │ ├── ShuffleMode@2x.png │ ├── en.lproj │ ├── InfoPlist.strings │ └── MainMenu.xib │ └── main.m ├── PlayKeysBridge.h ├── PlayKeysBridge.m ├── Play_Button.png ├── Play_Button@2x.png ├── Play_ButtonPressed.png ├── Play_ButtonPressed@2x.png ├── PlaybackErrorIcon.png ├── PlaybackErrorIcon@2x.png ├── Player-Info.plist ├── Player.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── Pinna.xccheckout │ │ └── Player.xccheckout │ └── xcuserdata │ │ ├── Jon.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings │ │ └── km.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ ├── Jon.xcuserdatad │ └── xcschemes │ │ ├── Pinna.xcscheme │ │ └── xcschememanagement.plist │ └── km.xcuserdatad │ ├── xcdebugger │ ├── Breakpoints.xcbkptlist │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Pinna.xcscheme │ └── xcschememanagement.plist ├── PlayerApplication.h ├── PlayerApplication.m ├── Player_Prefix.pch ├── Playlist.h ├── Playlist.m ├── Playlist_Friends.png ├── Playlist_Friends@2x.png ├── Playlist_Friends_Selected.png ├── Playlist_Friends_Selected@2x.png ├── Playlist_ITunes.png ├── Playlist_ITunes@2x.png ├── Playlist_ITunes_Selected.png ├── Playlist_ITunes_Selected@2x.png ├── Playlist_Regular.png ├── Playlist_Regular@2x.png ├── Playlist_Regular_Selected.png ├── Playlist_Regular_Selected@2x.png ├── Playlist_Remote.png ├── Playlist_Remote@2x.png ├── Playlist_Remote_Selected.png ├── Playlist_Remote_Selected@2x.png ├── Playlists.png ├── Playlists@2x.png ├── PlaylistsBrowserLevel.h ├── PlaylistsBrowserLevel.m ├── PreferencesButtonCell.h ├── PreferencesButtonCell.m ├── PreferencesPane.h ├── PreferencesPane.m ├── PreferencesWindow.h ├── PreferencesWindow.m ├── PreviousTrack_Button.png ├── PreviousTrack_Button@2x.png ├── PreviousTrack_ButtonPressed.png ├── PreviousTrack_ButtonPressed@2x.png ├── QueueTableScrollView.h ├── QueueTableScrollView.m ├── QueueTableView.h ├── QueueTableView.m ├── README.md ├── RKBrowserIconTextFieldCell.h ├── RKBrowserIconTextFieldCell.m ├── RKBrowserLevel.h ├── RKBrowserLevel.m ├── RKBrowserLevelController.h ├── RKBrowserLevelController.m ├── RKBrowserLevelController.xib ├── RKBrowserLevelInternal.h ├── RKBrowserScrollView.h ├── RKBrowserScrollView.m ├── RKBrowserTableView.h ├── RKBrowserTableView.m ├── RKBrowserView.h ├── RKBrowserView.m ├── RKBrowserViewPrivate.h ├── RSVerticallyCenteredTextFieldCell.h ├── RSVerticallyCenteredTextFieldCell.m ├── RoundaboutKitMac ├── NSBezierPath+MCAdditions.h ├── NSBezierPath+MCAdditions.m ├── RKAnimator.h ├── RKAnimator.m ├── RKBarButton.h ├── RKBarButton.m ├── RKBarButtonCell.h ├── RKBarButtonCell.m ├── RKBorderlessWindow.h ├── RKBorderlessWindow.m ├── RKChromeView.h ├── RKChromeView.m ├── RKKeyDispatcher.h ├── RKKeyDispatcher.m ├── RKMacPrelude.h ├── RKNavigationBar.h ├── RKNavigationBar.m ├── RKNavigationController.h ├── RKNavigationController.m ├── RKNavigationItem.h ├── RKNavigationItem.m ├── RKSandboxTools.h ├── RKSandboxTools.m ├── RKSideSheetView.h ├── RKSideSheetView.m ├── RKTitleBarButtonsView.h ├── RKTitleBarButtonsView.m ├── RKView.h ├── RKView.m ├── RKViewController.h ├── RKViewController.m ├── RKViewController_Private.h └── RoundaboutKitMac.h ├── RoundaboutKit_Prefix.pch ├── SRCommon.h ├── SRCommon.m ├── SRKeyCodeTransformer.h ├── SRKeyCodeTransformer.m ├── SRRecorderCell.h ├── SRRecorderCell.m ├── SRRecorderControl.h ├── SRRecorderControl.m ├── SRValidator.h ├── SRValidator.m ├── SafeButton.h ├── SafeButton.m ├── ScriptingController.h ├── ScriptingController.m ├── ScrubbingBarBackground_Fill.png ├── ScrubbingBarBackground_Fill@2x.png ├── ScrubbingBarBackground_LeftCap.png ├── ScrubbingBarBackground_LeftCap@2x.png ├── ScrubbingBarBackground_RightCap.png ├── ScrubbingBarBackground_RightCap@2x.png ├── ScrubbingBarDial.png ├── ScrubbingBarDial@2x.png ├── ScrubbingBarKnob_Fill.png ├── ScrubbingBarKnob_Fill@2x.png ├── ScrubbingBarKnob_LeftCap.png ├── ScrubbingBarKnob_LeftCap@2x.png ├── ScrubbingBarKnob_RightCap.png ├── ScrubbingBarKnob_RightCap@2x.png ├── ScrubbingBarStrike.png ├── ScrubbingBarStrike@2x.png ├── ScrubbingBarView.h ├── ScrubbingBarView.m ├── SearchBarButtonCell.h ├── SearchBarButtonCell.m ├── SearchBarDivider.png ├── ShadowedTextFieldCell.h ├── ShadowedTextFieldCell.m ├── Share_Button.png ├── Share_Button@2x.png ├── Share_ButtonPressed.png ├── Share_ButtonPressed@2x.png ├── ShuffleOff_Button.png ├── ShuffleOff_Button@2x.png ├── ShuffleOff_ButtonPressed.png ├── ShuffleOff_ButtonPressed@2x.png ├── ShuffleOn_Button.png ├── ShuffleOn_Button@2x.png ├── ShuffleOn_ButtonPressed.png ├── ShuffleOn_ButtonPressed@2x.png ├── SimpleNumberTransformer.h ├── SimpleNumberTransformer.m ├── SocialIcon.png ├── SocialPane.h ├── SocialPane.m ├── SocialPane.xib ├── Song.h ├── Song.m ├── SongQueryPromise.h ├── SongQueryPromise.m ├── Songs.png ├── Songs@2x.png ├── SongsBrowserLevel.h ├── SongsBrowserLevel.m ├── TimeValueTransformer.h ├── TimeValueTransformer.m ├── TrendingScroller.h ├── TrendingScroller.m ├── UppercaseStringTransformer.h ├── UppercaseStringTransformer.m ├── UserDefaults.plist ├── WindowRoundedResizeKnob.png ├── WindowRoundedResizeKnob@2x.png ├── WindowTexture.png ├── WindowTransition.h ├── WindowTransition.m ├── main.m └── prep.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | .DS_Store 3 | /External/.DS_Store 4 | /Pinna.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /AMIndeterminateProgressIndicatorCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // AMIndeterminateProgressIndicatorCell.h 3 | // IPICellTest 4 | // 5 | // Created by Andreas on 23.01.07. 6 | // Copyright 2007 Andreas Mayer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface AMIndeterminateProgressIndicatorCell : NSCell { 13 | double doubleValue; 14 | NSTimeInterval animationDelay; 15 | BOOL displayedWhenStopped; 16 | BOOL spinning; 17 | NSColor *color; 18 | CGFloat redComponent; 19 | CGFloat greenComponent; 20 | CGFloat blueComponent; 21 | } 22 | 23 | - (NSColor *)color; 24 | - (void)setColor:(NSColor *)value; 25 | 26 | - (double)doubleValue; 27 | - (void)setDoubleValue:(double)value; 28 | 29 | - (NSTimeInterval)animationDelay; 30 | - (void)setAnimationDelay:(NSTimeInterval)value; 31 | 32 | - (BOOL)isDisplayedWhenStopped; 33 | - (void)setDisplayedWhenStopped:(BOOL)value; 34 | 35 | - (BOOL)isSpinning; 36 | - (void)setSpinning:(BOOL)value; 37 | 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /AccountRemovalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AccountRemovalViewController.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "RKViewController.h" 10 | 11 | @class RKSideSheetView, Account; 12 | 13 | @interface AccountRemovalViewController : RKViewController 14 | 15 | - (id)initWithAccount:(Account *)account; 16 | 17 | #pragma mark - Properties 18 | 19 | @property (nonatomic) Account *account; 20 | 21 | @property (nonatomic, weak) RKSideSheetView *containingSheet; 22 | 23 | #pragma mark - Actions 24 | 25 | - (IBAction)cancel:(id)sender; 26 | 27 | - (IBAction)remove:(id)sender; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /AccountRemovalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AccountRemovalViewController.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "AccountRemovalViewController.h" 10 | #import "RoundaboutKitMac.h" 11 | #import "RKSideSheetView.h" 12 | 13 | #import "ServiceDescriptor.h" 14 | #import "AccountManager.h" 15 | 16 | @interface AccountRemovalViewController () 17 | 18 | @end 19 | 20 | @implementation AccountRemovalViewController 21 | 22 | - (id)initWithAccount:(Account *)account 23 | { 24 | NSParameterAssert(account); 25 | 26 | if((self = [super init])) { 27 | self.account = account; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | - (void)viewDidLoad 34 | { 35 | [super viewDidLoad]; 36 | 37 | self.navigationItem.title = self.account.descriptor.name; 38 | } 39 | 40 | #pragma mark - Actions 41 | 42 | - (IBAction)cancel:(id)sender 43 | { 44 | [self.containingSheet dismiss:YES completionHandler:nil]; 45 | } 46 | 47 | - (IBAction)remove:(id)sender 48 | { 49 | [[[AccountManager sharedAccountManager] deleteAccount:self.account] then:^(id service) { 50 | [self.containingSheet dismiss:YES completionHandler:nil]; 51 | } otherwise:^(NSError *error) { 52 | [NSApp presentError:error]; 53 | 54 | [self.containingSheet dismiss:YES completionHandler:nil]; 55 | }]; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /AccountsIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/AccountsIcon.png -------------------------------------------------------------------------------- /AccountsIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/AccountsIcon@2x.png -------------------------------------------------------------------------------- /AdvancedPane.h: -------------------------------------------------------------------------------- 1 | // 2 | // LibraryPane.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/7/13. 6 | // 7 | // 8 | 9 | #import "PreferencesPane.h" 10 | 11 | @class Library; 12 | 13 | ///The AdvancedPane class is responsible for representing Advanced preferences in Pinna. 14 | @interface AdvancedPane : PreferencesPane 15 | { 16 | Library *mLibrary; 17 | } 18 | 19 | #pragma mark Actions 20 | 21 | ///Causes the receiver to tell the shared Library to use its default location. 22 | - (IBAction)useDefaultLibraryLocation:(id)sender; 23 | 24 | ///Causes the receiver to run an open panel for the user to select a new 25 | ///library location, and then subsequently telling the shread Library to use it. 26 | - (IBAction)changeLibraryLocation:(id)sender; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Album.h: -------------------------------------------------------------------------------- 1 | // 2 | // Album.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 11/17/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class Artist; 12 | 13 | @interface Album : NSObject 14 | { 15 | NSString *mName; 16 | Artist *mArtist; 17 | NSMutableArray *mSongs; 18 | BOOL mIsCompilation; 19 | } 20 | 21 | ///Initialize an album with a specified name, inserting it into a specified artist. 22 | - (id)initWithName:(NSString *)name insertIntoArtist:(Artist *)artist isCompilation:(BOOL)isCompilation; 23 | 24 | #pragma mark - Properties 25 | 26 | ///The name of the album. 27 | @property (readonly) NSString *name; 28 | 29 | ///The artist the album is by. 30 | @property (readonly) Artist *artist; 31 | 32 | ///Whether or not the album is a compilation. 33 | @property (readonly) BOOL isCompilation; 34 | 35 | #pragma mark - 36 | 37 | ///The songs of the album. Friend-objects may mutate this value through `-mutableArrayValueForKeyPath:`. 38 | @property (readonly) NSArray *songs; 39 | 40 | #pragma mark - Identity 41 | 42 | ///Returns a predicate suitable for a search UI displaying an array of albums. 43 | + (NSPredicate *)searchPredicateForQueryString:(NSString *)queryString; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Albums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Albums.png -------------------------------------------------------------------------------- /Albums@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Albums@2x.png -------------------------------------------------------------------------------- /AlbumsBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // AlbumsBrowserLevel.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 2/12/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | @class Library, Artist; 12 | @interface AlbumsBrowserLevel : RKBrowserLevel 13 | { 14 | Library *mLibrary; 15 | 16 | Artist *mParentArtist; 17 | } 18 | 19 | #pragma mark Properties 20 | 21 | ///The parent artist of the albums to filter by, if any. 22 | @property (nonatomic) Artist *parentArtist; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ArtModeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ArtModeIcon.png -------------------------------------------------------------------------------- /ArtModeIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ArtModeIcon@2x.png -------------------------------------------------------------------------------- /ArtModeModelBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ArtModeModelBackground.png -------------------------------------------------------------------------------- /ArtModePane.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArtModePane.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "PreferencesPane.h" 10 | 11 | @class BackgroundArtworkDisplayView; 12 | 13 | @interface ArtModePane : PreferencesPane 14 | { 15 | ///The view used to display a replica of the artwork mode. 16 | IBOutlet BackgroundArtworkDisplayView *oArtModeModelView; 17 | } 18 | 19 | #pragma mark Actions 20 | 21 | - (IBAction)restoreDefaultArtModeSize:(id)sender; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Artist.h: -------------------------------------------------------------------------------- 1 | // 2 | // Artist.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 11/17/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class Album; 12 | 13 | @interface Artist : NSObject 14 | { 15 | NSString *mName; 16 | NSMutableArray *mAlbums; 17 | BOOL mIsCompilationContainer; 18 | } 19 | 20 | ///Initialize a new artist with a specified name. 21 | - (id)initWithName:(NSString *)name isCompilationContainer:(BOOL)isCompilationContainer; 22 | 23 | #pragma mark - Properties 24 | 25 | ///The name of the artist. 26 | /// 27 | ///The value of this property is not fit for display if `isCompilationContainer` is YES. 28 | @property (readonly) NSString *name; 29 | 30 | ///The interface-ready name of the artist. 31 | /// 32 | ///This should be preferred over `name`. 33 | @property (readonly) NSString *displayName; 34 | 35 | ///The albums of the artist. Friend-objects may mutate this value through `-mutableArrayValueForKeyPath:`. 36 | @property (readonly) NSArray *albums; 37 | 38 | ///The songs of the artist. Readonly. 39 | @property (readonly) NSArray *songs; 40 | 41 | ///Whether or not the artist is a compilation container. 42 | @property (readonly) BOOL isCompilationContainer; 43 | 44 | #pragma mark - 45 | 46 | ///Returns the first known album with a specified name. 47 | - (Album *)albumWithName:(NSString *)name; 48 | 49 | #pragma mark - Identity 50 | 51 | ///Returns a predicate suitable for a search UI displaying an array of artists. 52 | + (NSPredicate *)searchPredicateForQueryString:(NSString *)queryString; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Artists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Artists.png -------------------------------------------------------------------------------- /Artists@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Artists@2x.png -------------------------------------------------------------------------------- /ArtistsBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArtistsBrowserLevel.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 2/12/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | @class Library; 12 | @interface ArtistsBrowserLevel : RKBrowserLevel 13 | { 14 | Library *mLibrary; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ArtworkCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArtworkCache.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 1/24/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class Album, Song; 12 | 13 | ///This class is responsible for managing the artwork tiles used by Player. 14 | @interface ArtworkCache : NSObject 15 | { 16 | NSCache *mImageCache; 17 | 18 | NSOperationQueue *mCachingQueue; 19 | } 20 | 21 | ///Returns the shared artwork cache, creating it if it doesn't exist. 22 | + (ArtworkCache *)sharedArtworkCache; 23 | 24 | ///Erase the artwork cache. 25 | - (void)deleteCachedArtwork; 26 | 27 | #pragma mark - Accessing Artwork 28 | 29 | ///Returns YES if the receiver has artwork for a specified album in its cache; NO otherwise. 30 | - (BOOL)hasArtworkForAlbum:(Album *)album; 31 | 32 | ///Asynchronously cache the artwork for an album. 33 | - (void)cacheArtworkForAlbums:(NSArray *)albums completionHandler:(void(^)())completionHandler; 34 | 35 | ///Returns the cached artwork for a specified album. 36 | - (NSImage *)artworkForAlbum:(Album *)album; 37 | 38 | ///Returns the cached artwork for a specified album 39 | - (NSImage *)artworkForSong:(Song *)album; 40 | 41 | #pragma mark - Controlling Access 42 | 43 | ///Inform the receiver that you will be accessing it extensively. 44 | - (void)beginCacheAccess; 45 | 46 | ///Inform the receiver that you have finished accessing it extensively. 47 | - (void)endCacheAccess; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /BackButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/BackButton.png -------------------------------------------------------------------------------- /BackButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/BackButton@2x.png -------------------------------------------------------------------------------- /BackgroundArtworkDisplayView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BackgroundArtworkDisplayView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/27/11. 6 | // Copyright (c) 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BackgroundArtworkDisplayView : NSView 12 | { 13 | BOOL mIsMouseInView; 14 | 15 | /** Properties **/ 16 | 17 | ///The storage for `mImage` 18 | NSImage *mImage; 19 | } 20 | 21 | #pragma mark Properties 22 | 23 | @property (nonatomic, copy) NSImage *image; 24 | 25 | @property (nonatomic, readonly) BOOL isMouseInView; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /BottomBarButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BottomBarButtonCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 8/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BottomBarButtonCell : NSButtonCell 12 | { 13 | BOOL mIsLeftMostButton; 14 | BOOL mIsRightMostButton; 15 | } 16 | 17 | #pragma mark - Properties 18 | 19 | @property (nonatomic) BOOL isLeftMostButton; 20 | @property (nonatomic) BOOL isRightMostButton; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /BottomWindowTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/BottomWindowTexture.png -------------------------------------------------------------------------------- /BottomWindowTexture@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/BottomWindowTexture@2x.png -------------------------------------------------------------------------------- /BrowserModeMatrix.h: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserModeMatrix.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/18/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | ///The BrowserModeMatrix subclass registers itself as a drop target for Songs, 12 | ///and will switch to a specified mode when a user holds a song over the matrix 13 | ///for one-half second. 14 | @interface BrowserModeMatrix : NSMatrix 15 | 16 | ///The mode to switch to when a user holds a song over the matrix. 17 | @property (nonatomic) NSUInteger dropTargetMode; 18 | 19 | ///Whether or not the matrix should switch back after the drag operation is completed. 20 | @property (nonatomic) BOOL shouldRevertToPreviousMode; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /BrowserModeMatrix.m: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserModeMatrix.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/18/13. 6 | // 7 | // 8 | 9 | #import "BrowserModeMatrix.h" 10 | 11 | #import "Song.h" 12 | 13 | @implementation BrowserModeMatrix { 14 | NSTimer *_delay; 15 | NSUInteger _selectedModeBeforeDrag; 16 | } 17 | 18 | - (void)awakeFromNib 19 | { 20 | self.dropTargetMode = 0; 21 | self.shouldRevertToPreviousMode = YES; 22 | 23 | [self registerForDraggedTypes:@[kSongUTI]]; 24 | } 25 | 26 | #pragma mark - Drag Popover 27 | 28 | - (void)showPopoverAfterDelay:(NSTimer *)timer 29 | { 30 | if([self selectedColumn] != self.dropTargetMode) 31 | { 32 | _selectedModeBeforeDrag = [self selectedColumn]; 33 | 34 | [self selectCellAtRow:0 column:self.dropTargetMode]; 35 | [self sendAction]; 36 | } 37 | 38 | _delay = nil; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender 44 | { 45 | [_delay invalidate]; 46 | _delay = [NSTimer scheduledTimerWithTimeInterval:0.5 47 | target:self 48 | selector:@selector(showPopoverAfterDelay:) 49 | userInfo:nil 50 | repeats:NO]; 51 | 52 | return NSDragOperationCopy; 53 | } 54 | 55 | - (void)draggingEnded:(id < NSDraggingInfo >)sender 56 | { 57 | if(self.shouldRevertToPreviousMode) 58 | { 59 | [self selectCellAtRow:0 column:_selectedModeBeforeDrag]; 60 | [self sendAction]; 61 | } 62 | 63 | [_delay invalidate]; 64 | _delay = nil; 65 | } 66 | 67 | - (void)draggingExited:(id < NSDraggingInfo >)sender 68 | { 69 | [_delay invalidate]; 70 | _delay = nil; 71 | } 72 | 73 | - (BOOL)performDragOperation:(id < NSDraggingInfo >)sender 74 | { 75 | return NO; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /BrowserSearchField.h: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserSearchField.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/13/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BrowserSearchField : NSSearchField 12 | { 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /BrowserSearchField.m: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserSearchField.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/13/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "BrowserSearchField.h" 10 | 11 | @implementation BrowserSearchField 12 | 13 | - (void)awakeFromNib 14 | { 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /BrowserSearchFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserSearchFieldCell.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/13/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BrowserSearchFieldCell : NSSearchFieldCell 12 | { 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Common/ServiceAuthorizationPresenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // ServiceAuthorizationPresenter.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/21/13. 6 | // 7 | // 8 | 9 | #ifndef ServiceAuthorizationPresenter_h 10 | #define ServiceAuthorizationPresenter_h 1 11 | 12 | #import 13 | 14 | @class ServiceDescriptor; 15 | 16 | ///A block called when a service authorization view controller has completed. 17 | /// 18 | /// \param succeeded Whether or not the authorization was successful. 19 | typedef void(^ServiceAuthorizationPresenterCompletionHandler)(BOOL succeeded); 20 | 21 | ///The ServiceAuthorizationPresenter protocol describes the methods required 22 | ///for a controller to be used as an account service presenter. 23 | /// 24 | ///A presenter is an object which provides an interface to either create 25 | ///a new account on a service, or to log into an existing account. 26 | /// 27 | ///It is expected that an account presenter will take care of creating, 28 | ///or updating any relevant accounts. The account editing interface 29 | ///expects to simply pass control to the presenter. 30 | /// 31 | ///Under OS X, it is expected that presenters will be RKViewControllers; 32 | ///under iOS, it is expected that presenters will be UIViewControllers. 33 | @protocol ServiceAuthorizationPresenter 34 | 35 | //Shut up the compiler. 36 | + (instancetype)alloc; 37 | 38 | 39 | ///Initialize the receiver with a given service descriptor. 40 | /// 41 | /// \param serviceDescriptor The service descriptor. Required. 42 | /// \param completionHandler The block to invoke when the service is signed up/into. Optional. 43 | /// 44 | /// \result A fully initialized account service view controller. 45 | /// 46 | ///This is the primitive initializer. 47 | - (id)initWithServiceDescriptor:(ServiceDescriptor *)serviceDescriptor completionHandler:(ServiceAuthorizationPresenterCompletionHandler)completionHandler; 48 | 49 | @end 50 | 51 | #endif /* ServiceAuthorizationPresenter_h */ 52 | -------------------------------------------------------------------------------- /EXFMLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/EXFMLogo.png -------------------------------------------------------------------------------- /EXFMLogo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/EXFMLogo@2x.png -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | CFBundleName = "Pinna"; 4 | NSHumanReadableCopyright = "© 2007-2012 The Roundabout Co., LLC. All Rights Reserved."; 5 | -------------------------------------------------------------------------------- /ErrorBannerButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ErrorBannerButtonCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 10/14/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface ErrorBannerButtonCell : NSButtonCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ErrorBannerButtonCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ErrorBannerButtonCell.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 10/14/12. 6 | // 7 | // 8 | 9 | #import "ErrorBannerButtonCell.h" 10 | 11 | @implementation ErrorBannerButtonCell 12 | 13 | - (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView 14 | { 15 | NSMutableAttributedString *ourTitle = [title mutableCopy]; 16 | [ourTitle addAttribute:NSForegroundColorAttributeName value:[NSColor whiteColor] range:NSMakeRange(0, ourTitle.length)]; 17 | [ourTitle addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, ourTitle.length)]; 18 | return [super drawTitle:ourTitle withFrame:frame inView:controlView]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /ErrorBannerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ErrorPresentationView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 10/12/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class ErrorPresentationViewController; 12 | 13 | ///The view responsible for presenting error banners in the main window. 14 | @interface ErrorBannerView : NSView 15 | { 16 | ErrorPresentationViewController *mErrorPresentationViewController; 17 | NSTimer *mCloseTimer; 18 | 19 | /** Properties **/ 20 | 21 | NSString *mTitle; 22 | NSString *mButtonTitle; 23 | dispatch_block_t mButtonAction; 24 | } 25 | 26 | #pragma mark - Properties 27 | 28 | ///The title of the error presentation view. 29 | @property (copy) NSString *title; 30 | 31 | ///The title of the informative button showne below the title. 32 | @property (copy) NSString *buttonTitle; 33 | 34 | ///The block to invoke upon the informative button being clicked. 35 | @property (copy) dispatch_block_t buttonAction; 36 | 37 | #pragma mark - 38 | 39 | ///Whether or not the error presentation view is visible. 40 | @property (nonatomic, readonly) BOOL isVisible; 41 | 42 | #pragma mark - Presentation 43 | 44 | ///Shows the receiver in a specified parent view. 45 | /// 46 | ///Invoking this method will add the receiver to the specified view, 47 | ///slide the error down from the top, and then fade out the error 48 | ///after a predetermined number of seconds. 49 | - (void)showInView:(NSView *)parentView; 50 | 51 | ///Fades out the receiver and removes it from its parent view. 52 | - (void)close; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /EtchedTextFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // EtchedTextFieldCell.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 6/11/09. 6 | // Copyright 2009 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EtchedTextFieldCell : NSTextFieldCell 12 | { 13 | } 14 | @end 15 | -------------------------------------------------------------------------------- /EtchedTextFieldCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // EtchedTextFieldCell.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 6/11/09. 6 | // Copyright 2009 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "EtchedTextFieldCell.h" 10 | 11 | @implementation EtchedTextFieldCell 12 | 13 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 14 | { 15 | NSShadow *shadow = [NSShadow new]; 16 | [shadow setShadowColor:[NSColor colorWithDeviceWhite:1.0 alpha:0.45]]; 17 | [shadow setShadowBlurRadius:0.0]; 18 | [shadow setShadowOffset:NSMakeSize(0.0, -1.0)]; 19 | 20 | [NSGraphicsContext saveGraphicsState]; 21 | [shadow set]; 22 | 23 | [super drawWithFrame:cellFrame inView:controlView]; 24 | 25 | [NSGraphicsContext restoreGraphicsState]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ExFMPopoverHeader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ExFMPopoverHeader.png -------------------------------------------------------------------------------- /ExFMPopoverHeader@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ExFMPopoverHeader@2x.png -------------------------------------------------------------------------------- /ExFMPopoverLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ExFMPopoverLogo.png -------------------------------------------------------------------------------- /ExFMPopoverSelectionBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ExFMPopoverSelectionBackground.png -------------------------------------------------------------------------------- /ExFMPopoverSelectionBackground@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ExFMPopoverSelectionBackground@2x.png -------------------------------------------------------------------------------- /ExFMTrendingSourceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExFMTrendingSourceController.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/17/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ExFMTrendingSourceController : NSWindowController 12 | { 13 | IBOutlet NSArrayController *oContentController; 14 | } 15 | 16 | #pragma mark Showing/Hiding 17 | 18 | - (void)showBelowView:(NSView *)view; 19 | 20 | - (void)hide; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ExfmAccountServiceViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExfmServiceViewController.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "AccountServiceViewController.h" 10 | 11 | ///The PnafmAccountServiceViewController class encapsulates signing into/up with Exfm. 12 | @interface ExfmAccountServiceViewController : AccountServiceViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ExfmAccountServiceViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExfmServiceViewController.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "ExfmAccountServiceViewController.h" 10 | 11 | #import "ExfmSession.h" 12 | 13 | @interface ExfmAccountServiceViewController () 14 | 15 | @end 16 | 17 | @implementation ExfmAccountServiceViewController 18 | 19 | - (RKPromise *)loginPromiseForUsername:(NSString *)username password:(NSString *)password 20 | { 21 | RKPromise *promise = [RKPromise new]; 22 | [[RKQueueManager commonQueue] addOperationWithBlock:^{ 23 | ExfmSession *session = [ExfmSession defaultSession]; 24 | 25 | NSError *error = nil; 26 | id userIsValid = [[session verifyUsername:username password:password] await:&error]; 27 | if(userIsValid) { 28 | session.username = username; 29 | session.password = password; 30 | 31 | [promise accept:userIsValid]; 32 | } else { 33 | [promise reject:error]; 34 | } 35 | }]; 36 | 37 | return promise; 38 | } 39 | 40 | - (RKPromise *)signUpPromiseForEmail:(NSString *)email username:(NSString *)username password:(NSString *)password 41 | { 42 | RKPromise *promise = [RKPromise new]; 43 | [[RKQueueManager commonQueue] addOperationWithBlock:^{ 44 | ExfmSession *session = [ExfmSession defaultSession]; 45 | 46 | NSError *error = nil; 47 | id userIsValid = [[session createUserWithName:username password:password email:email] await:&error]; 48 | if(userIsValid) { 49 | session.username = username; 50 | session.password = password; 51 | 52 | [promise accept:userIsValid]; 53 | } else { 54 | [promise reject:error]; 55 | } 56 | }]; 57 | 58 | return promise; 59 | } 60 | 61 | #pragma mark - 62 | 63 | - (IBAction)forgotPassword:(id)sender 64 | { 65 | 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Explore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Explore.png -------------------------------------------------------------------------------- /Explore@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Explore@2x.png -------------------------------------------------------------------------------- /ExploreBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // DiscoveryBrowserLevel.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/19/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RKBrowserLevel.h" 11 | 12 | @class Library; 13 | 14 | @interface ExploreBrowserLevel : RKBrowserLevel 15 | { 16 | Library *mLibrary; 17 | 18 | NSArray *mCachedTrending; 19 | NSTimer *mTrendingUpdateTimer; 20 | 21 | NSArray *mResults; 22 | 23 | NSUInteger mResultsOffset; 24 | 25 | BOOL mIsLoadingMoreResults; 26 | 27 | NSCache *mArtworkCache; 28 | NSMutableSet *mArtworkBeingDownloaded; 29 | NSOperationQueue *mArtworkDownloadQueue; 30 | } 31 | 32 | ///Whether or not the browser is searching. 33 | @property (nonatomic, readonly) BOOL isSearching; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /External/RoundaboutKit/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Roundabout Software, LLC. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Roundabout Co. nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /External/RoundaboutKit/README.md: -------------------------------------------------------------------------------- 1 | RoundaboutKit 2 | ============= 3 | 4 | RoundaboutKit is a collection of abstractions, utility functions, and a full networking stack to assist in the creation of modern applications. 5 | 6 | Tests 7 | ===== 8 | 9 | The tests for RoundaboutKit live in an Xcode project in the repo called `RoundaboutKitTests`. To run, launch Xcode and press `command+u`. 10 | 11 | Requirements 12 | ============ 13 | 14 | RoundaboutKit requires the `SystemConfiguration` framework be added to the host project in order to link. 15 | 16 | License 17 | ======= 18 | 19 | Copyright (c) 2012-2013, Roundabout Software, LLC. 20 | All rights reserved. 21 | 22 | Redistribution and use in source and binary forms, with or without 23 | modification, are permitted provided that the following conditions are met: 24 | * Redistributions of source code must retain the above copyright 25 | notice, this list of conditions and the following disclaimer. 26 | * Redistributions in binary form must reproduce the above copyright 27 | notice, this list of conditions and the following disclaimer in the 28 | documentation and/or other materials provided with the distribution. 29 | * Neither the name of the Roundabout Co. nor the 30 | names of its contributors may be used to endorse or promote products 31 | derived from this software without specific prior written permission. 32 | 33 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 34 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 36 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 37 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 39 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 40 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 42 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/project.xcworkspace/xcshareddata/RoundaboutKit.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectIdentifier 6 | 84753A62-A5F8-476B-BD1C-685F9FF99738 7 | IDESourceControlProjectName 8 | RoundaboutKit 9 | IDESourceControlProjectOriginsDictionary 10 | 11 | 5AA99680-D348-4CF8-BC6E-2436755D3873 12 | ssh://github.com/decarbonization/RoundaboutKit.git 13 | 14 | IDESourceControlProjectPath 15 | RoundaboutKit.xcodeproj/project.xcworkspace 16 | IDESourceControlProjectRelativeInstallPathDictionary 17 | 18 | 5AA99680-D348-4CF8-BC6E-2436755D3873 19 | ../.. 20 | 21 | IDESourceControlProjectURL 22 | ssh://github.com/decarbonization/RoundaboutKit.git 23 | IDESourceControlProjectVersion 24 | 110 25 | IDESourceControlProjectWCCIdentifier 26 | 5AA99680-D348-4CF8-BC6E-2436755D3873 27 | IDESourceControlProjectWCConfigurations 28 | 29 | 30 | IDESourceControlRepositoryExtensionIdentifierKey 31 | public.vcs.git 32 | IDESourceControlWCCIdentifierKey 33 | 5AA99680-D348-4CF8-BC6E-2436755D3873 34 | IDESourceControlWCCName 35 | RoundaboutKit 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/External/RoundaboutKit/RoundaboutKit.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/xcuserdata/km.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/xcuserdata/km.xcuserdatad/xcschemes/RoundaboutKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 44 | 45 | 51 | 52 | 54 | 55 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/xcuserdata/km.xcuserdatad/xcschemes/RoundaboutKitMacTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 36 | 37 | 38 | 39 | 45 | 46 | 48 | 49 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit.xcodeproj/xcuserdata/km.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RoundaboutKit.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | RoundaboutKitMac.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | RoundaboutKitMacTests.xcscheme 18 | 19 | orderHint 20 | 2 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 8B75839717920E7200D45F54 26 | 27 | primary 28 | 29 | 30 | 8B7583A717920E7200D45F54 31 | 32 | primary 33 | 34 | 35 | 8B7583ED1792100D00D45F54 36 | 37 | primary 38 | 39 | 40 | 8B7583FE1792100D00D45F54 41 | 42 | primary 43 | 44 | 45 | 8B75842F179210F300D45F54 46 | 47 | primary 48 | 49 | 50 | 8BE806F51792189300DFEC35 51 | 52 | primary 53 | 54 | 55 | 8BE807051792189300DFEC35 56 | 57 | primary 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKActivityManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKActivityManager.h 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 12/10/12. 6 | // Copyright (c) 2012 Kevin MacWhinnie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The RKActivityManager class is responsible for managing the activity state of the application. 12 | /// 13 | ///The RKActivityManager class does not provide an interface, this is the responsbility of the host application. 14 | @interface RKActivityManager : NSObject 15 | 16 | ///Returns the shared activity manager, creating it if it doesn't exist. 17 | + (instancetype)sharedActivityManager; 18 | 19 | #pragma mark - Properties 20 | 21 | ///Whether or not there is activity. KVC compliant. 22 | /// 23 | ///This property should be observed by an application's main controller, 24 | ///and used to control the display of a prominent activity indicator view. 25 | /// 26 | ///This property is thread-safe for interface bindings. 27 | @property (readonly) BOOL isActive; 28 | 29 | ///The activity count of the manager. 30 | /// 31 | ///This property can potentially be mutated from multiple threads, and as such 32 | ///is not safe to be bound to or observed for the purpose of manipulating interface 33 | ///controls. The `isActive` property should be used in stead. 34 | @property NSUInteger activityCount; 35 | 36 | #if TARGET_OS_IPHONE 37 | 38 | ///Whether or not the activity manager updates the network activity indicator. 39 | @property (nonatomic) BOOL updatesNetworkActivityIndicator; 40 | 41 | #endif /* TARGET_OS_IPHONE */ 42 | 43 | #pragma mark - Activity 44 | 45 | ///Increments the activity count of the receiver. 46 | - (void)incrementActivityCount; 47 | 48 | ///Decrements the activity count of the receiver. 49 | - (void)decrementActivityCount; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKActivityManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKActivityManager.m 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 12/10/12. 6 | // Copyright (c) 2012 Kevin MacWhinnie. All rights reserved. 7 | // 8 | 9 | #import "RKActivityManager.h" 10 | #if TARGET_OS_IPHONE 11 | # import 12 | #endif /* TARGET_OS_IPHONE */ 13 | 14 | @implementation RKActivityManager 15 | 16 | + (instancetype)sharedActivityManager 17 | { 18 | static RKActivityManager *sharedActivityManager = nil; 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | sharedActivityManager = [self new]; 22 | }); 23 | 24 | return sharedActivityManager; 25 | } 26 | 27 | - (id)init 28 | { 29 | if((self = [super init])) { 30 | [self addObserver:self forKeyPath:@"activityCount" options:0 context:NULL]; 31 | } 32 | 33 | return self; 34 | } 35 | 36 | #pragma mark - Observations 37 | 38 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 39 | { 40 | if((object == self) && [keyPath isEqualToString:@"activityCount"]) { 41 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 42 | [self willChangeValueForKey:@"isActive"]; 43 | #if TARGET_OS_IPHONE 44 | if(_updatesNetworkActivityIndicator) 45 | [UIApplication sharedApplication].networkActivityIndicatorVisible = self.isActive; 46 | #endif /* TARGET_OS_IPHONE */ 47 | [self didChangeValueForKey:@"isActive"]; 48 | }]; 49 | } else { 50 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 51 | } 52 | } 53 | 54 | #pragma mark - Properties 55 | 56 | - (BOOL)isActive 57 | { 58 | return (self.activityCount > 0); 59 | } 60 | 61 | #pragma mark - Activity 62 | 63 | - (void)incrementActivityCount 64 | { 65 | if(self.activityCount == NSIntegerMax) 66 | [NSException raise:NSInternalInconsistencyException format:@"NSIntegerMax reached, cannot increment activity count anymore."]; 67 | 68 | self.activityCount++; 69 | } 70 | 71 | - (void)decrementActivityCount 72 | { 73 | if(self.activityCount == 0) 74 | return; 75 | 76 | self.activityCount--; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKDefaults.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKDefaults.h 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #ifndef RKDefaults_h 10 | #define RKDefaults_h 1 11 | 12 | #import 13 | #import "RKPrelude.h" 14 | 15 | ///Short-hand for interacting with the user defaults. 16 | 17 | #pragma mark Defaults Short-hand 18 | 19 | ///Persist an object into the user defaults. 20 | RK_EXTERN id RKSetPersistentObject(NSString *key, id object); 21 | 22 | ///Get an object persisted into the user defaults. 23 | RK_EXTERN id RKGetPersistentObject(NSString *key); 24 | 25 | #pragma mark - 26 | 27 | ///Persist an integer into the user defaults. 28 | RK_EXTERN NSInteger RKSetPersistentInteger(NSString *key, NSInteger value); 29 | 30 | ///Get an object persisted into the user defaults. 31 | RK_EXTERN NSInteger RKGetPersistentInteger(NSString *key); 32 | 33 | #pragma mark - 34 | 35 | ///Persist an integer into the user defaults. 36 | RK_EXTERN float RKSetPersistentFloat(NSString *key, float value); 37 | 38 | ///Get an object persisted into the user defaults. 39 | RK_EXTERN float RKGetPersistentFloat(NSString *key); 40 | 41 | #pragma mark - 42 | 43 | ///Persist an integer into the user defaults. 44 | RK_EXTERN BOOL RKSetPersistentBool(NSString *key, BOOL value); 45 | 46 | ///Get an object persisted into the user defaults. 47 | RK_EXTERN BOOL RKGetPersistentBool(NSString *key); 48 | 49 | #pragma mark - 50 | 51 | ///Returns a boolean indicating whether or not a persistent value exists. 52 | RK_EXTERN BOOL RKPersistentValueExists(NSString *key); 53 | 54 | #pragma mark - Testing Support 55 | 56 | ///Turns off the persistent backing of the RKDefaults functions. Intended for use with unit tests. 57 | RK_EXTERN void RKDefaultsActivateTestMode(); 58 | 59 | #endif /* RKDefaults_h */ 60 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKFileSystemCacheManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKFileSystemCacheManager.h 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 1/7/13. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKURLRequestPromise.h" 10 | 11 | ///The RKFileSystemCacheManager class encapsulates a persistent data-agnostic cache manager. 12 | /// 13 | ///RKFileSystemCacheManager is asynchronously initialize to reduce the cost of calling 14 | ///`+[self sharedCacheManagerForBucket]` as the cache manager must perform file system IO 15 | ///when it is initialized. This means that any method calls before the initialization 16 | ///process has been completed may block longer than is otherwise typical. 17 | /// 18 | ///The methods on this class should always be called from a background thread. 19 | /// 20 | ///This class was formerly known as RKURLRequestPromiseCacheManager. 21 | @interface RKFileSystemCacheManager : NSObject 22 | 23 | ///Returns the shared cache manager, creating it if it does not already exist. 24 | + (instancetype)sharedCacheManager; 25 | 26 | #pragma mark - Properties 27 | 28 | ///The name of the bucket associated with this cache manager. 29 | @property (readonly, copy) NSString *bucketName DEPRECATED_ATTRIBUTE; 30 | 31 | ///The maximum size of the cache. Defaults to 30 MB. 32 | /// 33 | ///Changing the value of this property will not affect 34 | ///the cache until its next maintenance cycle. 35 | @property NSUInteger maxCacheSize; 36 | 37 | ///The estimated size of the cache. 38 | @property (readonly) NSUInteger cacheSize; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKQueueManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKQueueManager.h 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 6/13/13. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The RKQueueManager class manages a collection of named queues which tasks can be executed on. 12 | @interface RKQueueManager : NSObject 13 | 14 | ///Returns the shared queue cache, creating it if it does not already exist. 15 | + (NSCache *)queueCache; 16 | 17 | ///Returns a queue matching a given name. 18 | /// 19 | /// \param queueName The name of the queue to find. Required. 20 | /// 21 | /// \result A queue corresponding to the name given. 22 | /// 23 | ///This method may return different values if called concurrently 24 | ///from multiple threads. The returned queue may not be reconfigured. 25 | /// 26 | ///There is an upper limit on the number of queues that may be kept 27 | ///in memory at a given time. The default limit is 10. 28 | + (NSOperationQueue *)queueNamed:(NSString *)queueName; 29 | 30 | ///Returns a common catch-all queue suitable for use for short-lived background tasks. 31 | /// 32 | ///The returned queue is subject to the same rules as 33 | ///all other queues vended by the RKQueueManager class. 34 | + (NSOperationQueue *)commonQueue; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RKQueueManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKQueueManager.m 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 6/13/13. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKQueueManager.h" 10 | 11 | ///The maximum number of queues to keep around at once. 12 | static NSUInteger const kCacheLimit = 10; 13 | 14 | @implementation RKQueueManager 15 | 16 | + (NSCache *)queueCache 17 | { 18 | static NSCache *queueCache = nil; 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | queueCache = [NSCache new]; 22 | queueCache.name = @"com.roundabout.rk.queueManager.queueCache"; 23 | queueCache.countLimit = kCacheLimit; 24 | }); 25 | 26 | return queueCache; 27 | } 28 | 29 | + (NSOperationQueue *)queueNamed:(NSString *)queueName 30 | { 31 | NSParameterAssert(queueName); 32 | 33 | NSCache *queueCache = [self queueCache]; 34 | 35 | NSOperationQueue *queue = [queueCache objectForKey:queueName]; 36 | if(!queue) { 37 | queue = [NSOperationQueue new]; 38 | queue.name = queueName; 39 | } 40 | 41 | return queue; 42 | } 43 | 44 | + (NSOperationQueue *)commonQueue 45 | { 46 | return [self queueNamed:@"com.roundabout.rk.queueManager.commonQueue"]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RoundaboutKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import "RKPrelude.h" 10 | #endif 11 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKit/RoundaboutKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Roundabout Software, LLC. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the Roundabout Co. nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import "RKPrelude.h" 29 | #import "RKQueueManager.h" 30 | #import "RKPromise.h" 31 | #import "RKPossibility.h" 32 | #import "RKDefaults.h" 33 | #import "RKConnectivityManager.h" 34 | #import "RKURLRequestPromise.h" 35 | #import "RKFileSystemCacheManager.h" 36 | #import "RKRequestFactory.h" 37 | #import "RKPossibility.h" 38 | #import "RKActivityManager.h" 39 | 40 | #if TARGET_OS_IPHONE 41 | # import "RKImageLoader.h" 42 | #endif /* TARGET_OS_IPHONE */ 43 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKitMac/RoundaboutKitMac-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.roundabout.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 2.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 2.0 25 | NSHumanReadableCopyright 26 | Copyright © 2013 Roundabout Software, LLC. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKitMac/RoundaboutKitMac-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // RoundaboutKitMac-Prefix.pch 3 | // RoundaboutKit 4 | // 5 | // Created by Kevin MacWhinnie on 7/13/13. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #ifndef RoundaboutKit_RoundaboutKitMac_Prefix_pch 10 | #define RoundaboutKit_RoundaboutKitMac_Prefix_pch 11 | 12 | # import 13 | # import "RoundaboutKit.h" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /External/RoundaboutKit/RoundaboutKitMac/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKActivityManagerTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKActivityManagerTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 4/12/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKActivityManagerTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKActivityManagerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKActivityManagerTests.m 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 4/12/13. 6 | // 7 | // 8 | 9 | #import "RKActivityManagerTests.h" 10 | 11 | @implementation RKActivityManagerTests 12 | 13 | - (void)setUp 14 | { 15 | [super setUp]; 16 | 17 | } 18 | 19 | - (void)tearDown 20 | { 21 | [super tearDown]; 22 | 23 | } 24 | 25 | - (void)testActivityManager 26 | { 27 | RKActivityManager *activityManager = [RKActivityManager sharedActivityManager]; 28 | 29 | STAssertFalse(activityManager.isActive, @".isActive is wrong"); 30 | STAssertEquals(activityManager.activityCount, 0UL, @".activityCount is wrong"); 31 | 32 | [activityManager incrementActivityCount]; 33 | [activityManager incrementActivityCount]; 34 | 35 | STAssertTrue(activityManager.isActive, @".isActive is wrong"); 36 | STAssertEquals(activityManager.activityCount, 2UL, @".activityCount is wrong"); 37 | 38 | [activityManager decrementActivityCount]; 39 | [activityManager decrementActivityCount]; 40 | 41 | STAssertFalse(activityManager.isActive, @".isActive is wrong"); 42 | STAssertEquals(activityManager.activityCount, 0UL, @".activityCount is wrong"); 43 | 44 | [activityManager decrementActivityCount]; 45 | 46 | STAssertEquals(activityManager.activityCount, 0UL, @".activityCount is wrong"); 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKDefaultsTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKDefaultsTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 4/12/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKDefaultsTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKFileSystemCacheManagerTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKCacheManagerTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKFileSystemCacheManagerTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKMockPromise.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKMockPromise.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import "RKPromise.h" 10 | 11 | ///The RKMockPromise class encapsulates a determinate asynchronous 12 | ///process that will yield a predetermined success or failure value. 13 | @interface RKMockPromise : RKPromise 14 | 15 | ///Initialize the receiver with an expected result, duration, whether or not 16 | ///it can cancel, and the number of times the success callback should be run. 17 | /// 18 | /// \param result The value to yield for the promise. The possibility *cannot* be empty. Required. 19 | /// \param duration The amount of time to elapse before the promise is run. May be 0.0. 20 | /// 21 | ///This is the designated initializer of RKMockPromise. 22 | - (id)initWithResult:(RKPossibility *)result 23 | duration:(NSTimeInterval)duration RK_REQUIRE_RESULT_USED; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKMockPromise.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKMockPromise.m 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import "RKMockPromise.h" 10 | 11 | ///The amount of time that should elapse between success callbacks. 12 | #define SUCCESS_CALLBACK_SLEEP_TIME 0.1 13 | 14 | @interface RKMockPromise () 15 | 16 | ///The intended result of the mock promise. 17 | @property RKPossibility *result; 18 | 19 | ///The amount of time that should elapse before a mock promise yields a value/error. 20 | @property NSTimeInterval duration; 21 | 22 | @end 23 | 24 | @implementation RKMockPromise 25 | 26 | - (id)init 27 | { 28 | [self doesNotRecognizeSelector:_cmd]; 29 | return nil; 30 | } 31 | 32 | - (id)initWithResult:(RKPossibility *)result 33 | duration:(NSTimeInterval)duration 34 | { 35 | NSParameterAssert(result); 36 | NSAssert((result.state != kRKPossibilityStateEmpty), @"Cannot pass an empty possibility to RKMockPromise."); 37 | 38 | if((self = [super init])) { 39 | self.result = result; 40 | self.duration = duration; 41 | } 42 | 43 | return self; 44 | } 45 | 46 | #pragma mark - Execution 47 | 48 | - (void)fire 49 | { 50 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.duration * NSEC_PER_SEC)); 51 | dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 52 | [self.result whenValue:^(id value) { 53 | [self accept:value]; 54 | }]; 55 | [self.result whenError:^(NSError *error) { 56 | [self reject:error]; 57 | }]; 58 | }); 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKPossibilityTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKPossibilityTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 4/12/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKPossibilityTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKPostProcessorTestImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/External/RoundaboutKit/Tests/RKPostProcessorTestImage.png -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKPreludeTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKPreludeTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 4/12/13. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RKPreludeTests : SenTestCase 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKPromiseTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKPromiseTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKPromiseTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RKURLRequestPromiseTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKURLRequestPromiseTests.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface RKURLRequestPromiseTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RunLoopHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // RunLoopHelper.h 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | ///The RunLoopHelper class contains methods to assist in tests 12 | ///which require the main runloop to be running to complete. 13 | @interface RunLoopHelper : NSObject 14 | 15 | ///Runs the main run loop for n seconds. 16 | /// 17 | /// \param seconds The number of seconds to run the run loop for. 18 | /// 19 | + (void)runFor:(NSTimeInterval)seconds; 20 | 21 | ///Runs the main run loop until the given predicate yields NO. 22 | /// 23 | /// \param predicate A block which returns a BOOL indicating whether or not the run loop should continue. Required. 24 | /// \param seconds The timeout for the run loop cycle. Must be greater than 0.0. 25 | /// 26 | /// \result YES if the run cycle ended naturally; NO if it timed out. 27 | + (BOOL)runUntil:(BOOL(^)())predicate orSecondsHasElapsed:(NSTimeInterval)seconds; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/RunLoopHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // RunLoopHelper.m 3 | // RoundaboutKitTests 4 | // 5 | // Created by Kevin MacWhinnie on 5/6/13. 6 | // 7 | // 8 | 9 | #import "RunLoopHelper.h" 10 | 11 | @implementation RunLoopHelper 12 | 13 | + (void)runFor:(NSTimeInterval)seconds 14 | { 15 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:seconds]]; 16 | } 17 | 18 | + (BOOL)runUntil:(BOOL(^)())predicate orSecondsHasElapsed:(NSTimeInterval)seconds 19 | { 20 | NSParameterAssert(predicate); 21 | 22 | NSDate *startTime = [NSDate date]; 23 | BOOL lessThanStartTime = YES; 24 | NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 25 | while (!predicate() && 26 | (lessThanStartTime = (-[startTime timeIntervalSinceNow] < seconds)) && 27 | [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); 28 | 29 | return lessThanStartTime; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | roundabout.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import 10 | #import "RunLoopHelper.h" 11 | #endif 12 | -------------------------------------------------------------------------------- /External/RoundaboutKit/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /FileEnumerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // FileEnumerator.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 1/21/13. 6 | // 7 | // 8 | 9 | #ifndef Pinna_FileEnumerator_h 10 | #define Pinna_FileEnumerator_h 11 | 12 | RK_INLINE void EnumerateFilesInLocation(NSURL *folderLocation, void(^callback)(NSURL *location)) 13 | { 14 | NSCParameterAssert(folderLocation); 15 | NSCAssert([folderLocation isFileURL], @"Cannot find files in the cloud, you idiot."); 16 | 17 | NSNumber *isDirectory = nil; 18 | if(![folderLocation getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]) 19 | NSCAssert(0, @"Couldn't retrieve NSURLIsDirectoryKey for %@", folderLocation); 20 | 21 | if(![isDirectory boolValue]) 22 | { 23 | callback(folderLocation); 24 | return; 25 | } 26 | 27 | NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:folderLocation 28 | includingPropertiesForKeys:@[NSURLIsDirectoryKey, NSURLTypeIdentifierKey] 29 | options:NSDirectoryEnumerationSkipsHiddenFiles 30 | errorHandler:^(NSURL *url, NSError *error) { 31 | NSLog(@"%@ for %@", [error localizedDescription], url); 32 | return NO; 33 | }]; 34 | 35 | for (NSURL *item in enumerator) 36 | { 37 | if(![item getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]) 38 | NSCAssert(0, @"Couldn't retrieve NSURLIsDirectoryKey for %@", item); 39 | 40 | NSString *type = nil; 41 | if(![item getResourceValue:&type forKey:NSURLTypeIdentifierKey error:nil]) 42 | NSCAssert(0, @"Couldn't retrieve NSURLTypeIdentifierKey for %@", item); 43 | 44 | if([isDirectory boolValue] || [type rangeOfString:@"audio"].location == NSNotFound) 45 | continue; 46 | 47 | callback(item); 48 | } 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /FriendActivityBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FriendActivityBrowserLevel.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/29/12. 6 | // 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | @class Library, ExfmSession; 12 | @interface FriendActivityBrowserLevel : RKBrowserLevel 13 | { 14 | Library *mLibrary; 15 | ExfmSession *mExfmSession; 16 | 17 | NSArray *mCachedActors; 18 | NSArray *mCachedSongs; 19 | 20 | NSCache *mArtworkCache; 21 | NSMutableSet *mArtworkBeingDownloaded; 22 | NSOperationQueue *mArtworkDownloadQueue; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /GeneralIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/GeneralIcon.png -------------------------------------------------------------------------------- /GeneralIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/GeneralIcon@2x.png -------------------------------------------------------------------------------- /GeneralPane.h: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralPane.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "PreferencesPane.h" 10 | 11 | @interface GeneralPane : PreferencesPane 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GeneralPane.m: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralPane.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "GeneralPane.h" 10 | 11 | @implementation GeneralPane 12 | 13 | #pragma mark Properties 14 | 15 | - (NSString *)name 16 | { 17 | return @"General"; 18 | } 19 | 20 | - (NSImage *)icon 21 | { 22 | return [NSImage imageNamed:@"GeneralIcon"]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /HeaderLabelView.h: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderLabelView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/25/11. 6 | // Copyright (c) 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class AMIndeterminateProgressIndicatorCell; 12 | @interface HeaderLabelView : NSView 13 | { 14 | /** Internal **/ 15 | 16 | ///The spinner of the header. 17 | AMIndeterminateProgressIndicatorCell *mSpinner; 18 | 19 | ///The animation timer of the spinner. 20 | NSTimer *mSpinnerHeartBeat; 21 | 22 | ///The tracking area used to highlight rows. 23 | NSTrackingArea *mHoverTrackingArea; 24 | 25 | ///Whether or not a mouse down can move the window. 26 | BOOL mMouseDownCanMoveWindow; 27 | 28 | ///Whether or not the mouse is inside the header view. 29 | BOOL mMouseInside; 30 | 31 | ///Whether or not the mouse is pressed. 32 | BOOL mMouseIsPressed; 33 | 34 | ///Whether or not the header view is highlighted. 35 | BOOL mHighlighted; 36 | 37 | 38 | /** Properties **/ 39 | 40 | ///Storage for `string` 41 | NSString *mString; 42 | 43 | ///Storage for `leftMargin` 44 | CGFloat mLeftMargin; 45 | 46 | ///Storage for `rightMargin` 47 | CGFloat mRightMargin; 48 | 49 | ///Storage for `showBusyIndicator` 50 | BOOL mShowBusyIndicator; 51 | 52 | 53 | ///Storage for `clickable` 54 | BOOL mClickable; 55 | 56 | ///Storage for `action` 57 | SEL mAction; 58 | 59 | ///Storage for `target` 60 | id mTarget; 61 | } 62 | 63 | #pragma mark Properties 64 | 65 | ///The string value of the header label view. 66 | @property (nonatomic, copy) NSString *string; 67 | 68 | ///The left margin of the header label view. 69 | @property (nonatomic) CGFloat leftMargin; 70 | 71 | ///The right margin of the header label view. 72 | @property (nonatomic) CGFloat rightMargin; 73 | 74 | ///Whether or not the header should be spinning its progress indicator. 75 | @property (nonatomic) BOOL showBusyIndicator; 76 | 77 | #pragma mark - 78 | 79 | ///Whether or not the view is clickable. 80 | @property (nonatomic) BOOL clickable; 81 | 82 | ///The view's action. 83 | @property (nonatomic) SEL action; 84 | 85 | ///The target of the view's action. 86 | @property (nonatomic) id target; 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /HotKeyDispatcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // HotKeyDispatcher.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/24/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "SRCommon.h" 12 | 13 | @protocol HotKeyDispatcherDelegate; 14 | 15 | RK_EXTERN NSDictionary *KeyComboToDictionary(KeyCombo keyCombo); 16 | RK_EXTERN KeyCombo KeyComboFromDictionary(NSDictionary *dictionary); 17 | 18 | #pragma mark - 19 | 20 | @interface HotKeyDispatcher : NSObject 21 | { 22 | EventHotKeyRef mPlayPauseHotKeyRef; 23 | EventHotKeyRef mNextTrackHotKeyRef; 24 | EventHotKeyRef mPreviousTrackHotKeyRef; 25 | 26 | ///Storage for `playPauseCombo` 27 | KeyCombo mPlayPauseCombo; 28 | 29 | ///Storage for `nextTrackCombo` 30 | KeyCombo mNextTrackCombo; 31 | 32 | ///Storage for `previousTrackCombo` 33 | KeyCombo mPreviousTrackCombo; 34 | 35 | 36 | ///Storage for `delegate` 37 | id mDelegate; 38 | } 39 | 40 | + (HotKeyDispatcher *)sharedHotKeyDispatcher; 41 | 42 | #pragma mark - Properties 43 | 44 | ///The key combo to listen for for play pause. 45 | @property (nonatomic) KeyCombo playPauseCombo; 46 | 47 | ///The key combo to listen for for next track. 48 | @property (nonatomic) KeyCombo nextTrackCombo; 49 | 50 | ///The key combo to listen for for previous track. 51 | @property (nonatomic) KeyCombo previousTrackCombo; 52 | 53 | #pragma mark - 54 | 55 | @property (nonatomic) id delegate; 56 | 57 | @end 58 | 59 | #pragma mark - 60 | 61 | @protocol HotKeyDispatcherDelegate 62 | @required 63 | 64 | - (void)hotKeyDispatcherDetectedPlayPause:(HotKeyDispatcher *)sender; 65 | 66 | - (void)hotKeyDispatcherDetectedNextTrack:(HotKeyDispatcher *)sender; 67 | 68 | - (void)hotKeyDispatcherDetectedPreviousTrack:(HotKeyDispatcher *)sender; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /HotKeysIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/HotKeysIcon.png -------------------------------------------------------------------------------- /HotKeysIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/HotKeysIcon@2x.png -------------------------------------------------------------------------------- /HotKeysPane.h: -------------------------------------------------------------------------------- 1 | // 2 | // HotKeysPane.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 7/7/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "PreferencesPane.h" 10 | 11 | @class SRRecorderControl; 12 | 13 | @interface HotKeysPane : PreferencesPane 14 | { 15 | IBOutlet SRRecorderControl *oPlayPauseRecorder; 16 | IBOutlet SRRecorderControl *oNextTrackRecorder; 17 | IBOutlet SRRecorderControl *oPreviousTrackRecorder; 18 | } 19 | 20 | #pragma mark Actions 21 | 22 | - (IBAction)listensForMediaKeysChanged:(NSButton *)sender; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2013, Roundabout Software, LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Roundabout Software, LLC nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL ROUNDABOUT SOFTWARE, LLC BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /LastFMDefines.h: -------------------------------------------------------------------------------- 1 | // 2 | // LastFMDefines.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/13/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifndef Pinna_LastFMDefines_h 12 | #define Pinna_LastFMDefines_h 13 | 14 | //Uncomment the following define to have Last.fm use 15 | //our non-commercial public and private keys, and to use 16 | //the non-commercial user defaults keys. 17 | //#define BUILD_LASTFM_FOR_INTERNAL 1 18 | 19 | ///The user defaults key for the cached Last.fm session key. 20 | RK_EXTERN NSString *const kLastFMSessionDefaultsKey DEPRECATED_ATTRIBUTE; 21 | 22 | ///The user defaults key for the cached Last.fm user info. 23 | RK_EXTERN NSString *const kLastFMCachedUserInfoDefaultsKey; 24 | 25 | 26 | ///Our Last.fm public key. 27 | RK_EXTERN NSString *const kLastFMPublicKey; 28 | 29 | ///Our Last.fm shared secret. 30 | RK_EXTERN NSString *const kLastFMSecret; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /LastFMDefines.m: -------------------------------------------------------------------------------- 1 | // 2 | // LastFMDefines.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 2/13/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "LastFMDefines.h" 10 | 11 | #if BUILD_LASTFM_FOR_INTERNAL 12 | 13 | #warning Building Last.fm for Internal Testing 14 | 15 | NSString *const kLastFMSessionDefaultsKey = @"LastFMSessionKey"; 16 | NSString *const kLastFMCachedUserInfoDefaultsKey = @"LastFM_cachedUserInfo"; 17 | 18 | NSString *const kLastFMPublicKey = @"c9e43d974b1851ad62b617b8b4a24749"; 19 | NSString *const kLastFMSecret = @"afb90a915ba30d52ef4cc4744ed2fc5b"; 20 | 21 | #else 22 | 23 | NSString *const kLastFMSessionDefaultsKey = @"LastFMSessionKey_Deployment"; 24 | NSString *const kLastFMCachedUserInfoDefaultsKey = @"LastFM_cachedUserInfo_Deployment"; 25 | 26 | NSString *const kLastFMPublicKey = @"c28ced55bab8f035de0e0f33479f749d"; 27 | NSString *const kLastFMSecret = @"c3c1b6d9f808dc617acbc9ba6997444d"; 28 | 29 | #endif /* BUILD_LASTFM_FOR_INTERNAL */ -------------------------------------------------------------------------------- /LastFMLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LastFMLogo.png -------------------------------------------------------------------------------- /LastFMLogo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LastFMLogo@2x.png -------------------------------------------------------------------------------- /LastfmAccountServiceViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LastfmAccountServiceViewController.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "RKViewController.h" 10 | #import "ServiceAuthorizationPresenter.h" 11 | 12 | @class ServiceDescriptor; 13 | 14 | ///The LastfmAccountServiceViewController class encapsulates authorizing Pinna with Last.fm. 15 | @interface LastfmAccountServiceViewController : RKViewController 16 | 17 | #pragma mark - Outlets 18 | 19 | ///The button the user presses to begin authorizing through Last.fm. 20 | @property (assign) IBOutlet NSButton *authorizeButton; 21 | 22 | ///The activity indicator. 23 | @property (assign) IBOutlet NSProgressIndicator *loadingActivityIndicator; 24 | 25 | #pragma mark - Properties 26 | 27 | ///The service being described by this controller. 28 | @property (nonatomic) ServiceDescriptor *serviceDescriptor; 29 | 30 | ///The completion handler block. 31 | @property (nonatomic, copy) ServiceAuthorizationPresenterCompletionHandler completionHandler; 32 | 33 | #pragma mark - Actions 34 | 35 | ///Begin the authorization process. 36 | - (IBAction)authorize:(id)sender; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /LinkArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LinkArrow.png -------------------------------------------------------------------------------- /LinkArrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LinkArrow@2x.png -------------------------------------------------------------------------------- /LoveItemButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton.png -------------------------------------------------------------------------------- /LoveItemButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Busy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Busy.png -------------------------------------------------------------------------------- /LoveItemButton_Busy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Busy@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Full.png -------------------------------------------------------------------------------- /LoveItemButton_Full@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Full@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Full_Presed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Full_Presed@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Full_Pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Full_Pressed.png -------------------------------------------------------------------------------- /LoveItemButton_Full_Pressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Full_Pressed@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Presed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Presed@2x.png -------------------------------------------------------------------------------- /LoveItemButton_Pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Pressed.png -------------------------------------------------------------------------------- /LoveItemButton_Pressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/LoveItemButton_Pressed@2x.png -------------------------------------------------------------------------------- /Lyrics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Lyrics 5 | 6 | 10 | 11 | 12 |
13 |
14 |
No Lyrics
15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /LyricsCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // LyricsCache.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 7/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class Song; 12 | 13 | ///The LyricsCache class is responsible for managing lyrics inputted into Pinna by the user. 14 | @interface LyricsCache : NSObject 15 | { 16 | NSCache *mLyricsCache; 17 | 18 | NSOperationQueue *mCachingQueue; 19 | } 20 | 21 | #pragma mark Lifecycle 22 | 23 | ///Returns the shared lyrics cache object, creating it if it doesn't exist. 24 | + (LyricsCache *)sharedLyricsCache; 25 | 26 | ///Causes the receiver to clear its lyrics cache. 27 | - (void)deleteLyricsCache; 28 | 29 | #pragma mark - Accessing the Cache 30 | 31 | ///Returns a BOOL indicating whether or not the receiver has cached lyrics for a song. 32 | - (BOOL)hasLyricsForSong:(Song *)song; 33 | 34 | ///Asynchronously cache lyrics for a specified (required) song. 35 | - (void)cacheLyrics:(NSString *)lyrics forSong:(Song *)song; 36 | 37 | ///Returns the cached lyrics for a song, if any exist. 38 | - (NSString *)lyricsForSong:(Song *)song; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LyricsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LyricsViewController.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/10/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class WebView; 12 | @class Song; 13 | 14 | @interface LyricsViewController : NSViewController 15 | { 16 | ///The current song. 17 | Song *mCurrentSong; 18 | 19 | ///Whether or not the controller is editing. 20 | BOOL mIsEditing; 21 | 22 | 23 | ///The header view of the buttons. 24 | IBOutlet NSView *oButtonsHeader; 25 | 26 | ///The lyrics web view. 27 | IBOutlet WebView *oLyricsWebView; 28 | } 29 | 30 | #pragma mark - Actions 31 | 32 | ///Saves the lyrics of the receiver. 33 | - (IBAction)save:(id)sender; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /MainWindowSplitView.h: -------------------------------------------------------------------------------- 1 | // 2 | // PinnaSplitView.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 12/8/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The split view subclass used by the main window to stylize the divider. 12 | @interface MainWindowSplitView : NSSplitView 13 | { 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /MainWindowSplitView.m: -------------------------------------------------------------------------------- 1 | // 2 | // PinnaSplitView.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 12/8/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "MainWindowSplitView.h" 10 | 11 | static NSGradient *DividerGradient = nil; 12 | 13 | @implementation MainWindowSplitView 14 | 15 | + (void)initialize 16 | { 17 | DividerGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedRed:0.55 green:0.55 blue:0.55 alpha:1.00] 18 | endingColor:[NSColor colorWithCalibratedRed:0.07 green:0.07 blue:0.07 alpha:1.00]]; 19 | 20 | [super initialize]; 21 | } 22 | 23 | #pragma mark - Drawing 24 | 25 | - (void)drawDividerInRect:(NSRect)rect 26 | { 27 | [DividerGradient drawInRect:rect angle:90.0]; 28 | } 29 | 30 | #pragma mark - Events 31 | 32 | - (void)resetCursorRects 33 | { 34 | 35 | } 36 | 37 | - (BOOL)mouseDownCanMoveWindow 38 | { 39 | return NO; 40 | } 41 | 42 | #pragma mark - 43 | 44 | 45 | - (void)mouseUp:(NSEvent *)theEvent 46 | { 47 | [[self nextResponder] mouseUp:theEvent]; 48 | } 49 | 50 | - (void)mouseDragged:(NSEvent *)theEvent 51 | { 52 | [[self nextResponder] mouseDragged:theEvent]; 53 | } 54 | 55 | - (void)mouseMoved:(NSEvent *)theEvent 56 | { 57 | [[self nextResponder] mouseMoved:theEvent]; 58 | } 59 | 60 | - (void)mouseDown:(NSEvent *)theEvent 61 | { 62 | [[self nextResponder] mouseDown:theEvent]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /MavenProBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/MavenProBold.otf -------------------------------------------------------------------------------- /MavenProMedium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/MavenProMedium.otf -------------------------------------------------------------------------------- /MavenProRegular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/MavenProRegular.otf -------------------------------------------------------------------------------- /MenuGenerator.h: -------------------------------------------------------------------------------- 1 | // 2 | // ContextualMenuGenerator.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 8/22/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class Library; 12 | 13 | ///The MenuGenerator class is responsible for generating contextual 14 | ///and share menus for the Pinna application. 15 | @interface MenuGenerator : NSObject 16 | { 17 | Library *library; 18 | } 19 | 20 | #pragma mark Lifecycle 21 | 22 | ///Returns the shared menu generator, creating it if it doesn't exist. 23 | + (MenuGenerator *)sharedGenerator; 24 | 25 | #pragma mark - Menu Generation 26 | 27 | ///Returns a fully configured contextual menu for an array of library items. 28 | - (NSMenu *)contextualMenuForLibraryItems:(NSArray *)items; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /MenuNotificationView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BackgroundStatusView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/7/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CATextLayer; 12 | 13 | @interface MenuNotificationView : NSView 14 | { 15 | /** State **/ 16 | 17 | ///The status item responsible for displaying the view. 18 | NSStatusItem *mStatusItem; 19 | 20 | ///The timer used to fade the status view out after 2 seconds. 21 | NSTimer *mFadeOutTimer; 22 | 23 | ///Whether or not the status view is highlighted. 24 | BOOL mHighlighted; 25 | 26 | 27 | /** Properties **/ 28 | 29 | ///See `image` 30 | NSImage *mImage; 31 | 32 | ///See `title` 33 | NSString *mTitle; 34 | 35 | ///See `isPaused` 36 | BOOL mIsPaused; 37 | 38 | ///See `action` 39 | dispatch_block_t mAction; 40 | } 41 | 42 | #pragma mark Initialization 43 | 44 | ///The designated initializer of BackgroundStatusView. 45 | - (id)init; 46 | 47 | #pragma mark - Properties 48 | 49 | ///The image of the background status view, if any. 50 | @property (nonatomic, copy) NSImage *image; 51 | 52 | ///The title of the background status view. 53 | @property (nonatomic, copy) NSString *title; 54 | 55 | ///Whether or not the receiver is paused. 56 | @property (nonatomic) BOOL isPaused; 57 | 58 | ///The action to invoke when the background status view is clicked, if any. 59 | @property (nonatomic, copy) dispatch_block_t action; 60 | 61 | #pragma mark - Visibility 62 | 63 | ///Show the receiver where appropriate. 64 | - (void)show; 65 | 66 | ///Close the receiver. 67 | - (void)close; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /NSObject+AssociatedValues.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+AssociatedValues.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 11/30/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// 12 | /// The AssociatedValues category on NSObject adds methods to associate 13 | /// arbitrary values with an instance of NSObject in a thread-safe manner. 14 | /// 15 | @interface NSObject (AssociatedValues) 16 | 17 | #pragma mark Object Associations 18 | 19 | ///Associates an arbitrary object with the receiver using a specified key. Thread safe. 20 | - (void)setAssociatedValue:(id)value forKey:(NSString *)key; 21 | 22 | ///Returns the value associated with a specified key. Thread safe. 23 | - (id)associatedValueForKey:(NSString *)key; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /NSObject+AssociatedValues.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+AssociatedValues.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 11/30/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "NSObject+AssociatedValues.h" 10 | #import 11 | 12 | static NSString *const kAssociatedValuesDictionaryKey = @"NSObject.Convenience.AssociatedValuesDictionary"; 13 | 14 | @implementation NSObject (AssociatedValues) 15 | 16 | #pragma mark Object Associations 17 | 18 | - (void)setAssociatedValue:(id)value forKey:(NSString *)key 19 | { 20 | NSParameterAssert(key); 21 | 22 | @synchronized(self) 23 | { 24 | NSMutableDictionary *associatedValues = objc_getAssociatedObject(self, (__bridge void *)kAssociatedValuesDictionaryKey); 25 | if(!associatedValues) 26 | { 27 | associatedValues = [NSMutableDictionary new]; 28 | objc_setAssociatedObject(self, (__bridge void *)kAssociatedValuesDictionaryKey, associatedValues, OBJC_ASSOCIATION_RETAIN); 29 | } 30 | 31 | if(value) 32 | [associatedValues setObject:value forKey:key]; 33 | else 34 | [associatedValues removeObjectForKey:key]; 35 | } 36 | } 37 | 38 | - (id)associatedValueForKey:(NSString *)key 39 | { 40 | NSParameterAssert(key); 41 | 42 | @synchronized(self) 43 | { 44 | NSMutableDictionary *associatedValues = objc_getAssociatedObject(self, (__bridge void *)kAssociatedValuesDictionaryKey); 45 | return [associatedValues objectForKey:key]; 46 | } 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /NSView+Convenience.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+Convenience.h 3 | // Player 4 | // 5 | // Created by Peter MacWhinnie on 12/8/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSShadow+EasyCreation.h" 11 | #import "NSBezierPath+MCAdditions.h" 12 | 13 | @interface NSView (BKConvenience) 14 | 15 | ///The first key view of the view. 16 | @property (assign) IBOutlet NSView *firstKeyView; 17 | 18 | ///The name of the view. 19 | @property (copy) NSString *name; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /NSView+Convenience.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+Convenience.m 3 | // Player 4 | // 5 | // Created by Peter MacWhinnie on 12/8/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "NSView+Convenience.h" 10 | #import "NSObject+AssociatedValues.h" 11 | 12 | @implementation NSView (BKConvenience) 13 | 14 | - (void)setFirstKeyView:(NSView *)view 15 | { 16 | [self setAssociatedValue:view forKey:@"firstKeyView"]; 17 | } 18 | 19 | - (NSView *)firstKeyView 20 | { 21 | return [self associatedValueForKey:@"firstKeyView"]; 22 | } 23 | 24 | - (void)setName:(NSString *)name 25 | { 26 | [self setAssociatedValue:[name copy] forKey:@"name"]; 27 | } 28 | 29 | - (NSString *)name 30 | { 31 | return [self associatedValueForKey:@"name"]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /NextTrack_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NextTrack_Button.png -------------------------------------------------------------------------------- /NextTrack_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NextTrack_Button@2x.png -------------------------------------------------------------------------------- /NextTrack_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NextTrack_ButtonPressed.png -------------------------------------------------------------------------------- /NextTrack_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NextTrack_ButtonPressed@2x.png -------------------------------------------------------------------------------- /NoArtwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NoArtwork.png -------------------------------------------------------------------------------- /NotificationBarShadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationBarShadow.png -------------------------------------------------------------------------------- /NotificationBarShadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationBarShadow@2x.png -------------------------------------------------------------------------------- /NotificationIcon_Paused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationIcon_Paused.png -------------------------------------------------------------------------------- /NotificationIcon_Paused@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationIcon_Paused@2x.png -------------------------------------------------------------------------------- /NotificationIcon_Playing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationIcon_Playing.png -------------------------------------------------------------------------------- /NotificationIcon_Playing@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NotificationIcon_Playing@2x.png -------------------------------------------------------------------------------- /NowPlayingBackgroundTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingBackgroundTexture.png -------------------------------------------------------------------------------- /NowPlayingLowerLayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingLowerLayer.png -------------------------------------------------------------------------------- /NowPlayingLowerLayer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingLowerLayer@2x.png -------------------------------------------------------------------------------- /NowPlayingShadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingShadow.png -------------------------------------------------------------------------------- /NowPlayingShadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingShadow@2x.png -------------------------------------------------------------------------------- /NowPlayingTextFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // NowPlayingTextFieldCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/17/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NowPlayingTextFieldCell : NSTextFieldCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /NowPlayingTextFieldCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // NowPlayingTextFieldCell.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/17/12. 6 | // 7 | // 8 | 9 | #import "NowPlayingTextFieldCell.h" 10 | 11 | @implementation NowPlayingTextFieldCell 12 | 13 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 14 | { 15 | NSShadow *shadow = RKShadowMake([NSColor colorWithDeviceWhite:1.0 alpha:0.6], 0.1, NSMakeSize(0.0, -1.0)); 16 | 17 | [NSGraphicsContext saveGraphicsState]; 18 | [shadow set]; 19 | 20 | [super drawWithFrame:cellFrame inView:controlView]; 21 | 22 | [NSGraphicsContext restoreGraphicsState]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /NowPlayingToggle_Off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingToggle_Off.png -------------------------------------------------------------------------------- /NowPlayingToggle_Off_Pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingToggle_Off_Pressed.png -------------------------------------------------------------------------------- /NowPlayingToggle_On.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingToggle_On.png -------------------------------------------------------------------------------- /NowPlayingToggle_On_Pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingToggle_On_Pressed.png -------------------------------------------------------------------------------- /NowPlayingUpperLayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingUpperLayer.png -------------------------------------------------------------------------------- /NowPlayingUpperLayer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/NowPlayingUpperLayer@2x.png -------------------------------------------------------------------------------- /Pause_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Pause_Button.png -------------------------------------------------------------------------------- /Pause_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Pause_Button@2x.png -------------------------------------------------------------------------------- /Pause_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Pause_ButtonPressed.png -------------------------------------------------------------------------------- /Pause_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Pause_ButtonPressed@2x.png -------------------------------------------------------------------------------- /PlayItemButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayItemButton.png -------------------------------------------------------------------------------- /PlayItemButton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayItemButton@2x.png -------------------------------------------------------------------------------- /PlayItemButton_Pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayItemButton_Pressed.png -------------------------------------------------------------------------------- /PlayItemButton_Pressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayItemButton_Pressed@2x.png -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/project.xcworkspace/xcshareddata/PlayKeys.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 9167A2E4-1659-4823-98FF-8E93C7DA04F7 9 | IDESourceControlProjectName 10 | PlayKeys 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 14 | ssh://github.com/decarbonization/player.git 15 | 16 | IDESourceControlProjectPath 17 | PlayKeys/PlayKeys.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/decarbonization/player.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 36 | IDESourceControlWCCName 37 | Player 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/xcuserdata/km.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys.xcodeproj/xcuserdata/km.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PlayKeys.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8BBE6EFF1466E6B20037D91E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PlayKeysAppDelegate.h 3 | // PlayKeys 4 | // 5 | // Created by Kevin MacWhinnie on 11/6/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MediaKeyEventTap.h" 11 | 12 | @interface AppDelegate : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/BackgroundArtworkDisplayView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BackgroundArtworkDisplayView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/27/11. 6 | // Copyright (c) 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BackgroundArtworkDisplayView : NSView 12 | 13 | #pragma mark Properties 14 | 15 | @property (nonatomic, copy) NSImage *image; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/BackgroundArtworkDisplayView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BackgroundArtworkDisplayView.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/27/11. 6 | // Copyright (c) 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "BackgroundArtworkDisplayView.h" 10 | #import 11 | #import "NSBezierPath+MCAdditions.h" 12 | 13 | @implementation BackgroundArtworkDisplayView 14 | 15 | #pragma mark - Drawing 16 | 17 | - (void)drawRect:(NSRect)dirtyRect 18 | { 19 | NSRect drawingRect = [self bounds]; 20 | 21 | [[NSColor blackColor] set]; 22 | [NSBezierPath fillRect:drawingRect]; 23 | 24 | if(_image) 25 | { 26 | NSRect imageRect = NSZeroRect; 27 | imageRect.size = [_image size]; 28 | 29 | CGFloat delta = drawingRect.size.width / imageRect.size.width; 30 | imageRect.size.width *= delta; 31 | imageRect.size.height *= delta; 32 | imageRect.origin.x = NSMidX(drawingRect) - (NSWidth(imageRect) / 2.0); 33 | imageRect.origin.y = NSMidY(drawingRect) - (NSHeight(imageRect) / 2.0); 34 | 35 | [_image setFlipped:NO]; 36 | [_image drawInRect:imageRect 37 | fromRect:NSZeroRect 38 | operation:NSCompositeSourceOver 39 | fraction:1.0 40 | respectFlipped:YES 41 | hints:nil]; 42 | 43 | [[NSColor colorWithDeviceWhite:0.0 alpha:0.5] set]; 44 | [[NSBezierPath bezierPathWithRect:drawingRect] strokeInside]; 45 | 46 | NSRect topLineRect = NSMakeRect(1.0, NSHeight(drawingRect) - 2.0, 47 | NSWidth(drawingRect) - 2.0, 1.0); 48 | [[NSColor colorWithDeviceWhite:1.0 alpha:0.45] set]; 49 | [NSBezierPath fillRect:topLineRect]; 50 | } 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/HeadsUpWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HeadsUpWindowController.h 3 | // PlayKeys 4 | // 5 | // Created by Kevin MacWhinnie on 5/27/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class BackgroundArtworkDisplayView; 12 | 13 | ///The HeadsUpWindowController class encapsulates the heads up controller that 14 | ///appears when the user press and holds the play-pause button on their keyboard. 15 | @interface HeadsUpWindowController : NSWindowController 16 | 17 | #pragma mark - Outlets 18 | 19 | ///The image view that displays the symbol for the current playback mode. 20 | @property (nonatomic, assign) IBOutlet NSImageView *playbackModeIndicatorImageView; 21 | 22 | ///The song artwork image view. 23 | @property (nonatomic, assign) IBOutlet BackgroundArtworkDisplayView *songArtworkImageView; 24 | 25 | ///The song name label. 26 | @property (nonatomic, assign) IBOutlet NSTextField *songNameLabel; 27 | 28 | ///The song detail label. 29 | @property (nonatomic, assign) IBOutlet NSTextField *songDetailLabel; 30 | 31 | #pragma mark - Properties 32 | 33 | ///A block to invoke when the controller window closes. 34 | @property (nonatomic, copy) dispatch_block_t dismissalHandler; 35 | 36 | #pragma mark - Updating 37 | 38 | ///Update the contents of the heads up window. 39 | - (void)update; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/Icon.icns -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/MavenProBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/MavenProBold.otf -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/MavenProMedium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/MavenProMedium.otf -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/MavenProRegular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/MavenProRegular.otf -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/NSString+SymlinksAndAliases.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+SymlinksAndAliases.h 3 | // ResolvePath 4 | // 5 | // Created by Matt Gallagher on 2010/02/22. 6 | // Copyright 2010 Matt Gallagher. All rights reserved. 7 | // 8 | // Permission is given to use this source code file, free of charge, in any 9 | // project, commercial or otherwise, entirely at your risk, with the condition 10 | // that any redistribution (in part or whole) of source code must retain 11 | // this copyright and permission notice. Attribution in compiled projects is 12 | // appreciated but not required. 13 | // 14 | 15 | #import 16 | 17 | @interface NSString (SymlinksAndAliases) 18 | 19 | - (NSString *)stringByResolvingSymlinksAndAliases; 20 | - (NSString *)stringByIterativelyResolvingSymlinkOrAlias; 21 | 22 | - (NSString *)stringByResolvingSymlink; 23 | - (NSString *)stringByConditionallyResolvingSymlink; 24 | 25 | - (NSString *)stringByResolvingAlias; 26 | - (NSString *)stringByConditionallyResolvingAlias; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/PFMoveApplication.h: -------------------------------------------------------------------------------- 1 | // 2 | // PFMoveApplication.h, version 1.7.2 3 | // LetsMove 4 | // 5 | // Created by Andy Kim at Potion Factory LLC on 9/17/09 6 | // 7 | // The contents of this file are dedicated to the public domain. 8 | 9 | #import 10 | 11 | void PFMoveToApplicationsFolderIfNecessary(void); 12 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/Pinna.m: -------------------------------------------------------------------------------- 1 | // 2 | // Pinna.m 3 | // PlayKeys 4 | // 5 | // Created by Kevin MacWhinnie on 5/27/13. 6 | // 7 | // 8 | 9 | #import "Pinna.h" 10 | 11 | @implementation Pinna 12 | 13 | + (instancetype)sharedPinna 14 | { 15 | static Pinna *sharedPinna = nil; 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | sharedPinna = [Pinna new]; 19 | }); 20 | 21 | return sharedPinna; 22 | } 23 | 24 | - (id)init 25 | { 26 | if((self = [super init])) { 27 | 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - Properties 34 | 35 | - (BOOL)isRunning 36 | { 37 | return RKCollectionDoesAnyValueMatch([[NSWorkspace sharedWorkspace] runningApplications], ^BOOL(NSRunningApplication *app) { 38 | return [app.bundleIdentifier isEqualToString:@"com.roundabout.pinna"]; 39 | }); 40 | } 41 | 42 | - (id )scriptingController 43 | { 44 | if(!self.isRunning) 45 | return nil; 46 | 47 | NSConnection *proxyConnection = [NSConnection connectionWithRegisteredName:@"com.roundabout.pinna.JSTalk" host:nil]; 48 | return (id )[proxyConnection rootProxy]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/PlayKeys-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ATSApplicationFontsPath 6 | Fonts 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | Icon 13 | CFBundleIdentifier 14 | com.roundabout.playkeys 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 2.0.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 2.0.0 27 | LSApplicationCategoryType 28 | public.app-category.utilities 29 | LSMinimumSystemVersion 30 | 10.7.4 31 | LSUIElement 32 | 33 | NSHumanReadableCopyright 34 | Copyright © 2011-2013 Roundabout Software LLC. All rights reserved. 35 | NSMainNibFile 36 | MainMenu 37 | NSPrincipalClass 38 | NSApplication 39 | 40 | 41 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/PlayKeys-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PlayKeys' target in the 'PlayKeys' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/PlayMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/PlayMode.png -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/PlayMode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/PlayMode@2x.png -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/ShuffleMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/ShuffleMode.png -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/ShuffleMode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlayKeys/PlayKeys/ShuffleMode@2x.png -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /PlayKeys/PlayKeys/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PlayKeys 4 | // 5 | // Created by Kevin MacWhinnie on 11/6/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /Play_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Play_Button.png -------------------------------------------------------------------------------- /Play_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Play_Button@2x.png -------------------------------------------------------------------------------- /Play_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Play_ButtonPressed.png -------------------------------------------------------------------------------- /Play_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Play_ButtonPressed@2x.png -------------------------------------------------------------------------------- /PlaybackErrorIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlaybackErrorIcon.png -------------------------------------------------------------------------------- /PlaybackErrorIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PlaybackErrorIcon@2x.png -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcshareddata/Pinna.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectIdentifier 6 | 9F63E12E-0998-45ED-9D4D-BC0CB7C1D87A 7 | IDESourceControlProjectName 8 | Pinna 9 | IDESourceControlProjectOriginsDictionary 10 | 11 | 179DE728-35D3-4C25-8502-EE7D28F98C26 12 | ssh://pinna.beanstalkapp.com//pinna.git 13 | 14 | IDESourceControlProjectPath 15 | Pinna.xcodeproj/project.xcworkspace 16 | IDESourceControlProjectRelativeInstallPathDictionary 17 | 18 | 179DE728-35D3-4C25-8502-EE7D28F98C26 19 | ../.. 20 | 8C352AEC-D417-485C-91D5-EA9FA9E4D490 21 | ../../../TagLib 22 | 23 | IDESourceControlProjectURL 24 | ssh://pinna.beanstalkapp.com//pinna.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 179DE728-35D3-4C25-8502-EE7D28F98C26 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 8C352AEC-D417-485C-91D5-EA9FA9E4D490 36 | IDESourceControlWCCName 37 | TagLib 38 | 39 | 40 | IDESourceControlRepositoryExtensionIdentifierKey 41 | public.vcs.git 42 | IDESourceControlWCCIdentifierKey 43 | 179DE728-35D3-4C25-8502-EE7D28F98C26 44 | IDESourceControlWCCName 45 | Pinna 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcshareddata/Player.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 2DC3B72F-F797-41FC-82E5-C923D855D32F 9 | IDESourceControlProjectName 10 | Player 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 14 | ssh://github.com/decarbonization/player.git 15 | 16 | IDESourceControlProjectPath 17 | Player.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/decarbonization/player.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | B9A650EA-7A9F-4A95-B698-11AC4976BF2C 36 | IDESourceControlWCCName 37 | Player 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcuserdata/Jon.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Player.xcodeproj/project.xcworkspace/xcuserdata/Jon.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcuserdata/Jon.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Player.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Player.xcodeproj/project.xcworkspace/xcuserdata/km.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 12 | 13 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 14 | 15 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges 16 | 17 | IssueFilterStyle 18 | ShowActiveSchemeOnly 19 | LiveSourceIssuesEnabled 20 | 21 | SnapshotAutomaticallyBeforeSignificantChanges 22 | 23 | SnapshotLocationStyle 24 | Default 25 | 26 | 27 | -------------------------------------------------------------------------------- /Player.xcodeproj/xcuserdata/Jon.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pinna.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8B12A3B816A8853C00249E0F 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Player.xcodeproj/xcuserdata/km.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Player.xcodeproj/xcuserdata/km.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pinna.xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | notifier.xcscheme 13 | 14 | orderHint 15 | 4 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 8B12A3B816A8853C00249E0F 21 | 22 | primary 23 | 24 | 25 | 8B403C401425031600022E33 26 | 27 | primary 28 | 29 | 30 | 8D1107260486CEB800E47090 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PlayerApplication.h: -------------------------------------------------------------------------------- 1 | // 2 | // PinnaApplication.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/21/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | ///The PlayerApplication class adds several mechanisms to NSApplication including 12 | ///an "important queue" mechanism which is used to track queues that must be allowed 13 | ///to finish in order for the application to terminate gracefully, as well as 14 | ///a JSTalk-enabling mechanism. Additionally, `PinnaApplication` adds hooks so that 15 | ///`WindowTransition` can function correctly when an application is hidden. 16 | @interface PlayerApplication : NSApplication 17 | { 18 | BOOL mIsWaitingForImportantQueuesToFinish; 19 | id mJSTalkObject; 20 | NSConnection *mJSTalkBroadcastConnection; 21 | } 22 | 23 | ///Adds a queue to the receiver's list of queues that must be allowed to finish before an application can terminate. 24 | - (void)addImportantQueue:(NSOperationQueue *)queue; 25 | 26 | ///Removes a queue from the receiver's list of queues that must be allowed to finish before an application can terminate. 27 | - (void)removeImportantQueue:(NSOperationQueue *)queue; 28 | 29 | ///Returns the queues that must be allowed to finish before an application can terminate. 30 | - (NSArray *)importantQueues; 31 | 32 | #pragma mark - 33 | 34 | ///Indicates whether or not the application is waiting for important queues to finish. 35 | @property (readonly) BOOL isWaitingForImportantQueuesToFinish; 36 | 37 | ///Cancels all pending operations on the receiver's important queues and waits for them to 38 | ///finish. This method blocks the calling thread until all remaining operations have completed. 39 | - (void)waitForImportantQueuesToFinish; 40 | 41 | #pragma mark - JSTalk 42 | 43 | ///Causes the receiver to broadcast the presence of the app with a specified root object. 44 | - (void)broadcastToJSTalkWithRootObject:(id)object; 45 | 46 | ///Causes the receiver to stop broadcasting through JSTalk. 47 | - (void)stopBroadcastingToJSTalk; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Player_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Player' target in the 'Player' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | # import 7 | # import 8 | # import "RoundaboutKitMac.h" 9 | # import "NSObject+AssociatedValues.h" 10 | #endif 11 | -------------------------------------------------------------------------------- /Playlist.h: -------------------------------------------------------------------------------- 1 | // 2 | // Playlist.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 12/4/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The different types a playlist can be. 12 | enum PlaylistType { 13 | ///The playlist contains music purchased in iTunes. 14 | kPlaylistTypePurchasedMusic = 1, 15 | 16 | ///The playlist contains the user's loved songs. 17 | kPlaylistTypeLovedSongs = 2, 18 | 19 | ///The playlist contains the user's friends' loved songs. 20 | kPlaylistTypeFriendsLovedSongs = 3, 21 | 22 | ///The normal type of playlist, simply imported from iTunes with no special markings. 23 | kPlaylistTypeDefault = 4, 24 | }; 25 | typedef NSUInteger PlaylistType; 26 | 27 | ///Used to represent playlists in the Player Library system. 28 | @interface Playlist : NSObject 29 | { 30 | NSString *mName; 31 | NSArray *mSongs; 32 | PlaylistType mPlaylistType; 33 | } 34 | 35 | ///Initialize a playlist with a specified title and a specified content array of songs. 36 | /// 37 | ///You may not use `kPlaylistTypeUserPlaylist` with this initializer. 38 | - (id)initWithName:(NSString *)name songs:(NSArray *)songs playlistType:(PlaylistType)playlistType; 39 | 40 | #pragma mark - Properties 41 | 42 | ///The title of the playlist. 43 | /// 44 | ///In the case of Playlist objects wrapping UserPlaylist objects, 45 | ///the `name` property simply forwards to the wrapped UserPlaylist. 46 | @property (readonly, RK_NONATOMIC_IOSONLY) NSString *name; 47 | 48 | ///The songs of the playlist. 49 | @property (copy, RK_NONATOMIC_IOSONLY) NSArray *songs; 50 | 51 | ///The type of the playlist. 52 | @property (readonly, RK_NONATOMIC_IOSONLY) PlaylistType playlistType; 53 | 54 | #pragma mark - 55 | 56 | ///The badge of the playlist. 57 | /// 58 | ///Not persisted. 59 | @property (copy) NSString *badge; 60 | 61 | #pragma mark - Identity 62 | 63 | ///Returns a predicate suitable for a search UI displaying an array of playlists. 64 | + (NSPredicate *)searchPredicateForQueryString:(NSString *)queryString; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Playlist_Friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Friends.png -------------------------------------------------------------------------------- /Playlist_Friends@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Friends@2x.png -------------------------------------------------------------------------------- /Playlist_Friends_Selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Friends_Selected.png -------------------------------------------------------------------------------- /Playlist_Friends_Selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Friends_Selected@2x.png -------------------------------------------------------------------------------- /Playlist_ITunes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_ITunes.png -------------------------------------------------------------------------------- /Playlist_ITunes@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_ITunes@2x.png -------------------------------------------------------------------------------- /Playlist_ITunes_Selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_ITunes_Selected.png -------------------------------------------------------------------------------- /Playlist_ITunes_Selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_ITunes_Selected@2x.png -------------------------------------------------------------------------------- /Playlist_Regular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Regular.png -------------------------------------------------------------------------------- /Playlist_Regular@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Regular@2x.png -------------------------------------------------------------------------------- /Playlist_Regular_Selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Regular_Selected.png -------------------------------------------------------------------------------- /Playlist_Regular_Selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Regular_Selected@2x.png -------------------------------------------------------------------------------- /Playlist_Remote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Remote.png -------------------------------------------------------------------------------- /Playlist_Remote@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Remote@2x.png -------------------------------------------------------------------------------- /Playlist_Remote_Selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Remote_Selected.png -------------------------------------------------------------------------------- /Playlist_Remote_Selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlist_Remote_Selected@2x.png -------------------------------------------------------------------------------- /Playlists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlists.png -------------------------------------------------------------------------------- /Playlists@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Playlists@2x.png -------------------------------------------------------------------------------- /PlaylistsBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // PlaylistsBrowserLevel.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 2/12/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | @class Library, Playlist; 12 | @class FriendActivityBrowserLevel; 13 | @interface PlaylistsBrowserLevel : RKBrowserLevel 14 | { 15 | Library *mLibrary; 16 | 17 | Playlist *mFriendActivityLevelPlaylist; 18 | FriendActivityBrowserLevel *mFriendActivityLevel; 19 | 20 | NSMutableArray *mPlaylists; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PreferencesButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleWhiteButton.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 1/2/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The PreferencesButtonCell class encapsulates a flat aesthetic 12 | ///button suitable for use in the Preferences window in Pinna. 13 | @interface PreferencesButtonCell : NSButtonCell 14 | 15 | ///Whether or not the cell has square corners. 16 | @property (nonatomic) BOOL hasSquareCorners; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /PreferencesPane.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesPane.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PreferencesPane : NSViewController 12 | 13 | #pragma mark Properties 14 | 15 | ///The name of the pane. 16 | @property (nonatomic, readonly, copy) NSString *name; 17 | 18 | ///The icon of the pane. 19 | @property (nonatomic, readonly, copy) NSImage *icon; 20 | 21 | #pragma mark - Adding/Removing 22 | 23 | - (void)paneWillBeRemovedFromWindow:(NSWindow *)window; 24 | 25 | - (void)paneWasAddedToWindow:(NSWindow *)window; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /PreferencesPane.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesPane.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 6/6/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "PreferencesPane.h" 10 | 11 | @implementation PreferencesPane 12 | 13 | - (id)init 14 | { 15 | return [self initWithNibName:NSStringFromClass([self class]) bundle:[NSBundle bundleForClass:[self class]]]; 16 | } 17 | 18 | #pragma mark - Properties 19 | 20 | - (NSString *)name 21 | { 22 | return NSStringFromClass([self class]); 23 | } 24 | 25 | - (NSImage *)icon 26 | { 27 | return [NSImage imageNamed:@"NSApplicationIcon"]; 28 | } 29 | 30 | #pragma mark - Adding/Removing 31 | 32 | - (void)paneWillBeRemovedFromWindow:(NSWindow *)window 33 | { 34 | } 35 | 36 | - (void)paneWasAddedToWindow:(NSWindow *)window 37 | { 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /PreferencesWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesWindow.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 1/21/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PreferencesPane.h" 11 | 12 | ///The window controller responsible for providing a preferences window for Player. 13 | @interface PreferencesWindow : NSWindowController 14 | { 15 | ///The content box used to display preferences. 16 | IBOutlet NSBox *oContentBox; 17 | 18 | ///The preference panes. 19 | NSDictionary *mPreferencesPanes; 20 | 21 | ///The selected pane 22 | PreferencesPane *mSelectedPane; 23 | } 24 | 25 | #pragma mark - Showing Specific Panes 26 | 27 | - (void)showGeneralPane; 28 | 29 | - (void)showArtModePane; 30 | 31 | - (void)showPlayKeysPane; 32 | 33 | - (void)showSocialPane; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /PreviousTrack_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PreviousTrack_Button.png -------------------------------------------------------------------------------- /PreviousTrack_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PreviousTrack_Button@2x.png -------------------------------------------------------------------------------- /PreviousTrack_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PreviousTrack_ButtonPressed.png -------------------------------------------------------------------------------- /PreviousTrack_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/PreviousTrack_ButtonPressed@2x.png -------------------------------------------------------------------------------- /QueueTableScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QueueTableScrollView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 7/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QueueTableScrollView : NSScrollView 12 | { 13 | ///The tracking area used to highlight rows. 14 | NSTrackingArea *mHoverTrackingArea; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QueueTableScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QueueTableScrollView.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 7/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "QueueTableScrollView.h" 10 | #import "QueueTableView.h" 11 | 12 | @implementation QueueTableScrollView 13 | 14 | - (void)viewDidMoveToWindow 15 | { 16 | [[self window] setAcceptsMouseMovedEvents:YES]; 17 | 18 | if(mHoverTrackingArea) 19 | { 20 | [self removeTrackingArea:mHoverTrackingArea]; 21 | mHoverTrackingArea = nil; 22 | } 23 | 24 | if([self window]) 25 | { 26 | mHoverTrackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect 27 | options:(NSTrackingAssumeInside | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect) 28 | owner:self 29 | userInfo:nil]; 30 | 31 | [self addTrackingArea:mHoverTrackingArea]; 32 | } 33 | } 34 | 35 | #pragma mark - 36 | 37 | - (void)mouseExited:(NSEvent *)event 38 | { 39 | QueueTableView *targetTableView = [self documentView]; 40 | targetTableView.hoveredUponRow = -1; 41 | } 42 | 43 | - (void)mouseMoved:(NSEvent *)event 44 | { 45 | NSPoint mouseLocation = [self convertPoint:[event locationInWindow] fromView:nil]; 46 | QueueTableView *targetTableView = [self documentView]; 47 | NSPoint mouseLocationInTableView = [targetTableView convertPoint:mouseLocation fromView:self]; 48 | 49 | targetTableView.hoveredUponRow = [targetTableView rowAtPoint:mouseLocationInTableView]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /QueueTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BrowserTableView.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 12/8/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol QueueTableViewDelegate; 12 | @class RKKeyDispatcher; 13 | 14 | ///The table view subclass used by Pinna for its play queue. 15 | @interface QueueTableView : NSTableView 16 | { 17 | /** State **/ 18 | 19 | NSInteger mHoveredUponRow; 20 | BOOL mHoverButtonIsClicked; 21 | 22 | 23 | /** Properties **/ 24 | NSColor *mAlternateBackgroundColor; 25 | RKKeyDispatcher *mKeyListener; 26 | } 27 | 28 | #pragma mark Properties 29 | 30 | ///The row currently hovered upon in the browser table view. 31 | /// 32 | ///Mutating this property causes a redraw of the table view. 33 | @property (nonatomic) NSInteger hoveredUponRow; 34 | 35 | @property (nonatomic, assign) id delegate; 36 | 37 | #pragma mark - 38 | 39 | ///The background color used for alternating rows. 40 | @property (nonatomic, copy) NSColor *alternateBackgroundColor; 41 | 42 | ///The key listener of the table view. 43 | @property (nonatomic, readonly) RKKeyDispatcher *keyListener; 44 | 45 | @end 46 | 47 | @protocol QueueTableViewDelegate 48 | @optional 49 | 50 | - (NSMenu *)tableView:(NSTableView *)tableView menuForRows:(NSIndexSet *)rows; 51 | 52 | - (NSImage *)tableView:(NSTableView *)tableView hoverButtonImageForRow:(NSInteger)row; 53 | 54 | - (NSImage *)tableView:(NSTableView *)tableView hoverButtonPressedImageForRow:(NSInteger)row; 55 | 56 | - (void)tableView:(NSTableView *)tableView hoverButtonWasClickedAtRow:(NSInteger)row; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /RKBrowserIconTextFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // This code is derived from RSVerticallyCenteredTextFieldCell and IconTextFieldCell. 3 | // 4 | // Copyright 2006 Red Sweater Software. All rights reserved. 5 | // Copyright 2008 Brian Amerige. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | ///The cell used by RKBrowser. 11 | @interface RKBrowserIconTextFieldCell : NSTextFieldCell 12 | { 13 | NSImage *mImage; 14 | BOOL mStylizesImage; 15 | CGFloat mImageInset; 16 | CGFloat mSpacingBetweenImageAndText; 17 | 18 | NSGradient *mBackgroundGradient; 19 | NSImage *mButtonImage; 20 | 21 | BOOL mIsEditingOrSelecting; 22 | } 23 | 24 | ///The image of the cell. 25 | @property (readwrite, retain) NSImage *image; 26 | 27 | ///Whether or not the image of the cell should be stylized. 28 | @property (nonatomic) BOOL stylizesImage; 29 | 30 | ///The left inset of the image. Default value 0.0. 31 | @property (nonatomic) CGFloat imageInset; 32 | 33 | ///The spacing between the cell's image and text. Default value 5.0. 34 | @property (nonatomic) CGFloat spacingBetweenImageAndText; 35 | 36 | #pragma mark - 37 | 38 | ///The background gradient of the cell. Used to indicate now playing in the queue. 39 | @property (nonatomic, copy) NSGradient *backgroundGradient; 40 | 41 | ///The button image of the cell. 42 | @property (retain) NSImage *buttonImage; 43 | 44 | @end -------------------------------------------------------------------------------- /RKBrowserLevelController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserLevelController.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 1/31/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RKBrowserTableView, RKBrowserLevel, RKBrowserView; 12 | 13 | @interface RKBrowserLevelController : NSViewController 14 | { 15 | RKBrowserLevel *mBrowserLevel; 16 | RKBrowserView *mBrowserView; 17 | 18 | IBOutlet RKBrowserTableView *oTableView; 19 | 20 | IBOutlet NSArrayController *oContentsController; 21 | } 22 | 23 | ///Initialize the receiver with a specified browser level. 24 | - (id)initWithBrowserLevel:(RKBrowserLevel *)browserLevel browserView:(RKBrowserView *)browserView; 25 | 26 | #pragma mark - Properties 27 | 28 | ///The selection indexes of the controller. 29 | @property (nonatomic, copy) NSIndexSet *selectionIndexes; 30 | 31 | ///The items selected in the browser level's array controller. 32 | @property (nonatomic, readonly) NSArray *selectedItems; 33 | 34 | ///The table view of the level controller. 35 | @property (nonatomic, readonly) RKBrowserTableView *tableView; 36 | 37 | ///The level of the controller. 38 | @property (nonatomic, readonly) RKBrowserLevel *browserLevel; 39 | 40 | #pragma mark - Visibility 41 | 42 | ///Invoked when the receiver is about to become visible in a browser view. 43 | - (void)controllerWillBecomeVisibleInBrowser:(RKBrowserView *)browserView; 44 | 45 | ///Invoked when the receiver has become visible in a browser view. 46 | - (void)controllerDidBecomeVisibleInBrowser:(RKBrowserView *)browserView; 47 | 48 | #pragma mark - 49 | 50 | ///Invoked when the receiver is about to be removed from a browser view. 51 | - (void)controllerWillBeRemovedFromBrowser:(RKBrowserView *)browserView; 52 | 53 | ///Invoked when the receiver has been removed from the browser view. 54 | - (void)controllerWasRemovedFromBrowser:(RKBrowserView *)browserView; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /RKBrowserLevelInternal.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserLevelInternal.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 2/12/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | ///The internal support methods for RKBrowserLevel 12 | @interface RKBrowserLevel () 13 | 14 | /// \ignore 15 | /// \see(-[RKBrowserLevel parentBrowser]) 16 | @property (nonatomic, readwrite) RKBrowserView *parentBrowser; 17 | 18 | #pragma mark - 19 | 20 | ///The cached previous browser level. 21 | @property (nonatomic) RKBrowserLevel *cachedPreviousLevel; 22 | 23 | ///The cached next browser level. 24 | @property (nonatomic) RKBrowserLevel *cachedNextLevel; 25 | 26 | ///Returns the deepest cached level, starting with the receiver. 27 | - (RKBrowserLevel *)deepestCachedLevel; 28 | 29 | ///Returns the shallowest level, starting with the receiver. 30 | - (RKBrowserLevel *)shallowestLevel; 31 | 32 | #pragma mark - 33 | 34 | ///The controller of the browser level. 35 | /// 36 | ///This property is lazily initialized. 37 | @property (nonatomic) RKBrowserLevelController *controller; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /RKBrowserScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserScrollView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/26/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | RK_EXTERN NSString *const RKBrowserScrollViewDidScrollToTopNotification; 12 | RK_EXTERN NSString *const RKBrowserScrollViewDidScrollToBottomNotification; 13 | 14 | @interface RKBrowserScrollView : NSScrollView 15 | { 16 | NSSize mDocumentViewSizeAtTimeOfLastBeginningNotification; 17 | NSSize mDocumentViewSizeAtTimeOfLastEndNotification; 18 | 19 | BOOL mHasSentBeginningNotification; 20 | BOOL mHasSentEndNotification; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /RKBrowserScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserScrollView.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/26/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserScrollView.h" 10 | 11 | NSString *const RKBrowserScrollViewDidScrollToTopNotification = @"RKBrowserScrollViewDidScrollToTopNotification"; 12 | NSString *const RKBrowserScrollViewDidScrollToBottomNotification = @"RKBrowserScrollViewDidScrollToBottomNotification"; 13 | 14 | @implementation RKBrowserScrollView 15 | 16 | - (void)reflectScrolledClipView:(NSClipView *)clipView 17 | { 18 | [super reflectScrolledClipView:clipView]; 19 | 20 | if([self verticalScroller].floatValue == 1.0) 21 | { 22 | if(!NSEqualSizes(mDocumentViewSizeAtTimeOfLastEndNotification, [[self documentView] frame].size)) 23 | { 24 | [[NSNotificationCenter defaultCenter] postNotificationName:RKBrowserScrollViewDidScrollToBottomNotification 25 | object:self]; 26 | mDocumentViewSizeAtTimeOfLastEndNotification = [[self documentView] frame].size; 27 | } 28 | } 29 | else if([self verticalScroller].floatValue == 0.0) 30 | { 31 | if(!!NSEqualSizes(mDocumentViewSizeAtTimeOfLastBeginningNotification, [[self documentView] frame].size)) 32 | { 33 | [[NSNotificationCenter defaultCenter] postNotificationName:RKBrowserScrollViewDidScrollToTopNotification 34 | object:self]; 35 | mDocumentViewSizeAtTimeOfLastBeginningNotification = [[self documentView] frame].size; 36 | } 37 | } 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /RKBrowserTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserTableView.h 3 | // NewBrowser 4 | // 5 | // Created by Kevin MacWhinnie on 1/31/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RKBrowserView; 12 | 13 | @protocol RKBrowserTableViewDelegate; 14 | 15 | @interface RKBrowserTableView : NSTableView 16 | { 17 | RKBrowserView *mBrowserView; 18 | 19 | NSInteger mHoveredUponRow; 20 | BOOL mHoverButtonIsClicked; 21 | 22 | NSColor *mAlternateBackgroundColor; 23 | } 24 | 25 | ///The browser view of the table view. 26 | @property (nonatomic) RKBrowserView *browserView; 27 | 28 | @property (nonatomic) id delegate; 29 | 30 | ///The row currently hovered upon in the browser table view. 31 | /// 32 | ///Mutating this property causes a redraw of the table view. 33 | @property (nonatomic) NSInteger hoveredUponRow; 34 | 35 | ///The alternate background color of the browser table view. 36 | @property (nonatomic) NSColor *alternateBackgroundColor; 37 | 38 | @end 39 | 40 | @protocol RKBrowserTableViewDelegate 41 | @required 42 | 43 | - (NSMenu *)tableView:(NSTableView *)tableView menuForRows:(NSIndexSet *)rows; 44 | 45 | - (NSImage *)tableView:(NSTableView *)tableView hoverButtonImageForRow:(NSInteger)row; 46 | 47 | - (NSImage *)tableView:(NSTableView *)tableView hoverButtonPressedImageForRow:(NSInteger)row; 48 | 49 | - (void)tableView:(NSTableView *)tableView hoverButtonWasClickedAtRow:(NSInteger)row; 50 | 51 | @end -------------------------------------------------------------------------------- /RKBrowserViewPrivate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBrowserViewPrivate.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/15/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserView.h" 10 | 11 | @interface RKBrowserView () 12 | 13 | #pragma mark Handling Keys 14 | 15 | - (BOOL)handleSpecialKeyPress:(RKBrowserSpecialKey)key InSubordinateTableView:(NSTableView *)tableView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RSVerticallyCenteredTextFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSVerticallyCenteredTextFieldCell.h 3 | // RSCommon 4 | // 5 | // Created by Daniel Jalkut on 6/17/06. 6 | // Copyright 2006 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface RSVerticallyCenteredTextFieldCell : NSTextFieldCell 13 | { 14 | BOOL mIsEditingOrSelecting; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RSVerticallyCenteredTextFieldCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSVerticallyCenteredTextField.m 3 | // RSCommon 4 | // 5 | // Created by Daniel Jalkut on 6/17/06. 6 | // Copyright 2006 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import "RSVerticallyCenteredTextFieldCell.h" 10 | 11 | @implementation RSVerticallyCenteredTextFieldCell 12 | 13 | - (NSRect)drawingRectForBounds:(NSRect)theRect 14 | { 15 | // Get the parent's idea of where we should draw 16 | NSRect newRect = [super drawingRectForBounds:theRect]; 17 | 18 | // When the text field is being 19 | // edited or selected, we have to turn off the magic because it screws up 20 | // the configuration of the field editor. We sneak around this by 21 | // intercepting selectWithFrame and editWithFrame and sneaking a 22 | // reduced, centered rect in at the last minute. 23 | if (mIsEditingOrSelecting == NO) 24 | { 25 | // Get our ideal size for current text 26 | NSSize textSize = [self cellSizeForBounds:theRect]; 27 | 28 | // Center that in the proposed rect 29 | float heightDelta = newRect.size.height - textSize.height; 30 | if (heightDelta > 0) 31 | { 32 | newRect.size.height -= heightDelta; 33 | newRect.origin.y += (heightDelta / 2); 34 | } 35 | } 36 | 37 | return newRect; 38 | } 39 | 40 | - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength 41 | { 42 | aRect = [self drawingRectForBounds:aRect]; 43 | mIsEditingOrSelecting = YES; 44 | [super selectWithFrame:aRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength]; 45 | mIsEditingOrSelecting = NO; 46 | } 47 | 48 | - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent 49 | { 50 | aRect = [self drawingRectForBounds:aRect]; 51 | mIsEditingOrSelecting = YES; 52 | [super editWithFrame:aRect inView:controlView editor:textObj delegate:anObject event:theEvent]; 53 | mIsEditingOrSelecting = NO; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /RoundaboutKitMac/NSBezierPath+MCAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+MCAdditions.h 3 | // 4 | // Created by Sean Patrick O'Brien on 4/1/08. 5 | // Copyright 2008 MolokoCacao. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | #pragma once 11 | 12 | ///The struct used to describe corner radii for a bezier path. 13 | typedef struct NSBezierPathCornerRadii { 14 | 15 | CGFloat topLeft; 16 | CGFloat topRight; 17 | CGFloat bottomLeft; 18 | CGFloat bottomRight; 19 | 20 | } NSBezierPathCornerRadii; 21 | 22 | RK_INLINE NSBezierPathCornerRadii NSBezierPathCornerRadiiMake(CGFloat topLeft, CGFloat topRight, CGFloat bottomLeft, CGFloat bottomRight) 23 | { 24 | return (NSBezierPathCornerRadii){ 25 | .topLeft = topLeft, 26 | .topRight = topRight, 27 | .bottomLeft = bottomLeft, 28 | .bottomRight = bottomRight, 29 | }; 30 | } 31 | 32 | @interface NSBezierPath (MCAdditions) 33 | 34 | + (NSBezierPath *)bezierPathWithRect:(NSRect)rect cornerRadii:(NSBezierPathCornerRadii)cornerRadii; 35 | 36 | + (NSBezierPath *)bezierPathWithCGPath:(CGPathRef)pathRef; 37 | - (CGPathRef)cgPath; 38 | 39 | - (NSBezierPath *)pathWithStrokeWidth:(CGFloat)strokeWidth; 40 | 41 | - (void)fillWithInnerShadow:(NSShadow *)shadow; 42 | - (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius; 43 | 44 | - (void)strokeInside; 45 | - (void)strokeInsideWithinRect:(NSRect)clipRect; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKBarButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBarButtonCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/7/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RKBarButtonCell.h" 11 | 12 | ///The RKBarButton class is a subclass of NSButton used by RKNavigationItem 13 | ///instances to present navigation options to the user. 14 | /// 15 | ///Changing the title of image of a bar button will cause it to update its metrics. 16 | @interface RKBarButton : NSButton 17 | 18 | ///Initialize the receiver with a given button type and basic parameters. 19 | - (id)initWithType:(RKBarButtonType)type 20 | title:(NSString *)title 21 | target:(id)target 22 | action:(SEL)action; 23 | 24 | #pragma mark - Properties 25 | 26 | ///The type of the button. 27 | @property (nonatomic) RKBarButtonType buttonType; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKBarButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKBarButtonCell.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/7/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBarButton.h" 10 | 11 | @implementation RKBarButton 12 | 13 | - (id)initWithType:(RKBarButtonType)type title:(NSString *)title target:(id)target action:(SEL)action 14 | { 15 | if((self = [super initWithFrame:NSZeroRect])) { 16 | RKBarButtonCell *cell = [[RKBarButtonCell alloc] initWithType:type title:title]; 17 | [self setCell:cell]; 18 | [self setTarget:target]; 19 | [self setAction:action]; 20 | 21 | [self sizeToFit]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - Properties 28 | 29 | - (void)setButtonType:(RKBarButtonType)buttonType 30 | { 31 | [(RKBarButtonCell *)[self cell] setButtonType:buttonType]; 32 | 33 | [self sizeToFit]; 34 | } 35 | 36 | - (RKBarButtonType)buttonType 37 | { 38 | return [(RKBarButtonCell *)[self cell] buttonType]; 39 | } 40 | 41 | - (void)setTitle:(NSString *)aString 42 | { 43 | [super setTitle:aString]; 44 | 45 | [self sizeToFit]; 46 | } 47 | 48 | - (void)setImage:(NSImage *)image 49 | { 50 | [super setImage:image]; 51 | 52 | [self sizeToFit]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKBarButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKBarButtonCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/7/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The different types of bar buttons. 12 | typedef enum : NSUInteger { 13 | 14 | ///The default rounded type. 15 | kRKBarButtonTypeDefault = 0, 16 | 17 | ///The back button with an arrow on its left side. 18 | kRKBarButtonTypeBackButton = 1, 19 | 20 | } RKBarButtonType; 21 | 22 | ///The RKBarButtonCell implements the display/sizing logic for the RKBarButton class. 23 | @interface RKBarButtonCell : NSButtonCell 24 | 25 | ///Initialize the receiver with a given bar button type. 26 | - (RKBarButtonCell *)initWithType:(RKBarButtonType)type title:(NSString *)title; 27 | 28 | #pragma mark - Properties 29 | 30 | ///The type of the button. 31 | @property (nonatomic) RKBarButtonType buttonType; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKKeyDispatcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKKeyDispatcher.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/12/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The block type used as a callback for RKKeyDispatcher. 12 | typedef BOOL(^RKKeyDispatcherHandler)(NSUInteger pressedModifiers); 13 | 14 | ///The key listener class provides an object for dispatching specific key presses 15 | ///to different blocks. Used by BKBorderlessWindow to implement key event handling. 16 | @interface RKKeyDispatcher : NSObject 17 | { 18 | NSMutableDictionary *mHandlers; 19 | } 20 | 21 | ///Sets the block for a specified key code. 22 | /// \param keyCode The key code to listen for. 23 | /// \param block The block to invoke to try to handle the key combo. \see(RKKeyDispatcherBlock). 24 | - (void)setHandlerForKeyCode:(unichar)keyCode block:(RKKeyDispatcherHandler)block; 25 | 26 | ///Removes the handler for a specified key code. 27 | - (void)removeHandlerForKeyCode:(unichar)keyCode; 28 | 29 | ///Returns the block for a specified key code. 30 | - (RKKeyDispatcherHandler)handlerForKeyCode:(unichar)keyCode; 31 | 32 | ///Try to handle a specified key code with specified modifier keys. 33 | /// 34 | /// \param keyCode The key code to handle. 35 | /// \param modifiers The pressed modifier keys. 36 | - (BOOL)dispatchKey:(unichar)keyCode withModifiers:(NSUInteger)modifiers; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKKeyDispatcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKKeyDispatcher.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/12/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKKeyDispatcher.h" 10 | 11 | @implementation RKKeyDispatcher 12 | 13 | - (id)init 14 | { 15 | if((self = [super init])) 16 | { 17 | mHandlers = [NSMutableDictionary new]; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | - (void)setHandlerForKeyCode:(unichar)keyCode block:(RKKeyDispatcherHandler)block 24 | { 25 | NSParameterAssert(block); 26 | 27 | @synchronized(mHandlers) 28 | { 29 | [mHandlers setObject:[block copy] forKey:[NSNumber numberWithLong:keyCode]]; 30 | } 31 | } 32 | 33 | - (void)removeHandlerForKeyCode:(unichar)keyCode 34 | { 35 | @synchronized(mHandlers) 36 | { 37 | [mHandlers removeObjectForKey:[NSNumber numberWithLong:keyCode]]; 38 | } 39 | } 40 | 41 | - (RKKeyDispatcherHandler)handlerForKeyCode:(unichar)keyCode 42 | { 43 | @synchronized(mHandlers) 44 | { 45 | return [mHandlers objectForKey:[NSNumber numberWithLong:keyCode]]; 46 | } 47 | } 48 | 49 | - (BOOL)dispatchKey:(unichar)keyCode withModifiers:(NSUInteger)modifiers 50 | { 51 | @synchronized(mHandlers) 52 | { 53 | RKKeyDispatcherHandler block = [self handlerForKeyCode:keyCode]; 54 | if(block) 55 | return block(modifiers); 56 | } 57 | 58 | return NO; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKNavigationBar.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/6/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RKNavigationItem.h" 11 | #import "RKChromeView.h" 12 | 13 | ///The RKNavigationBar class implements a control for navigating hierarchical content. 14 | @interface RKNavigationBar : RKChromeView 15 | 16 | #pragma mark - Properties 17 | 18 | ///The navigation items of the bar. 19 | @property (nonatomic, copy, readonly) NSArray *navigationItems; 20 | 21 | ///The item at the top of the navigation bar's stack. 22 | @property (nonatomic, readonly) RKNavigationItem *topNavigationItem; 23 | 24 | ///The item currently visible to the user. 25 | @property (nonatomic, readonly) RKNavigationItem *visibleNavigationItem; 26 | 27 | #pragma mark - Pushing and Popping Items 28 | 29 | ///Pushes the given navigation item onto the receiver’s stack and updates the navigation bar. 30 | - (void)pushNavigationItem:(RKNavigationItem *)navigationItem animated:(BOOL)animated; 31 | 32 | ///Pops the top item from the receiver’s stack and updates the navigation bar. 33 | - (void)popNavigationItemAnimated:(BOOL)animated; 34 | 35 | ///Pops navigation items until the specified navigation item is at the top of the navigation stack. 36 | - (void)popToNavigationItem:(RKNavigationItem *)navigationItem animated:(BOOL)animated; 37 | 38 | ///Pops all the navigation on the stack except the top most. 39 | - (void)popToRootNavigationItemAnimated:(BOOL)animated; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKNavigationItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKNavigationItem.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/6/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RKBarButton.h" 11 | 12 | ///The RKNavigationItem encapsulates information about a navigation item pushed onto an RKNavigationBar's stack. 13 | /// 14 | ///By default a navigation item has no left or right button and has a borderless NSTextField as its title view. 15 | @interface RKNavigationItem : NSView 16 | 17 | #pragma mark - Properties 18 | 19 | ///The title of the navigation item. 20 | /// 21 | ///This property does nothing if the title view is not an NSTextField instance (default). 22 | @property (nonatomic, copy) NSString *title; 23 | 24 | #pragma mark - Views 25 | 26 | ///The left button of the navigation item. 27 | @property (nonatomic) NSView *leftView; 28 | 29 | ///The title view of the navigation item. 30 | @property (nonatomic) NSView *titleView; 31 | 32 | ///The right button of the navigation item. 33 | @property (nonatomic) NSView *rightView; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKSandboxTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKSandboxTools.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 10/17/12. 6 | // 7 | // 8 | 9 | #ifndef RKSandboxTools_h 10 | #define RKSandboxTools_h 1 11 | 12 | #pragma mark Paths and Sandboxing 13 | 14 | ///Returns the real world location of the user's home directory. 15 | RK_EXTERN NSString *RKGetRealUserDirectoryPath(); 16 | 17 | ///Returns the sandboxed location of the user's "home directory". 18 | RK_EXTERN NSString *RKGetSandboxUserDirectoryPath(); 19 | 20 | #pragma mark - 21 | 22 | ///Returns a BOOL indicating whether or not a given location is within the app's sandbox. 23 | RK_EXTERN BOOL RKIsLocationWithinSandbox(NSURL *location); 24 | 25 | ///Returns a URL resolved to point to within the app's sandbox. 26 | RK_EXTERN NSURL *RKResolveLocationInSandbox(NSURL *location); 27 | 28 | #endif /* RKSandboxTools_h */ -------------------------------------------------------------------------------- /RoundaboutKitMac/RKSideSheetView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKNavigationOverlayView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/7/13. 6 | // 7 | // 8 | 9 | #import "RKView.h" 10 | 11 | @class RKNavigationController; 12 | 13 | ///The RKSideSheetView class encapsulates a sheet-style view which is displayed 14 | ///over a specified content view. The sheet's contents are shown to the right of 15 | ///the view over a semi-translucent white background. 16 | /// 17 | ///Content is specified by modifying the side sheet's navigation controller. 18 | @interface RKSideSheetView : RKView 19 | 20 | ///The navigation controller the overlay manages. 21 | @property (nonatomic, readonly) RKNavigationController *navigationController; 22 | 23 | #pragma mark - 24 | 25 | ///The view displayed behind the sheet's content view. 26 | @property (nonatomic) RKView *backgroundView; 27 | 28 | #pragma mark - 29 | 30 | ///The width of the content. 31 | /// 32 | ///Defaults to 320 points. 33 | @property (nonatomic) CGFloat contentWidth; 34 | 35 | ///The block to invoke when the sheet is dismissed. 36 | @property (nonatomic, copy) void(^dismissalHandler)(RKSideSheetView *sheet); 37 | 38 | #pragma mark - Showing/Hiding The Overlay 39 | 40 | ///Shows the overlay in a specified view. 41 | - (void)showInView:(NSView *)view animated:(BOOL)animated completionHandler:(dispatch_block_t)completionHandler; 42 | 43 | ///Dismisses the overlay. 44 | - (void)dismiss:(BOOL)animated completionHandler:(dispatch_block_t)completionHandler; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKTitleBarButtonsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BKWindowTitleBarButtonsView.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 1/23/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The RKTitleBarButtonsView class is used to provide the titlebar (x|-|+) buttons for the RKBorderlessWindow class. 12 | @interface RKTitleBarButtonsView : NSView 13 | { 14 | NSWindow *mOldWindow; 15 | 16 | NSTrackingRectTag mTrackingArea; 17 | BOOL mIsRolloverActive; 18 | NSButton *mCloseButton; 19 | NSButton *mMinimizeButton; 20 | NSButton *mZoomButton; 21 | } 22 | 23 | ///Returns the preferred size of the button view. 24 | + (NSSize)preferredSize; 25 | 26 | ///Returns the preferred frame of an instance of BKWindowTitleBarButtonsView. 27 | + (NSRect)preferredFrameInContentView:(NSView *)contentView; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKView.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | ///The RKView class is a layer-backed subclas of NSView 12 | ///that adds several convenient methods from UIView. 13 | @interface RKView : NSView 14 | 15 | ///The background color of the view. 16 | @property (nonatomic) NSColor *backgroundColor; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKView.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/8/13. 6 | // 7 | // 8 | 9 | #import "RKView.h" 10 | 11 | @implementation RKView 12 | 13 | - (id)initWithFrame:(NSRect)frame 14 | { 15 | if ((self = [super initWithFrame:frame])) { 16 | self.wantsLayer = YES; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | #pragma mark - Drawing 23 | 24 | - (void)drawRect:(NSRect)dirtyRect 25 | { 26 | [_backgroundColor set]; 27 | NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); 28 | } 29 | 30 | #pragma mark - Properties 31 | 32 | - (void)setBackgroundColor:(NSColor *)backgroundColor 33 | { 34 | _backgroundColor = backgroundColor; 35 | 36 | [self setNeedsDisplay:YES]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RKViewController_Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController_Private.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/6/12. 6 | // Copyright (c) 2013 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKViewController.h" 10 | 11 | @interface RKViewController () 12 | 13 | @property (nonatomic, readwrite) BOOL isViewLoaded; 14 | @property (nonatomic, readwrite, unsafe_unretained) RKNavigationController *navigationController; 15 | @property (nonatomic, readwrite) RKViewController *parentViewController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RoundaboutKitMac/RoundaboutKitMac.h: -------------------------------------------------------------------------------- 1 | // 2 | // RoundaboutKitMac.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 5/7/13. 6 | // 7 | // 8 | 9 | #ifndef Pinna_RoundaboutKitMacTools_h 10 | #define Pinna_RoundaboutKitMacTools_h 11 | 12 | #import "RKMacPrelude.h" 13 | #import 14 | #import "NSBezierPath+MCAdditions.h" 15 | 16 | #import "RKAnimator.h" 17 | #import "RKBorderlessWindow.h" 18 | #import "RKTitleBarButtonsView.h" 19 | #import "RKChromeView.h" 20 | 21 | #import "RKView.h" 22 | #import "RKViewController.h" 23 | #import "RKNavigationController.h" 24 | #import "RKNavigationBar.h" 25 | #import "RKBarButton.h" 26 | 27 | #endif /* Pinna_RoundaboutKitMacTools_h */ 28 | -------------------------------------------------------------------------------- /RoundaboutKit_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'BeyondKit' target in the 'BeyondKit' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import "BeyondKitDefines.h" 8 | #endif 9 | -------------------------------------------------------------------------------- /SRKeyCodeTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRKeyCodeTransformer.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRKeyCodeTransformer : NSValueTransformer {} @end 17 | -------------------------------------------------------------------------------- /SRRecorderControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderControl.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import "SRRecorderCell.h" 16 | 17 | @interface SRRecorderControl : NSControl 18 | { 19 | IBOutlet id delegate; 20 | } 21 | 22 | #pragma mark *** Aesthetics *** 23 | - (BOOL)animates; 24 | - (void)setAnimates:(BOOL)an; 25 | - (SRRecorderStyle)style; 26 | - (void)setStyle:(SRRecorderStyle)nStyle; 27 | 28 | #pragma mark *** Delegate *** 29 | - (id)delegate; 30 | - (void)setDelegate:(id)aDelegate; 31 | 32 | #pragma mark *** Key Combination Control *** 33 | 34 | - (NSUInteger)allowedFlags; 35 | - (void)setAllowedFlags:(NSUInteger)flags; 36 | 37 | - (BOOL)allowsKeyOnly; 38 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord; 39 | - (BOOL)escapeKeysRecord; 40 | 41 | - (BOOL)canCaptureGlobalHotKeys; 42 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState; 43 | 44 | - (NSUInteger)requiredFlags; 45 | - (void)setRequiredFlags:(NSUInteger)flags; 46 | 47 | - (KeyCombo)keyCombo; 48 | - (void)setKeyCombo:(KeyCombo)aKeyCombo; 49 | 50 | - (NSString *)keyChars; 51 | - (NSString *)keyCharsIgnoringModifiers; 52 | 53 | #pragma mark *** Autosave Control *** 54 | 55 | - (NSString *)autosaveName; 56 | - (void)setAutosaveName:(NSString *)aName; 57 | 58 | #pragma mark - 59 | 60 | // Returns the displayed key combination if set 61 | - (NSString *)keyComboString; 62 | 63 | #pragma mark *** Conversion Methods *** 64 | 65 | - (NSUInteger)cocoaToCarbonFlags:(NSUInteger)cocoaFlags; 66 | - (NSUInteger)carbonToCocoaFlags:(NSUInteger)carbonFlags; 67 | 68 | #pragma mark *** Binding Methods *** 69 | 70 | - (NSDictionary *)objectValue; 71 | - (void)setObjectValue:(NSDictionary *)shortcut; 72 | 73 | @end 74 | 75 | // Delegate Methods 76 | @interface NSObject (SRRecorderDelegate) 77 | - (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 78 | - (void)shortcutRecorder:(SRRecorderControl *)aRecorder keyComboDidChange:(KeyCombo)newKeyCombo; 79 | @end 80 | -------------------------------------------------------------------------------- /SRValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRValidator.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRValidator : NSObject { 17 | id delegate; 18 | } 19 | 20 | - (id) initWithDelegate:(id)theDelegate; 21 | 22 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags error:(NSError **)error; 23 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlags:(NSUInteger)flags takenInMenu:(NSMenu *)menu error:(NSError **)error; 24 | 25 | - (id) delegate; 26 | - (void) setDelegate: (id) theDelegate; 27 | 28 | @end 29 | 30 | #pragma mark - 31 | 32 | @interface NSObject( SRValidation ) 33 | - (BOOL) shortcutValidator:(SRValidator *)validator isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 34 | @end 35 | -------------------------------------------------------------------------------- /SafeButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // SafeButton.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 11/11/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | ///This subclass of NSButton does not accept first mouse. 12 | @interface SafeButton : NSButton 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /SafeButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // SafeButton.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 11/11/12. 6 | // 7 | // 8 | 9 | #import "SafeButton.h" 10 | 11 | @implementation SafeButton 12 | 13 | - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 14 | { 15 | return NO; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ScrubbingBarBackground_Fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_Fill.png -------------------------------------------------------------------------------- /ScrubbingBarBackground_Fill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_Fill@2x.png -------------------------------------------------------------------------------- /ScrubbingBarBackground_LeftCap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_LeftCap.png -------------------------------------------------------------------------------- /ScrubbingBarBackground_LeftCap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_LeftCap@2x.png -------------------------------------------------------------------------------- /ScrubbingBarBackground_RightCap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_RightCap.png -------------------------------------------------------------------------------- /ScrubbingBarBackground_RightCap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarBackground_RightCap@2x.png -------------------------------------------------------------------------------- /ScrubbingBarDial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarDial.png -------------------------------------------------------------------------------- /ScrubbingBarDial@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarDial@2x.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_Fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_Fill.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_Fill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_Fill@2x.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_LeftCap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_LeftCap.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_LeftCap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_LeftCap@2x.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_RightCap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_RightCap.png -------------------------------------------------------------------------------- /ScrubbingBarKnob_RightCap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarKnob_RightCap@2x.png -------------------------------------------------------------------------------- /ScrubbingBarStrike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarStrike.png -------------------------------------------------------------------------------- /ScrubbingBarStrike@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ScrubbingBarStrike@2x.png -------------------------------------------------------------------------------- /ScrubbingBarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ScrubbingBarView.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 1/21/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The scrubbing bar view provides the interface for moving within songs in Pinna's UI. 12 | @interface ScrubbingBarView : NSView 13 | { 14 | /** Internal State **/ 15 | 16 | CGFloat mTimeStampWidth; 17 | NSString *mTimeStampDisplayString; 18 | NSSize mTimeStampDisplayStringSize; 19 | 20 | /** Properties **/ 21 | 22 | NSTimeInterval mDuration; 23 | NSTimeInterval mCurrentTime; 24 | dispatch_block_t mAction; 25 | BOOL mUseTimeRemainingDisplayStyle; 26 | } 27 | 28 | #pragma mark Properties 29 | 30 | ///The duration. 31 | @property (nonatomic) NSTimeInterval duration; 32 | 33 | ///The current time. 34 | @property (nonatomic) NSTimeInterval currentTime; 35 | 36 | #pragma mark - 37 | 38 | ///Whether or not the scrubbing bar should display 39 | ///remaining time in its time stamp area. 40 | @property (nonatomic) BOOL useTimeRemainingDisplayStyle; 41 | 42 | #pragma mark - 43 | 44 | ///The action block. 45 | @property (nonatomic, copy) dispatch_block_t action; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /SearchBarButtonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchBarButtonCell.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/15/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SearchBarButtonCell : NSButtonCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SearchBarButtonCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchBarButtonCell.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/15/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "SearchBarButtonCell.h" 10 | 11 | @implementation SearchBarButtonCell 12 | 13 | - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView 14 | { 15 | if([self isHighlighted]) 16 | { 17 | [[NSColor colorWithDeviceWhite:0.0 alpha:0.05] set]; 18 | [NSBezierPath fillRect:NSMakeRect(NSMinX(frame), NSMinY(frame), NSWidth(frame) - 2.0, NSHeight(frame))]; 19 | } 20 | 21 | [[NSColor colorWithDeviceWhite:0.0 alpha:0.25] set]; 22 | [NSBezierPath fillRect:NSMakeRect(NSMaxX(frame) - 2.0, NSMinY(frame), 1.0, NSHeight(frame))]; 23 | [[NSColor colorWithDeviceWhite:1.0 alpha:0.45] set]; 24 | [NSBezierPath fillRect:NSMakeRect(NSMaxX(frame) - 1.0, NSMinY(frame), 1.0, NSHeight(frame))]; 25 | } 26 | 27 | - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 28 | { 29 | cellFrame.size.height -= 3.0; 30 | cellFrame.size.width -= 2.0; 31 | cellFrame.origin.y += 3.0; 32 | [super drawInteriorWithFrame:cellFrame inView:controlView]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /SearchBarDivider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/SearchBarDivider.png -------------------------------------------------------------------------------- /ShadowedTextFieldCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BKShadowedTextFieldCell.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/20/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ShadowedTextFieldCell : NSTextFieldCell 12 | { 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ShadowedTextFieldCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // BKShadowedTextFieldCell.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 3/20/11. 6 | // Copyright 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "ShadowedTextFieldCell.h" 10 | 11 | @implementation ShadowedTextFieldCell 12 | 13 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 14 | { 15 | NSShadow *shadow = [NSShadow new]; 16 | [shadow setShadowColor:[NSColor colorWithDeviceWhite:0.0 alpha:0.55]]; 17 | [shadow setShadowBlurRadius:1.0]; 18 | [shadow setShadowOffset:NSMakeSize(0.0, -1.0)]; 19 | 20 | [NSGraphicsContext saveGraphicsState]; 21 | [shadow set]; 22 | 23 | [super drawWithFrame:cellFrame inView:controlView]; 24 | 25 | [NSGraphicsContext restoreGraphicsState]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Share_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Share_Button.png -------------------------------------------------------------------------------- /Share_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Share_Button@2x.png -------------------------------------------------------------------------------- /Share_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Share_ButtonPressed.png -------------------------------------------------------------------------------- /Share_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Share_ButtonPressed@2x.png -------------------------------------------------------------------------------- /ShuffleOff_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOff_Button.png -------------------------------------------------------------------------------- /ShuffleOff_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOff_Button@2x.png -------------------------------------------------------------------------------- /ShuffleOff_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOff_ButtonPressed.png -------------------------------------------------------------------------------- /ShuffleOff_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOff_ButtonPressed@2x.png -------------------------------------------------------------------------------- /ShuffleOn_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOn_Button.png -------------------------------------------------------------------------------- /ShuffleOn_Button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOn_Button@2x.png -------------------------------------------------------------------------------- /ShuffleOn_ButtonPressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOn_ButtonPressed.png -------------------------------------------------------------------------------- /ShuffleOn_ButtonPressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/ShuffleOn_ButtonPressed@2x.png -------------------------------------------------------------------------------- /SimpleNumberTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleNumberTransformer.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 1/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SimpleNumberTransformer : NSValueTransformer 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SimpleNumberTransformer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleNumberTransformer.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 1/4/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "SimpleNumberTransformer.h" 10 | 11 | @implementation SimpleNumberTransformer 12 | 13 | + (Class)transformedValueClass 14 | { 15 | return [NSString class]; 16 | } 17 | 18 | + (BOOL)allowsReverseTransformation 19 | { 20 | return NO; 21 | } 22 | 23 | - (id)transformedValue:(id)value 24 | { 25 | return [NSNumberFormatter localizedStringFromNumber:[NSNumber numberWithInteger:[value integerValue]] 26 | numberStyle:NSNumberFormatterDecimalStyle]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SocialIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/SocialIcon.png -------------------------------------------------------------------------------- /SongQueryPromise.h: -------------------------------------------------------------------------------- 1 | // 2 | // SongQueryPromise.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 10/3/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class Library; 12 | 13 | ///The key used for errors from a song query promise that will contain the searched-for songs name. 14 | RK_EXTERN NSString *const SongQueryPromiseSongNameErrorKey; 15 | 16 | ///The key used for errors from a song query promise that will contain the searched-for songs artist. 17 | RK_EXTERN NSString *const SongQueryPromiseSongArtistErrorKey; 18 | 19 | ///The SongQueryPromise object represents a promise that can yield a local or remote 20 | ///song with a given artist and name. Used for matching songs from external sources. 21 | @interface SongQueryPromise : RKPromise 22 | { 23 | Library *mLibrary; 24 | 25 | NSString *mName; 26 | NSString *mArtist; 27 | } 28 | 29 | ///Initialize the receiver with the external identifier of a song. 30 | - (id)initWithIdentifier:(NSString *)identifier; 31 | 32 | ///Initialize the receiver with a given name and artist. 33 | /// 34 | /// \param name Required. 35 | /// \param artist Required. 36 | /// 37 | ///This is the designated initializer of the SongQueryPromise class. 38 | - (id)initWithName:(NSString *)name artist:(NSString *)artist; 39 | 40 | #pragma mark - Properties 41 | 42 | ///The name of the song. 43 | @property (copy, readonly) NSString *name; 44 | 45 | ///The artist of the song. 46 | @property (copy, readonly) NSString *artist; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Songs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Songs.png -------------------------------------------------------------------------------- /Songs@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/Songs@2x.png -------------------------------------------------------------------------------- /SongsBrowserLevel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SongsBrowserLevel.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 4/1/12. 6 | // Copyright (c) 2012 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import "RKBrowserLevel.h" 10 | 11 | @class Library; 12 | 13 | @interface SongsBrowserLevel : RKBrowserLevel 14 | { 15 | Library *mLibrary; 16 | 17 | BOOL mIsValid; 18 | BOOL mIsObservingPlaylistChanges; 19 | BOOL mShowsArtwork; 20 | id mParent; 21 | NSPredicate *mFetchPredicate; 22 | } 23 | 24 | #pragma mark Properties 25 | 26 | ///The parent whose content we are to display. 27 | /// 28 | ///This property may be set to an Artist, Album, or Playlist. 29 | @property (nonatomic) id parent; 30 | 31 | ///Whether or not the browser shows artwork. 32 | @property (nonatomic) BOOL showsArtwork; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TimeValueTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TimeStringValueTransformer.h 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 4/2/08. 6 | // Copyright 2008 Roundabout Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///Transform a string from [hh:]mm:ss format to seconds and back. 12 | @interface TimeValueTransformer : NSValueTransformer 13 | { 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /TimeValueTransformer.m: -------------------------------------------------------------------------------- 1 | // 2 | // TimeStringValueTransformer.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 4/2/08. 6 | // Copyright 2008 Roundabout Software. All rights reserved. 7 | // 8 | 9 | #import "TimeValueTransformer.h" 10 | 11 | @implementation TimeValueTransformer 12 | 13 | + (Class)transformedValueClass 14 | { 15 | return [NSString class]; 16 | } 17 | 18 | + (BOOL)allowsReverseTransformation 19 | { 20 | return YES; 21 | } 22 | 23 | - (id)transformedValue:(id)value 24 | { 25 | if(!value) 26 | return nil; 27 | 28 | NSInteger total = [value integerValue]; 29 | 30 | NSInteger hours = (total / (60 * 60)) % 24; 31 | NSInteger minutes = (total / 60) % 60; 32 | NSInteger seconds = total % 60; 33 | if(hours > 0) 34 | return [NSString stringWithFormat:@"%ld:%02ld:%02ld", hours, minutes, seconds]; 35 | 36 | return [NSString stringWithFormat:@"%ld:%02ld", minutes, seconds]; 37 | } 38 | 39 | - (id)reverseTransformedValue:(id)value 40 | { 41 | if(!value) 42 | return nil; 43 | 44 | NSArray *components = [value componentsSeparatedByString:@":"]; 45 | switch ([components count]) 46 | { 47 | case 3: /* hh:mm:ss */ 48 | { 49 | NSInteger hours = [[components objectAtIndex:0] integerValue]; 50 | NSInteger minutes = [[components objectAtIndex:1] integerValue]; 51 | NSInteger seconds = [[components objectAtIndex:2] integerValue]; 52 | 53 | return [NSNumber numberWithInteger:(hours * (60 * 60)) + (minutes * 60) + seconds]; 54 | } 55 | 56 | case 2: /* mm:ss */ 57 | { 58 | NSInteger minutes = [[components objectAtIndex:0] integerValue]; 59 | NSInteger seconds = [[components objectAtIndex:1] integerValue]; 60 | 61 | return [NSNumber numberWithInteger:(minutes * 60) + seconds]; 62 | } 63 | 64 | case 1: /* ss */ 65 | { 66 | NSInteger seconds = [[components objectAtIndex:0] integerValue]; 67 | 68 | return [NSNumber numberWithInteger:seconds]; 69 | } 70 | 71 | default: 72 | break; 73 | } 74 | 75 | return @"0"; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /TrendingScroller.h: -------------------------------------------------------------------------------- 1 | // 2 | // TrendingScroller.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/16/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface TrendingScroller : NSScroller 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TrendingScroller.m: -------------------------------------------------------------------------------- 1 | // 2 | // TrendingScroller.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/16/12. 6 | // 7 | // 8 | 9 | #import "TrendingScroller.h" 10 | 11 | static NSGradient *BackgroundGradient = nil; 12 | static NSGradient *KnobGradient = nil; 13 | 14 | @implementation TrendingScroller 15 | 16 | + (void)initialize 17 | { 18 | static dispatch_once_t onceToken; 19 | dispatch_once(&onceToken, ^{ 20 | BackgroundGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedRed:0.16 green:0.16 blue:0.16 alpha:1.00] 21 | endingColor:[NSColor colorWithCalibratedRed:0.14 green:0.14 blue:0.14 alpha:1.00]]; 22 | KnobGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedRed:0.82 green:0.82 blue:0.82 alpha:1.00] 23 | endingColor:[NSColor colorWithCalibratedRed:0.55 green:0.55 blue:0.55 alpha:1.00]]; 24 | }); 25 | 26 | [super initialize]; 27 | } 28 | 29 | + (BOOL)isCompatibleWithOverlayScrollers 30 | { 31 | return (self == [TrendingScroller class]); 32 | } 33 | 34 | #pragma mark - Drawing 35 | 36 | - (void)drawKnobSlotInRect:(NSRect)slotRect highlight:(BOOL)flag 37 | { 38 | if([self scrollerStyle] == NSScrollerStyleOverlay) 39 | { 40 | [super drawKnobSlotInRect:slotRect highlight:flag]; 41 | return; 42 | } 43 | 44 | NSBezierPath *backgroundPath = [NSBezierPath bezierPathWithRect:slotRect 45 | cornerRadii:NSBezierPathCornerRadiiMake(0.0, 5.0, 0.0, 0.0)]; 46 | [BackgroundGradient drawInBezierPath:backgroundPath angle:0.0]; 47 | 48 | NSRect lineRect = NSMakeRect(NSMinX(slotRect), NSMinY(slotRect), 1.0, NSHeight(slotRect)); 49 | [[NSColor blackColor] set]; 50 | [NSBezierPath fillRect:lineRect]; 51 | } 52 | 53 | - (void)drawKnob 54 | { 55 | if([self scrollerStyle] == NSScrollerStyleOverlay) 56 | { 57 | [super drawKnob]; 58 | return; 59 | } 60 | 61 | NSRect knobRect = NSInsetRect([self rectForPart:NSScrollerKnob], 2.0, 2.0); 62 | knobRect.origin.x += 1.0; 63 | knobRect.size.width -= 1.0; 64 | NSBezierPath *knobPath = [NSBezierPath bezierPathWithRoundedRect:knobRect 65 | xRadius:round(NSWidth(knobRect) / 2.0) 66 | yRadius:round(NSWidth(knobRect) / 2.0)]; 67 | [KnobGradient drawInBezierPath:knobPath angle:0.0]; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /UppercaseStringTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // UppercaseStringTransformer.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/15/12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface UppercaseStringTransformer : NSValueTransformer 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /UppercaseStringTransformer.m: -------------------------------------------------------------------------------- 1 | // 2 | // UppercaseStringTransformer.m 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 9/15/12. 6 | // 7 | // 8 | 9 | #import "UppercaseStringTransformer.h" 10 | 11 | @implementation UppercaseStringTransformer 12 | 13 | + (Class)transformedValueClass 14 | { 15 | return [NSString class]; 16 | } 17 | 18 | + (BOOL)allowsReverseTransformation 19 | { 20 | return NO; 21 | } 22 | 23 | - (id)transformedValue:(id)value 24 | { 25 | //For 10.8+ 26 | if([value respondsToSelector:@selector(uppercaseStringWithLocale:)]) 27 | return [value uppercaseStringWithLocale:nil]; 28 | 29 | return [value uppercaseString]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /UserDefaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ListenToMediaKeys 6 | 7 | FirstLaunchCompleted 8 | 9 | Effects_activePreset 10 | 0 11 | Effects_presets 12 | 13 | Effects_selectedMode 14 | 0 15 | AudioPlayer_numberOfRecentlyPlayedSongs 16 | -1 17 | AudioPlayer_volume 18 | 1 19 | AudioPlayer_shouldPauseWhenHeadphonesAreUnplugged 20 | 21 | AudioPlayer_shuffleModeActive 22 | 23 | AudioPlayer_shouldMaintainPlayAndSkipInfo 24 | 25 | AudioPlayer_autoSubstituteBadSources 26 | 27 | ScrobblePlayedSongsAndUpdateNowPlaying 28 | 29 | LastFM_cachedUserInfo 30 | 31 | LastFM_cachedUserInfo_Deployment 32 | 33 | MainWindow_browserMode 34 | 0 35 | ShowSongChangeNotifications 36 | 37 | MainWindow_shouldShowBackgroundMode 38 | 39 | MainWindow_artModeSquareSize 40 | 250 41 | MainWindow_artModeWindowLevel 42 | 0 43 | MainWindow_scrubbingBarUseTimeRemainingDisplayStyle 44 | 45 | MainWindow_automaticallyShowVideoWindow 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /WindowRoundedResizeKnob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/WindowRoundedResizeKnob.png -------------------------------------------------------------------------------- /WindowRoundedResizeKnob@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/WindowRoundedResizeKnob@2x.png -------------------------------------------------------------------------------- /WindowTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decarbonization/player/c48090c2d7d066ea2ea21fc708f8b454e91722aa/WindowTexture.png -------------------------------------------------------------------------------- /WindowTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // WindowTransition.h 3 | // Pinna 4 | // 5 | // Created by Kevin MacWhinnie on 12/28/11. 6 | // Copyright (c) 2011 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | ///The WindowTransition class encapsulates the transition used between windows in Pinna. 12 | @interface WindowTransition : NSObject 13 | { 14 | NSWindow *mTransitionWindow; 15 | 16 | NSView *mTransitionHostView; 17 | 18 | CALayer *mTransitionLayer; 19 | 20 | NSWindow *mSourceWindow; 21 | NSWindow *mTargetWindow; 22 | } 23 | 24 | ///Initialize the receiver with specified source and target windows. 25 | - (id)initWithSourceWindow:(NSWindow *)sourceWindow targetWindow:(NSWindow *)targetWindow; 26 | 27 | #pragma mark - Properties 28 | 29 | ///The source window 30 | @property (nonatomic, readonly) NSWindow *sourceWindow; 31 | 32 | ///The target window 33 | @property (nonatomic, readonly) NSWindow *targetWindow; 34 | 35 | #pragma mark - Transitioning 36 | 37 | ///Run the transition with a specified (optional) completion handler block. 38 | - (void)transition:(void(^)())completionHandler; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Pinna 4 | // 5 | // Created by Peter MacWhinnie on 9/24/10. 6 | // Copyright 2010 Roundabout Software, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AccountManager.h" 12 | #import "ServiceDescriptor.h" 13 | #import "Account.h" 14 | 15 | #import "LastFMDefines.h" 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | @autoreleasepool { 20 | NSURL *defaultValuesLocation = [[NSBundle mainBundle] URLForResource:@"UserDefaults" withExtension:@"plist"]; 21 | NSDictionary *defaultValues = [NSDictionary dictionaryWithContentsOfURL:defaultValuesLocation]; 22 | if(defaultValues) 23 | { 24 | [[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues]; 25 | } 26 | else 27 | { 28 | NSLog(@"Could not load UserDefaults.plist"); 29 | abort(); 30 | } 31 | } 32 | 33 | return NSApplicationMain(argc, (const char **)argv); 34 | } 35 | --------------------------------------------------------------------------------