YAY, it looks pretty and smooth. (The album art)
[MenuTunes.git] / StatusWindowController.m
1 #import "StatusWindowController.h"
2 #import "StatusWindow.h"
3 #import "PreferencesController.h"
4 #import "MainController.h"
5
6 #import <ITKit/ITTSWBackgroundView.h>
7 #import <ITKit/ITWindowEffect.h>
8 #import <ITKit/ITCutWindowEffect.h>
9 #import <ITKit/ITDissolveWindowEffect.h>
10 #import <ITKit/ITSlideHorizontallyWindowEffect.h>
11 #import <ITKit/ITSlideVerticallyWindowEffect.h>
12 #import <ITKit/ITPivotWindowEffect.h>
13
14 static StatusWindowController *sharedController;
15
16 @implementation StatusWindowController
17
18
19 + (StatusWindowController *)sharedController
20 {
21     if ( ! sharedController ) {
22         sharedController = [[StatusWindowController alloc] init];
23     }
24     
25     return sharedController;
26 }
27
28
29 - (id)init
30 {
31     if ( ( self = [super init] ) ) {
32         
33         float exitDelay;
34         NSString *entryClass;
35         NSString *exitClass;
36         NSArray  *classList = [ITWindowEffect effectClasses];
37         float entrySpeed;
38         float exitSpeed;
39         
40         NSData *colorData;
41         
42         ITWindowEffect *entryEffect;
43         ITWindowEffect *exitEffect;
44         
45         _window = [[StatusWindow sharedWindow] retain];
46         df = [[NSUserDefaults standardUserDefaults] retain];
47         
48         exitDelay  = [df floatForKey:@"statusWindowVanishDelay"];
49         entryClass = [df stringForKey:@"statusWindowAppearanceEffect"];
50         exitClass  = [df stringForKey:@"statusWindowVanishEffect"];
51         entrySpeed = [df floatForKey:@"statusWindowAppearanceSpeed"];
52         exitSpeed  = [df floatForKey:@"statusWindowVanishSpeed"];
53         
54         [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
55         [_window setExitDelay:(exitDelay ? exitDelay : 4.0)];
56         
57         [_window setHorizontalPosition:[df integerForKey:@"statusWindowHorizontalPosition"]];
58         [_window setVerticalPosition:[df integerForKey:@"statusWindowVerticalPosition"]];
59         
60         [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
61         
62         if ( [classList containsObject:NSClassFromString(entryClass)] ) {
63             entryEffect = [[[NSClassFromString(entryClass) alloc] initWithWindow:_window] autorelease];
64         } else {
65             entryEffect = [[[ITCutWindowEffect alloc] initWithWindow:_window] autorelease];
66         }
67         
68         if ( [classList containsObject:NSClassFromString(exitClass)] ) {
69             exitEffect = [[[NSClassFromString(exitClass) alloc] initWithWindow:_window] autorelease];
70         } else {
71             exitEffect = [[[ITDissolveWindowEffect alloc] initWithWindow:_window] autorelease];
72         }
73         
74         [_window setEntryEffect:entryEffect];
75         [_window setExitEffect:exitEffect];
76         
77         [[_window entryEffect] setEffectTime:(entrySpeed ? entrySpeed : 0.8)];
78         [[_window exitEffect]  setEffectTime:(exitSpeed  ? exitSpeed  : 0.8)];
79         
80         [(ITTSWBackgroundView *)[_window contentView]setBackgroundMode:
81             (ITTSWBackgroundMode)[df integerForKey:@"statusWindowBackgroundMode"]];
82         
83         colorData = [df dataForKey:@"statusWindowBackgroundColor"];
84         
85         if ( colorData ) {
86             [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:
87                 (NSColor *)[NSUnarchiver unarchiveObjectWithData:colorData]];
88         } else {
89             [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:[NSColor blueColor]];
90         }
91     }
92     
93     return self;
94 }
95
96 - (void)dealloc
97 {
98     [_window release];
99     [super dealloc];
100 }
101
102 - (void)showSongInfoWindowWithSource:(ITMTRemotePlayerSource)source
103                                title:            (NSString *)title
104                                album:            (NSString *)album
105                               artist:            (NSString *)artist
106                                 time:            (NSString *)time  // FLOW: Should probably be NSDate or something.
107                                track:            (NSString *)track
108                               rating:                   (int)rating
109                                image:             (NSImage *)art
110 {
111     NSImage  *image = nil;
112     NSString *text  = title;
113     
114     if ( art != nil ) {
115         image = art;
116     } else if ( source == ITMTRemoteLibrarySource ) {
117         image = [NSImage imageNamed:@"Library"];
118     } else if ( source == ITMTRemoteCDSource ) {
119         image = [NSImage imageNamed:@"CD"];
120     } else if ( source == ITMTRemoteRadioSource ) {
121         image = [NSImage imageNamed:@"Radio"];
122     } else if ( source == ITMTRemoteiPodSource ) {
123         image = [NSImage imageNamed:@"iPod"];
124     } else if ( source == ITMTRemoteGenericDeviceSource ) {
125         image = [NSImage imageNamed:@"MP3Player"];
126     } else if ( source == ITMTRemoteSharedLibrarySource ) {
127         image = [NSImage imageNamed:@"Library"];
128     }
129     
130     [_window setImage:image];
131     
132     if ( album ) {
133         text = [text stringByAppendingString:[@"\n" stringByAppendingString:album]];
134     }
135     if ( artist ) {
136         text = [text stringByAppendingString:[@"\n" stringByAppendingString:artist]];
137     }
138     if ( time ) {
139         text = [text stringByAppendingString:[@"\n" stringByAppendingString:time]];
140     }
141     if ( track ) {
142         text = [text stringByAppendingString:[@"\n" stringByAppendingString:track]];
143     }
144     if ( rating > -1 ) {
145
146         NSString *ratingString = [NSString string];
147         NSString *emptyChar    = [NSString stringWithUTF8String:"☆"];
148         NSString *fullChar     = [NSString stringWithUTF8String:"★"];
149         int       i;
150         
151         for ( i = 1; i < 6; i++ ) {
152                 
153             if ( rating >= i ) {
154                 ratingString = [ratingString stringByAppendingString:fullChar];
155             } else {
156                 ratingString = [ratingString stringByAppendingString:emptyChar];
157             }
158         }
159     
160         text = [text stringByAppendingString:[@"\n" stringByAppendingString:ratingString]];
161     }
162     
163     
164     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
165     [_window buildTextWindowWithString:text];
166     [_window appear:self];
167 }
168
169 - (void)showUpcomingSongsWindowWithTitles:(NSArray *)titleStrings
170 {
171 //  NSString *bull = [NSString stringWithUTF8String:"‣ "];
172     NSString *bull = [NSString stringWithUTF8String:"♪ "];
173     NSString *end  = [@"\n" stringByAppendingString:bull];
174     [_window setImage:[NSImage imageNamed:@"Upcoming"]];
175     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
176     [_window buildTextWindowWithString:[bull stringByAppendingString:[titleStrings componentsJoinedByString:end]]];
177     [_window appear:self];
178 }
179
180 - (void)showVolumeWindowWithLevel:(float)level
181 {
182     [_window setImage:[NSImage imageNamed:@"Volume"]];
183     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
184     [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"▊"]
185                                       size:18
186                                      count:10
187                                     active:( ceil(level * 100) / 10 )];
188     [_window appear:self];
189 }
190
191 - (void)showRatingWindowWithRating:(float)rating
192 {
193     [_window setImage:[NSImage imageNamed:@"Rating"]];
194     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
195     [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"★"]
196                                       size:48
197                                      count:5
198                                     active:( ceil(rating * 100) / 20 )];
199     [_window appear:self];
200 }
201
202 - (void)showShuffleWindow:(BOOL)shuffle
203 {
204     [_window setImage:[NSImage imageNamed:@"Shuffle"]];
205     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
206     [_window buildTextWindowWithString:( shuffle ? @"Shuffle On" : @"Shuffle Off")];
207     [_window appear:self];
208 }
209
210 - (void)showRepeatWindowWithMode:(StatusWindowRepeatMode)mode
211 {
212     NSString *string = nil;
213     
214     if ( mode == StatusWindowRepeatNone ) {
215         string = @"Repeat Off";
216     } else if ( mode == StatusWindowRepeatGroup ) {
217         string = @"Repeat Playlist";
218     } else if ( mode == StatusWindowRepeatTrack ) {
219         string = @"Repeat One Track";
220     }
221     
222     [_window setImage:[NSImage imageNamed:@"Repeat"]];
223     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
224     [_window buildTextWindowWithString:string];
225     [_window appear:self];
226 }
227
228 - (void)showSetupQueryWindow
229 {
230     NSString *message = @"Would you like MenuTunes to launch\nautomatically at startup?";
231
232     [_window setImage:[NSImage imageNamed:@"Setup"]];
233     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
234     [_window buildDialogWindowWithMessage:message
235                             defaultButton:@"Launch at Startup"
236                           alternateButton:@"Launch Manually"
237                                    target:[PreferencesController sharedPrefs]
238                             defaultAction:@selector(autoLaunchOK)
239                           alternateAction:@selector(autoLaunchCancel)];
240
241     [_window appear:self];
242     [_window setLocked:YES];
243 }
244
245
246 - (void)showRegistrationQueryWindow
247 {
248     NSString *message = @"Your 7-day unlimited trial period has elapsed.\nYou must register to continue using MenuTunes.";
249
250     [_window setImage:[NSImage imageNamed:@"Register"]];
251     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
252     [_window buildDialogWindowWithMessage:message
253                             defaultButton:@"Register Now"
254                           alternateButton:@"Quit MenuTunes"
255                                    target:[MainController sharedController]
256                             defaultAction:@selector(registerNowOK)
257                           alternateAction:@selector(registerNowCancel)];
258
259     [_window appear:self];
260     [_window setLocked:YES];
261 }
262
263 - (void)showReconnectQueryWindow
264 {
265     NSString *message = @"The selected shared player is available again.\nWould you like to reconnect to it?.";
266
267     [_window setImage:[NSImage imageNamed:@"Setup"]];
268     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
269     [_window buildDialogWindowWithMessage:message
270                             defaultButton:@"Reconnect"
271                           alternateButton:@"Ignore"
272                                    target:[MainController sharedController]
273                             defaultAction:@selector(reconnect)
274                           alternateAction:@selector(cancelReconnect)];
275
276     [_window appear:self];
277     [_window setLocked:YES];
278 }
279
280 - (void)showPreferencesUpdateWindow
281 {
282     NSString *message = @"The new features in this version of MenuTunes\nrequire you to reconfigure your preferences.";
283
284     [_window setImage:[NSImage imageNamed:@"Setup"]];
285     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
286     [_window buildDialogWindowWithMessage:message
287                             defaultButton:@"Show Preferences"
288                           alternateButton:@"OK"
289                                    target:[MainController sharedController]
290                             defaultAction:@selector(showPreferencesAndClose)
291                           alternateAction:@selector(cancelReconnect)];
292
293     [_window appear:self];
294     [_window setLocked:YES];
295 }
296
297 @end