1 #import "StatusWindowController.h"
2 #import "StatusWindow.h"
3 #import "PreferencesController.h"
4 #import "MainController.h"
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>
14 static StatusWindowController *sharedController;
16 @implementation StatusWindowController
19 + (StatusWindowController *)sharedController
21 if ( ! sharedController ) {
22 sharedController = [[StatusWindowController alloc] init];
25 return sharedController;
31 if ( ( self = [super init] ) ) {
36 NSArray *classList = [ITWindowEffect effectClasses];
42 ITWindowEffect *entryEffect;
43 ITWindowEffect *exitEffect;
45 _window = [[StatusWindow sharedWindow] retain];
46 df = [[NSUserDefaults standardUserDefaults] retain];
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"];
54 [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
55 [_window setExitDelay:(exitDelay ? exitDelay : 4.0)];
57 [_window setHorizontalPosition:[df integerForKey:@"statusWindowHorizontalPosition"]];
58 [_window setVerticalPosition:[df integerForKey:@"statusWindowVerticalPosition"]];
60 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
62 if ( [classList containsObject:NSClassFromString(entryClass)] ) {
63 entryEffect = [[[NSClassFromString(entryClass) alloc] initWithWindow:_window] autorelease];
65 entryEffect = [[[ITCutWindowEffect alloc] initWithWindow:_window] autorelease];
68 if ( [classList containsObject:NSClassFromString(exitClass)] ) {
69 exitEffect = [[[NSClassFromString(exitClass) alloc] initWithWindow:_window] autorelease];
71 exitEffect = [[[ITDissolveWindowEffect alloc] initWithWindow:_window] autorelease];
74 [_window setEntryEffect:entryEffect];
75 [_window setExitEffect:exitEffect];
77 [[_window entryEffect] setEffectTime:(entrySpeed ? entrySpeed : 0.8)];
78 [[_window exitEffect] setEffectTime:(exitSpeed ? exitSpeed : 0.8)];
80 [(ITTSWBackgroundView *)[_window contentView]setBackgroundMode:
81 (ITTSWBackgroundMode)[df integerForKey:@"statusWindowBackgroundMode"]];
83 colorData = [df dataForKey:@"statusWindowBackgroundColor"];
86 [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:
87 (NSColor *)[NSUnarchiver unarchiveObjectWithData:colorData]];
89 [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:[NSColor blueColor]];
102 - (void)showSongInfoWindowWithSource:(ITMTRemotePlayerSource)source
103 title: (NSString *)title
104 album: (NSString *)album
105 artist: (NSString *)artist
106 composer: (NSString *)composer
107 time: (NSString *)time // FLOW: Should probably be NSDate or something.
108 track: (NSString *)track
110 image: (NSImage *)art
112 NSImage *image = nil;
113 NSString *text = title;
117 } else if ( source == ITMTRemoteLibrarySource ) {
118 image = [NSImage imageNamed:@"Library"];
119 } else if ( source == ITMTRemoteCDSource ) {
120 image = [NSImage imageNamed:@"CD"];
121 } else if ( source == ITMTRemoteRadioSource ) {
122 image = [NSImage imageNamed:@"Radio"];
123 } else if ( source == ITMTRemoteiPodSource ) {
124 image = [NSImage imageNamed:@"iPod"];
125 } else if ( source == ITMTRemoteGenericDeviceSource ) {
126 image = [NSImage imageNamed:@"MP3Player"];
127 } else if ( source == ITMTRemoteSharedLibrarySource ) {
128 image = [NSImage imageNamed:@"Library"];
131 [_window setImage:image];
134 text = [text stringByAppendingString:[@"\n" stringByAppendingString:album]];
137 text = [text stringByAppendingString:[@"\n" stringByAppendingString:artist]];
140 text = [text stringByAppendingString:[@"\n" stringByAppendingString:composer]];
143 text = [text stringByAppendingString:[@"\n" stringByAppendingString:time]];
146 text = [text stringByAppendingString:[@"\n" stringByAppendingString:track]];
150 NSString *ratingString = [NSString string];
151 NSString *emptyChar = [NSString stringWithUTF8String:"☆"];
152 NSString *fullChar = [NSString stringWithUTF8String:"★"];
155 for ( i = 1; i < 6; i++ ) {
158 ratingString = [ratingString stringByAppendingString:fullChar];
160 ratingString = [ratingString stringByAppendingString:emptyChar];
164 text = [text stringByAppendingString:[@"\n" stringByAppendingString:ratingString]];
168 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
169 [_window buildTextWindowWithString:text];
170 [_window appear:self];
173 - (void)showUpcomingSongsWindowWithTitles:(NSArray *)titleStrings
175 // NSString *bull = [NSString stringWithUTF8String:"‣ "];
176 NSString *bull = [NSString stringWithUTF8String:"♪ "];
177 NSString *end = [@"\n" stringByAppendingString:bull];
178 [_window setImage:[NSImage imageNamed:@"Upcoming"]];
179 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
180 [_window buildTextWindowWithString:[bull stringByAppendingString:[titleStrings componentsJoinedByString:end]]];
181 [_window appear:self];
184 - (void)showVolumeWindowWithLevel:(float)level
186 [_window setImage:[NSImage imageNamed:@"Volume"]];
187 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
188 [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"▊"]
191 active:( ceil(level * 100) / 10 )];
192 [_window appear:self];
195 - (void)showRatingWindowWithRating:(float)rating
197 [_window setImage:[NSImage imageNamed:@"Rating"]];
198 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
199 [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"★"]
202 active:( ceil(rating * 100) / 20 )];
203 [_window appear:self];
206 - (void)showShuffleWindow:(BOOL)shuffle
208 [_window setImage:[NSImage imageNamed:@"Shuffle"]];
209 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
210 [_window buildTextWindowWithString:( shuffle ? @"Shuffle On" : @"Shuffle Off")];
211 [_window appear:self];
214 - (void)showRepeatWindowWithMode:(StatusWindowRepeatMode)mode
216 NSString *string = nil;
218 if ( mode == StatusWindowRepeatNone ) {
219 string = @"Repeat Off";
220 } else if ( mode == StatusWindowRepeatGroup ) {
221 string = @"Repeat Playlist";
222 } else if ( mode == StatusWindowRepeatTrack ) {
223 string = @"Repeat One Track";
226 [_window setImage:[NSImage imageNamed:@"Repeat"]];
227 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
228 [_window buildTextWindowWithString:string];
229 [_window appear:self];
232 - (void)showSetupQueryWindow
234 NSString *message = @"Would you like MenuTunes to launch\nautomatically at startup?";
236 [_window setImage:[NSImage imageNamed:@"Setup"]];
237 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
238 [_window buildDialogWindowWithMessage:message
239 defaultButton:@"Launch at Startup"
240 alternateButton:@"Launch Manually"
241 target:[PreferencesController sharedPrefs]
242 defaultAction:@selector(autoLaunchOK)
243 alternateAction:@selector(autoLaunchCancel)];
245 [_window appear:self];
246 [_window setLocked:YES];
250 - (void)showRegistrationQueryWindow
252 NSString *message = @"Your 7-day unlimited trial period has elapsed.\nYou must register to continue using MenuTunes.";
254 [_window setImage:[NSImage imageNamed:@"Register"]];
255 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
256 [_window buildDialogWindowWithMessage:message
257 defaultButton:@"Register Now"
258 alternateButton:@"Quit MenuTunes"
259 target:[MainController sharedController]
260 defaultAction:@selector(registerNowOK)
261 alternateAction:@selector(registerNowCancel)];
263 [_window appear:self];
264 [_window setLocked:YES];
267 - (void)showReconnectQueryWindow
269 NSString *message = @"The selected shared player is available again.\nWould you like to reconnect to it?";
270 [_window setLocked:NO];
271 [_window setImage:[NSImage imageNamed:@"Setup"]];
272 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
273 [_window buildDialogWindowWithMessage:message
274 defaultButton:@"Reconnect"
275 alternateButton:@"Ignore"
276 target:[MainController sharedController]
277 defaultAction:@selector(reconnect)
278 alternateAction:@selector(cancelReconnect)];
280 [_window appear:self];
281 [_window setLocked:YES];
284 - (void)showNetworkErrorQueryWindow
286 NSString *message = @"The remote MenuTunes server is unreachable.\nMenuTunes will revert back to the local player.";
288 [_window setImage:[NSImage imageNamed:@"Setup"]];
289 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
290 [_window buildDialogWindowWithMessage:message
291 defaultButton:@" OK "
293 target:[MainController sharedController]
294 defaultAction:@selector(cancelReconnect)
295 alternateAction:nil];
297 [_window appear:self];
298 [_window setLocked:YES];
301 - (void)showPreferencesUpdateWindow
303 NSString *message = @"The new features in this version of MenuTunes\nrequire you to reconfigure your preferences.";
305 [_window setImage:[NSImage imageNamed:@"Setup"]];
306 [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
307 [_window buildDialogWindowWithMessage:message
308 defaultButton:@"Show Preferences"
309 alternateButton:@"OK"
310 target:[MainController sharedController]
311 defaultAction:@selector(showPreferencesAndClose)
312 alternateAction:@selector(cancelReconnect)];
314 [_window appear:self];
315 [_window setLocked:YES];