Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 243 lines (191 sloc) 9.004 kb
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
1 //
2 // VivaSortableTrackListController.m
3 // Viva
4 //
5 // Created by Daniel Kennett on 4/22/11.
6 // Copyright 2011 Spotify. All rights reserved.
7 //
8
9 #import "VivaSortableTrackListController.h"
10 #import "SPTableHeaderCell.h"
11 #import "SPTableCorner.h"
12 #import "VivaSortDescriptorExtensions.h"
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
13 #import "Constants.h"
d65ce11 @iKenndac Searching now works for queries with spaces (oops!). Moved drag image ge...
authored
14 #import "VivaImageExtensions.h"
0802103 @iKenndac Add "Copy Spotify URI" menu items.
authored
15 #import "VivaTrackInContainerReference.h"
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
16
17 @implementation VivaSortableTrackListController
18
19 -(void)awakeFromNib {
20
21 sortAscending = YES;
22
23 // No IB support for custom headers. Yay!
24
25 for (NSTableColumn *column in [self.trackTable tableColumns]) {
90d18b1 @iKenndac Convert Viva to use ARC. Replace SPCircularBuffer with one included in C...
authored
26 SPTableHeaderCell *newCell = [[SPTableHeaderCell alloc] init];
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
27 [newCell setObjectValue:[[column headerCell] objectValue]];
28 [column setHeaderCell:newCell];
29 }
30
90d18b1 @iKenndac Convert Viva to use ARC. Replace SPCircularBuffer with one included in C...
authored
31 [self.trackTable setCornerView:[[SPTableCorner alloc] init]];
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
32
33 [self.trackTable setTarget:self];
34 [self.trackTable setDoubleAction:@selector(playTrack:)];
35
36 [self addObserver:self
37 forKeyPath:@"playingTrackContainerIsCurrentlyPlaying"
38 options:0
39 context:nil];
40
41 [self addObserver:self
42 forKeyPath:@"playingTrackContainer"
43 options:0
44 context:nil];
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
45 }
46
0802103 @iKenndac Add "Copy Spotify URI" menu items.
authored
47 -(BOOL)validateMenuItem:(NSMenuItem *)menuItem {
48 if (menuItem.action == @selector(copySpotifyURI:)) {
49 return self.trackTable.selectedRowIndexes.count == 1 || self.trackTable.clickedRow != -1;
50 }
51 return [super validateMenuItem:menuItem];
52 }
53
54 -(IBAction)copySpotifyURI:(id)sender {
55
56 VivaTrackInContainerReference *item = nil;
57
58 if (self.trackTable.clickedRow != -1) {
59 item = [self.trackContainerArrayController.arrangedObjects objectAtIndex:self.trackTable.clickedRow];
60 } else if (self.trackTable.selectedRowIndexes.count == 0) {
61 item = [self.trackContainerArrayController.arrangedObjects objectAtIndex:self.trackTable.selectedRowIndexes.firstIndex];
62 }
63
64 if (item == nil) {
65 NSBeep();
66 return;
67 }
68
69 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
70
71 [pasteboard declareTypes:[NSArray arrayWithObjects:NSURLPboardType, NSStringPboardType, nil] owner:nil];
bcfaacd @iKenndac Copy track URI to clipboard as string as well as URL.
authored
72 [pasteboard setString:item.track.spotifyURL.absoluteString forType:NSStringPboardType];
0802103 @iKenndac Add "Copy Spotify URI" menu items.
authored
73 [item.track.spotifyURL writeToPasteboard:pasteboard];
74
75 }
76
35dc30f @iKenndac Implement spotify: URI handler. UI improvements.
authored
77 -(void)viewControllerDidActivateWithContext:(id)context {
78 if ([context isKindOfClass:[SPTrack class]]) {
79
80 for (id <VivaTrackContainer> container in self.trackContainerArrayController.arrangedObjects) {
81
82 if ([container.track isEqual:context]) {
83 [self.trackTable selectRowIndexes:[NSIndexSet indexSetWithIndex:[self.trackContainerArrayController.arrangedObjects indexOfObject:container]]
84 byExtendingSelection:NO];
85 [self.trackTable becomeFirstResponder];
86 return;
87 }
88 }
89 }
90 }
91
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
92 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
93 if ([keyPath isEqualToString:@"playingTrackContainer"] || [keyPath isEqualToString:@"playingTrackContainerIsCurrentlyPlaying"]) {
94 [self.trackTable reloadData];
773af3a Draw unplayable tracks in grey. Only scroll track table around if playin...
Daniel Kennett authored
95 if (self.playingTrackContainer != nil) {
96
97 NSInteger rowIndex = [self.trackContainerArrayController.arrangedObjects indexOfObject:self.playingTrackContainer];
98 NSRect rowRect = [self.trackTable rectOfRow:rowIndex];
99
100 if (!NSContainsRect([self.trackTable visibleRect], rowRect))
101 [self.trackTable scrollRowToVisible:rowIndex];
102 }
103
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
104 } else {
105 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
106 }
107 }
108
41585af @iKenndac Space and return keys now control playback.
authored
109 -(void)keyDown:(NSEvent *)theEvent {
110
111 if ([[theEvent characters] isEqualToString:@" "]) {
a0ca473 @iKenndac Pulled in latest CocoaLibSpotify and updated Viva to use renamed APIs.
authored
112 [[[NSApp delegate] session] setPlaying:![[[NSApp delegate] session] isPlaying]];
41585af @iKenndac Space and return keys now control playback.
authored
113 } else {
114 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
115 }
116 }
117
118 -(void)insertNewline:(id)sender {
119
120 if (self.trackTable.window.firstResponder == self.trackTable) {
121 if (self.trackContainerArrayController.selectedObjects.count > 0) {
122 id <VivaTrackContainer> container = [[self.trackContainerArrayController selectedObjects] objectAtIndex:0];
123 [self playTrackContainerInThisContext:container];
124 return;
125 }
126 }
127 NSBeep();
128 }
129
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
130 @synthesize trackContainers;
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
131 @synthesize trackContainerArrayController;
132 @synthesize trackTable;
133
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
134 -(IBAction)playTrack:(id)sender {
135 if ([self.trackTable clickedRow] > -1) {
136 id <VivaTrackContainer> container = [[self.trackContainerArrayController arrangedObjects] objectAtIndex:[self.trackTable clickedRow]];
137 [self playTrackContainerInThisContext:container];
138 }
139 }
140
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
141 +(NSSet *)keyPathsForValuesAffectingTracksForPlayback {
142 return [NSSet setWithObject:@"trackContainerArrayController.arrangedObjects"];
143 }
144
145 -(NSArray *)trackContainersForPlayback {
146 return [NSArray arrayWithArray:[self.trackContainerArrayController arrangedObjects]];
147 }
148
149 - (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn
150 {
151 // Either reverse the sort or change the sorting column
152
153 if ([[tableColumn identifier] isEqualToString:@"playIndicator"])
154 return;
155
156 for (NSTableColumn *col in [tableView tableColumns]) {
157 if ([(SPTableHeaderCell *)[col headerCell] sortPriority] == 0) {
158 if (col == tableColumn) {
159 sortAscending = !sortAscending;
160 }
161 }
162 }
163
164 for (NSTableColumn *col in [tableView tableColumns]) {
165 if (tableView == self.trackTable) {
166 if (col == tableColumn) {
167 if ([[tableColumn identifier] isEqualToString:@"title"]) {
168 [self.trackContainerArrayController setSortDescriptors:[NSSortDescriptor trackContainerSortDescriptorsForTitleAscending:sortAscending]];
169 } else if ([[tableColumn identifier] isEqualToString:@"album"]) {
170 [self.trackContainerArrayController setSortDescriptors:[NSSortDescriptor trackContainerSortDescriptorsForAlbumAscending:sortAscending]];
171 } else if ([[tableColumn identifier] isEqualToString:@"artist"]) {
172 [self.trackContainerArrayController setSortDescriptors:[NSSortDescriptor trackContainerSortDescriptorsForArtistAscending:sortAscending]];
173 }
174 [(SPTableHeaderCell *)[col headerCell] setSortAscending:[[[self.trackContainerArrayController sortDescriptors] objectAtIndex:0] ascending] priority:0];
175 } else {
176 [(SPTableHeaderCell *)[col headerCell] setSortAscending:YES priority:1];
177 }
178
179 [[self.trackTable headerView] setNeedsDisplay:YES];
180 }
181 }
182 }
183
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
184 - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
185
186 if ([[aTableColumn identifier] isEqualToString:@"playIndicator"]) {
187 if (rowIndex < [[self.trackContainerArrayController arrangedObjects] count]) {
188 id <VivaTrackContainer> container = [[self.trackContainerArrayController arrangedObjects] objectAtIndex:rowIndex];
189 if (container == self.playingTrackContainer) {
190 if (self.playingTrackContainerIsCurrentlyPlaying) {
191 [aCell setImage:[NSImage imageNamed:@"playing-indicator"]];
192 [aCell setAlternateImage:[NSImage imageNamed:@"playing-indicator-highlighted"]];
193 } else {
194 [aCell setImage:[NSImage imageNamed:@"paused-indicator"]];
195 [aCell setAlternateImage:[NSImage imageNamed:@"paused-indicator-highlighted"]];
196 }
197 } else {
198 [aCell setImage:nil];
199 [aCell setAlternateImage:nil];
200 }
201 }
773af3a Draw unplayable tracks in grey. Only scroll track table around if playin...
Daniel Kennett authored
202 } else {
203
204 if (rowIndex < [[self.trackContainerArrayController arrangedObjects] count]) {
205 id <VivaTrackContainer> container = [[self.trackContainerArrayController arrangedObjects] objectAtIndex:rowIndex];
ea0e148 Local File playback now reports the natural end of playback. UI no longe...
Daniel Kennett authored
206 [aCell setEnabled:(container.track.availability == SP_TRACK_AVAILABILITY_AVAILABLE ||
207 container.track.isLocal)];
773af3a Draw unplayable tracks in grey. Only scroll track table around if playin...
Daniel Kennett authored
208 }
209 }
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
210 }
211
d65ce11 @iKenndac Searching now works for queries with spaces (oops!). Moved drag image ge...
authored
212 -(NSImage *)tableView:(NSTableView *)tableView dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset {
213
214 return [NSImage decoratedMosaicWithTracks:[[self.trackContainerArrayController.arrangedObjects objectsAtIndexes:dragRows] valueForKey:@"track"]
215 badgeLabel:[dragRows count] > 1 ? [[NSNumber numberWithInteger:[dragRows count]] stringValue] : nil
216 aspect:kDragImageMaximumMosaicSize];
217
218 }
219
be525f2 @iKenndac Moved more stuff to VivaSortableTrackListController.
authored
220 - (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
221
222 NSArray *containers = [self.trackContainerArrayController.arrangedObjects objectsAtIndexes:rowIndexes];
223 [pboard setData:[NSKeyedArchiver archivedDataWithRootObject:[[containers valueForKey:@"track"] valueForKey:@"spotifyURL"]]
224 forType:kSpotifyTrackURLListDragIdentifier];
225
226 NSMutableIndexSet *sourceIndexes = [NSMutableIndexSet indexSet];
227 for (id <VivaTrackContainer> ref in containers) {
228 [sourceIndexes addIndex:[self.trackContainers indexOfObject:ref]];
229 }
230
231 [pboard setData:[NSKeyedArchiver archivedDataWithRootObject:sourceIndexes]
232 forType:kSpotifyTrackMoveSourceIndexSetDragIdentifier];
233
234 return YES;
235 }
236
237 - (void)dealloc {
238 [self removeObserver:self forKeyPath:@"playingTrackContainerIsCurrentlyPlaying"];
239 [self removeObserver:self forKeyPath:@"playingTrackContainer"];
06df899 @iKenndac Added VivaSortableTrackListController to abstract out dealing with a sor...
authored
240 }
241
242 @end
Something went wrong with that request. Please try again.