5 // Created by Joseph Spiros on Wed Apr 30 2003.
6 // Copyright (c) 2003 iThink Software. All rights reserved.
9 #import "MenuController.h"
10 #import "NewMainController.h"
12 @interface MenuController (SubmenuMethods)
13 - (NSMenu *)ratingMenu;
14 - (NSMenu *)upcomingSongsMenu;
15 - (NSMenu *)playlistsMenu;
19 @implementation MenuController
23 if ( (self = [super init]) ) {
24 _menuLayout = [[NSMutableArray alloc] initWithCapacity:0];
31 NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
32 NSArray *menuArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"menu"];
33 NSEnumerator *enumerator = [menuArray objectEnumerator];
37 //Get the current playlist, track index, etc.
38 currentRemote = [[MainController sharedController] currentRemote];
39 _currentPlaylist = [currentRemote currentPlaylistIndex];
40 _currentTrack = [currentRemote currentSongIndex];
41 _playingRadio = ([currentRemote currentPlaylistClass] == ITMTRemotePlayerRadioPlaylist);
44 while ( (nextObject = [enumerator nextObject]) ) {
46 if ([nextObject isEqualToString:@"Play/Pause"]) {
47 tempItem = [menu addItemWithTitle:@"Play"
48 action:@selector(performMainMenuAction:)
50 [tempItem setTag:MTMenuPlayPauseItem];
51 [tempItem setTarget:self];
53 switch ([currentRemote playerPlayingState]) {
54 case ITMTRemotePlayerPlaying:
55 [tempItem setTitle:@"Pause"];
57 case ITMTRemotePlayerRewinding:
58 case ITMTRemotePlayerForwarding:
59 [tempItem setTitle:@"Resume"];
64 } else if ([nextObject isEqualToString:@"Next Track"]) {
65 tempItem = [menu addItemWithTitle:@"Next Track"
66 action:@selector(performMainMenuAction:)
68 if (_currentPlaylist) {
69 [tempItem setTag:MTMenuNextTrackItem];
70 [tempItem setTarget:self];
72 } else if ([nextObject isEqualToString:@"Previous Track"]) {
73 tempItem = [menu addItemWithTitle:@"Previous Track"
74 action:@selector(performMainMenuAction:)
76 if (_currentPlaylist) {
77 [tempItem setTag:MTMenuPreviousTrackItem];
78 [tempItem setTarget:self];
80 } else if ([nextObject isEqualToString:@"Fast Forward"]) {
81 tempItem = [menu addItemWithTitle:@"Fast Forward"
82 action:@selector(performMainMenuAction:)
84 if (_currentPlaylist) {
85 [tempItem setTag:MTMenuFastForwardItem];
86 [tempItem setTarget:self];
88 } else if ([nextObject isEqualToString:@"Rewind"]) {
89 tempItem = [menu addItemWithTitle:@"Rewind"
90 action:@selector(performMainMenuAction:)
92 if (_currentPlaylist) {
93 [tempItem setTag:MTMenuRewindItem];
94 [tempItem setTarget:self];
96 } else if ([nextObject isEqualToString:@"Preferences"]) {
97 tempItem = [menu addItemWithTitle:@"Preferences..."
98 action:@selector(performMainMenuAction:)
100 [tempItem setTag:MTMenuPreferencesItem];
101 [tempItem setTarget:self];
102 } else if ([nextObject isEqualToString:@"Quit"]) {
103 tempItem = [menu addItemWithTitle:@"Quit"
104 action:@selector(performMainMenuAction:)
106 [tempItem setTag:MTMenuQuitItem];
107 [tempItem setTarget:self];
108 } else if ([nextObject isEqualToString:@"Current Track Info"]) {
109 //Handle playing radio too
110 if (_currentPlaylist) {
111 NSString *title = [currentRemote currentSongTitle];
113 [menu addItemWithTitle:@"Now Playing" action:NULL keyEquivalent:@""];
115 if ([title length] > 0) {
116 [menu addItemWithTitle:[NSString stringWithFormat:@" %@", title] action:nil keyEquivalent:@""];
118 //Gotta add artist, album, track, time, etc, blah, blah, blah...
120 [menu addItemWithTitle:@"No Song" action:NULL keyEquivalent:@""];
122 } else if ([nextObject isEqualToString:@"<separator>"]) {
123 [menu addItem:[NSMenuItem separatorItem]];
125 } else if ([nextObject isEqualToString:@"Song Rating"]) {
126 tempItem = [menu addItemWithTitle:@"Song Rating"
129 [tempItem setSubmenu:[self ratingMenu]];
130 if (_playingRadio || !_currentPlaylist) {
131 [tempItem setEnabled:NO];
133 } else if ([nextObject isEqualToString:@"Upcoming Songs"]) {
134 tempItem = [menu addItemWithTitle:@"Upcoming Songs"
137 [tempItem setSubmenu:[self upcomingSongsMenu]];
138 if (_playingRadio || !_currentPlaylist) {
139 [tempItem setEnabled:NO];
141 } else if ([nextObject isEqualToString:@"Playlists"]) {
142 tempItem = [menu addItemWithTitle:@"Playlists"
145 [tempItem setSubmenu:[self playlistsMenu]];
146 } else if ([nextObject isEqualToString:@"EQ Presets"]) {
147 tempItem = [menu addItemWithTitle:@"EQ Presets"
150 [tempItem setSubmenu:[self eqMenu]];
154 [_currentMenu release];
159 - (NSMenu *)menuForNoPlayer
161 NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
162 NSMenuItem *tempItem;
163 tempItem = [menu addItemWithTitle:[NSString stringWithFormat:@"Open %@", [[[MainController sharedController] currentRemote] playerSimpleName]] action:@selector(performMainMenuAction:) keyEquivalent:@""];
164 [tempItem setTag:MTMenuShowPlayerItem];
165 [tempItem setTarget:self];
166 [menu addItem:[NSMenuItem separatorItem]];
167 tempItem = [menu addItemWithTitle:@"Preferences" action:@selector(performMainMenuAction:) keyEquivalent:@""];
168 [tempItem setTag:MTMenuPreferencesItem];
169 [tempItem setTarget:self];
170 tempItem = [menu addItemWithTitle:@"Quit" action:@selector(performMainMenuAction:) keyEquivalent:@""];
171 [tempItem setTag:MTMenuQuitItem];
172 [tempItem setTarget:self];
173 return [menu autorelease];
176 - (NSMenu *)ratingMenu
178 NSMenu *ratingMenu = [[NSMenu alloc] initWithTitle:@""];
180 if (_currentPlaylist && !_playingRadio) {
181 NSEnumerator *itemEnum;
184 SEL itemSelector = @selector(performRatingMenuAction:);
186 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"☆☆☆☆☆"] action:nil keyEquivalent:@""];
187 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★☆☆☆☆"] action:nil keyEquivalent:@""];
188 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★☆☆☆"] action:nil keyEquivalent:@""];
189 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★☆☆"] action:nil keyEquivalent:@""];
190 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★☆"] action:nil keyEquivalent:@""];
191 [ratingMenu addItemWithTitle:[NSString stringWithUTF8String:"★★★★★"] action:nil keyEquivalent:@""];
193 [[ratingMenu itemAtIndex:([currentRemote currentSongRating] * 5)] setState:NSOnState];
195 itemEnum = [[ratingMenu itemArray] objectEnumerator];
196 while ( (anItem = [itemEnum nextObject]) ) {
197 [anItem setAction:itemSelector];
198 [anItem setTarget:self];
199 [anItem setTag:itemTag];
204 return [ratingMenu autorelease];
207 - (NSMenu *)upcomingSongsMenu
209 NSMenu *upcomingSongsMenu = [[NSMenu alloc] initWithTitle:@""];
210 int numSongs = [currentRemote numberOfSongsInPlaylistAtIndex:_currentPlaylist];
211 int numSongsInAdvance = [[NSUserDefaults standardUserDefaults] integerForKey:@"SongsInAdvance"];
213 if (_currentPlaylist && !_playingRadio) {
217 for (i = _currentTrack + 1; i <= _currentTrack + numSongsInAdvance; i++) {
219 NSString *curSong = [currentRemote songTitleAtIndex:i];
220 NSMenuItem *songItem;
221 songItem = [upcomingSongsMenu addItemWithTitle:curSong action:@selector(performUpcomingSongsMenuAction:) keyEquivalent:@""];
223 [songItem setTarget:self];
230 return [upcomingSongsMenu autorelease];
233 - (NSMenu *)playlistsMenu
235 NSMenu *playlistsMenu = [[NSMenu alloc] initWithTitle:@""];
236 NSArray *playlists = [currentRemote playlists];
237 NSMenuItem *tempItem;
240 for (i = 0; i < [playlists count]; i++) {
241 tempItem = [playlistsMenu addItemWithTitle:[playlists objectAtIndex:i] action:@selector(performPlaylistMenuAction:) keyEquivalent:@""];
242 [tempItem setTag:i + 1];
243 [tempItem setTarget:self];
246 if (!_playingRadio && _currentPlaylist) {
247 [[playlistsMenu itemAtIndex:_currentPlaylist - 1] setState:NSOnState];
249 return [playlistsMenu autorelease];
254 NSMenu *eqMenu = [[NSMenu alloc] initWithTitle:@""];
255 NSArray *eqPresets = [currentRemote eqPresets];
256 NSMenuItem *tempItem;
259 for (i = 0; i < [eqPresets count]; i++) {
261 if ( ( name = [eqPresets objectAtIndex:i] ) ) {
262 tempItem = [eqMenu addItemWithTitle:name action:@selector(performEqualizerMenuAction:) keyEquivalent:@""];
264 [tempItem setTarget:self];
267 [[eqMenu itemAtIndex:([currentRemote currentEQPresetIndex] - 1)] setState:NSOnState];
268 return [eqMenu autorelease];
271 - (void)performMainMenuAction:(id)sender
273 switch ( [sender tag] )
275 case MTMenuPlayPauseItem:
276 NSLog(@"MenuController: Play/Pause");
277 [[MainController sharedController] playPause];
278 //We're gonna have to change the Play menu item to Pause here too.
280 case MTMenuFastForwardItem:
281 NSLog(@"MenuController: Fast Forward");
282 [[MainController sharedController] fastForward];
283 //make sure play/pause item says sane through this
285 case MTMenuRewindItem:
286 NSLog(@"MenuController: Rewind");
287 [[MainController sharedController] rewind];
288 //make sure play/pause item says sane through this
290 case MTMenuPreviousTrackItem:
291 NSLog(@"MenuController: Previous Track");
292 [[MainController sharedController] prevSong];
294 case MTMenuNextTrackItem:
295 NSLog(@"MenuController: Next Track");
296 [[MainController sharedController] nextSong];
298 case MTMenuShowPlayerItem:
299 NSLog(@"MainController: Show Main Interface");
300 [[MainController sharedController] showPlayer];
302 case MTMenuPreferencesItem:
303 NSLog(@"MenuController: Preferences...");
304 [[MainController sharedController] showPreferences];
307 NSLog(@"MenuController: Quit");
308 [[MainController sharedController] quitMenuTunes];
311 NSLog(@"MenuController: Unimplemented Menu Item OR Child-bearing Menu Item");
316 - (void)performRatingMenuAction:(id)sender
318 [[MainController sharedController] selectSongRating:[sender tag]];
321 - (void)performPlaylistMenuAction:(id)sender
323 [[MainController sharedController] selectPlaylistAtIndex:[sender tag]];
326 - (void)performEqualizerMenuAction:(id)sender
328 [[MainController sharedController] selectEQPresetAtIndex:[sender tag]];
331 - (void)performUpcomingSongsMenuAction:(id)sender
333 [[MainController sharedController] selectSongAtIndex:[sender tag]];
339 [_currentMenu update];
342 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
347 - (NSString *)systemUIColor
349 NSDictionary *tmpDict;
351 if ( (tmpDict = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/.GlobalPreferences.plist" stringByExpandingTildeInPath]]) ) {
352 if ( (tmpNumber = [tmpDict objectForKey:@"AppleAquaColorVariant"]) ) {
353 if ( ([tmpNumber intValue] == 1) ) {
366 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
367 onItem:(NSMenuItem *)item
369 unichar charcode = 'a';
371 long cocoaModifiers = 0;
372 static long carbonToCocoa[6][2] =
374 { cmdKey, NSCommandKeyMask },
375 { optionKey, NSAlternateKeyMask },
376 { controlKey, NSControlKeyMask },
377 { shiftKey, NSShiftKeyMask },
380 for (i = 0; i < 6; i++) {
381 if (modifiers & carbonToCocoa[i][0]) {
382 cocoaModifiers += carbonToCocoa[i][1];
385 [item setKeyEquivalentModifierMask:cocoaModifiers];
387 //Missing key combos for some keys. Must find them later.
401 // Haven't tested this, though it should work.
402 // This doesn't work. :'(
404 [[NSString stringWithString:@"Space"] getCharacters:&buffer];
406 /*MenuRef menuRef = _NSGetCarbonMenu([item menu]);
407 NSLog(@"%@", menuRef);
408 SetMenuItemCommandKey(menuRef, 0, NO, 49);
409 SetMenuItemModifiers(menuRef, 0, kMenuNoCommandModifier);
410 SetMenuItemKeyGlyph(menuRef, 0, kMenuBlankGlyph);
417 charcode = NSDeleteFunctionKey;
433 charcode = NSF5FunctionKey;
437 charcode = NSF6FunctionKey;
441 charcode = NSF7FunctionKey;
445 charcode = NSF3FunctionKey;
449 charcode = NSF8FunctionKey;
453 charcode = NSF9FunctionKey;
457 charcode = NSF11FunctionKey;
461 charcode = NSF3FunctionKey;
465 charcode = NSF14FunctionKey;
469 charcode = NSF10FunctionKey;
473 charcode = NSF12FunctionKey;
477 charcode = NSF13FunctionKey;
481 charcode = NSInsertFunctionKey;
485 charcode = NSHomeFunctionKey;
489 charcode = NSPageUpFunctionKey;
493 charcode = NSDeleteFunctionKey;
497 charcode = NSF4FunctionKey;
501 charcode = NSEndFunctionKey;
505 charcode = NSF2FunctionKey;
509 charcode = NSPageDownFunctionKey;
513 charcode = NSF1FunctionKey;
517 charcode = NSLeftArrowFunctionKey;
521 charcode = NSRightArrowFunctionKey;
525 charcode = NSDownArrowFunctionKey;
529 charcode = NSUpArrowFunctionKey;
533 if (charcode == 'a') {
539 kchr = (Ptr) GetScriptVariable(smCurrentScript, smKCHRCache);
540 keyTrans = KeyTranslate(kchr, code, &state);
542 [item setKeyEquivalent:[NSString stringWithCString:&charCode length:1]];
543 } else if (charcode != 'b') {
544 [item setKeyEquivalent:[NSString stringWithCharacters:&charcode length:1]];