Added more to MenuController. Does next/prev track
[MenuTunes.git] / MenuController.m
1 //
2 //  MenuController.m
3 //  MenuTunes
4 //
5 //  Created by Joseph Spiros on Wed Apr 30 2003.
6 //  Copyright (c) 2003 iThink Software. All rights reserved.
7 //
8
9 #import "MenuController.h"
10 #import "NewMainController.h"
11 #import "ITMTRemote.h"
12
13 @implementation MenuController
14
15 - (id)init
16 {
17     if ( (self = [super init]) ) {
18         _menuLayout = [[NSMutableArray alloc] initWithCapacity:0];
19     }
20     return self;
21 }
22
23 - (NSMenu *)menu
24 {
25     NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
26     NSArray *menuArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"menu"];
27     NSEnumerator *enumerator = [menuArray objectEnumerator];
28     NSString *nextObject;
29     ITMTRemote *currentRemote = [[MainController sharedController] currentRemote];
30     NSMenuItem *tempItem;
31     
32     //Get the current playlist, track index, etc.
33     int playlistIndex = [currentRemote currentPlaylistIndex];
34     int trackIndex = [currentRemote currentSongIndex];
35     
36     // dynamically create menu from supplied data and layout information.
37     while ( (nextObject = [enumerator nextObject]) ) {
38         if ([nextObject isEqualToString:@"Play/Pause"]) {
39             tempItem = [menu addItemWithTitle:@"Play"
40                     action:@selector(performMainMenuAction:)
41                     keyEquivalent:@""];
42             [tempItem setTag:MTMenuPlayPauseItem];
43             [tempItem setTarget:self];
44             
45             switch ([currentRemote playerPlayingState]) {
46                 case ITMTRemotePlayerPlaying:
47                     [tempItem setTitle:@"Pause"];
48                 break;
49                 case ITMTRemotePlayerRewinding:
50                 case ITMTRemotePlayerForwarding:
51                     [tempItem setTitle:@"Resume"];
52                 break;
53                 default:
54                 break;
55             }
56         } else if ([nextObject isEqualToString:@"Next Track"]) {
57             tempItem = [menu addItemWithTitle:@"Next Track"
58                     action:@selector(performMainMenuAction:)
59                     keyEquivalent:@""];
60             [tempItem setTag:MTMenuNextTrackItem];
61             [tempItem setTarget:self];
62         } else if ([nextObject isEqualToString:@"Previous Track"]) {
63             tempItem = [menu addItemWithTitle:@"Previous Track"
64                     action:@selector(performMainMenuAction:)
65                     keyEquivalent:@""];
66             [tempItem setTag:MTMenuPreviousTrackItem];
67             [tempItem setTarget:self];
68         } else if ([nextObject isEqualToString:@"Current Track Info"]) {
69             NSString *title = [currentRemote currentSongTitle];
70             [menu addItemWithTitle:@"Now Playing" action:NULL keyEquivalent:@""];
71             
72             if ([title length] > 0) {
73                 [menu addItemWithTitle:[NSString stringWithFormat:@"     %@", title] action:nil keyEquivalent:@""];
74             }
75         }
76         //Do cool stuff here woo hehe gack yay! 0_o
77     }
78     
79     [_currentMenu release];
80     _currentMenu = menu;
81     return _currentMenu;
82 }
83
84 - (void)performMainMenuAction:(id)sender
85 {
86     switch ( [sender tag] )
87     {
88         case MTMenuPlayPauseItem:
89             NSLog(@"MenuController: Play/Pause");
90             [[MainController sharedController] playPause];
91             //We're gonna have to change the Play menu item to Pause here too.
92             break;
93         case MTMenuFastForwardItem:
94             NSLog(@"MenuController: Fast Forward");
95             [[MainController sharedController] fastForward];
96             //make sure play/pause item says sane through this
97             break;
98         case MTMenuRewindItem:
99             NSLog(@"MenuController: Rewind");
100             [[MainController sharedController] rewind];
101             //make sure play/pause item says sane through this
102             break;
103         case MTMenuPreviousTrackItem:
104             NSLog(@"MenuController: Previous Track");
105             [[MainController sharedController] prevSong];
106             break;
107         case MTMenuNextTrackItem:
108             NSLog(@"MenuController: Next Track");
109             [[MainController sharedController] nextSong];
110             break;
111         case MTMenuPreferencesItem:
112             NSLog(@"MenuController: Preferences...");
113             [[MainController sharedController] showPreferences];
114             break;
115         case MTMenuQuitItem:
116             NSLog(@"MenuController: Quit");
117             [[MainController sharedController] quitMenuTunes];
118             break;
119         default:
120             NSLog(@"MenuController: Unimplemented Menu Item OR Child-bearing Menu Item");
121             break;
122     }
123 }
124
125 - (void)performRatingMenuAction:(id)sender
126 {
127     [[MainController sharedController] selectSongRating:[sender tag]];
128 }
129
130 - (void)performPlaylistMenuAction:(id)sender
131 {
132     [[MainController sharedController] selectPlaylistAtIndex:[sender tag]];
133 }
134
135 - (void)performEqualizerMenuAction:(id)sender
136 {
137     [[MainController sharedController] selectEQPresetAtIndex:[sender tag]];
138 }
139
140 - (void)performUpcomingSongsMenuAction:(id)sender
141 {
142     [[MainController sharedController] selectSongAtIndex:[sender tag]];
143 }
144
145 - (void)updateMenu
146 {
147     
148     [_currentMenu update];
149 }
150
151 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
152 {
153     return YES;
154 }
155
156 - (NSString *)systemUIColor
157 {
158     NSDictionary *tmpDict;
159     NSNumber *tmpNumber;
160     if ( (tmpDict = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/.GlobalPreferences.plist" stringByExpandingTildeInPath]]) ) {
161         if ( (tmpNumber = [tmpDict objectForKey:@"AppleAquaColorVariant"]) ) {
162             if ( ([tmpNumber intValue] == 1) ) {
163                 return @"Aqua";
164             } else {
165                 return @"Graphite";
166             }
167         } else {
168             return @"Aqua";
169         }
170     } else {
171         return @"Aqua";
172     }
173 }
174
175 - (void)setKeyEquivalentForCode:(short)code andModifiers:(long)modifiers
176         onItem:(NSMenuItem *)item
177 {
178     unichar charcode = 'a';
179     int i;
180     long cocoaModifiers = 0;
181     static long carbonToCocoa[6][2] = 
182     {
183         { cmdKey, NSCommandKeyMask },
184         { optionKey, NSAlternateKeyMask },
185         { controlKey, NSControlKeyMask },
186         { shiftKey, NSShiftKeyMask },
187     };
188     
189     for (i = 0; i < 6; i++) {
190         if (modifiers & carbonToCocoa[i][0]) {
191             cocoaModifiers += carbonToCocoa[i][1];
192         }
193     }
194     [item setKeyEquivalentModifierMask:cocoaModifiers];
195     
196     //Missing key combos for some keys. Must find them later.
197     switch (code)
198     {
199         case 36:
200             charcode = '\r';
201         break;
202         
203         case 48:
204             charcode = '\t';
205         break;
206         
207         //Space -- ARGH!
208         case 49:
209         {
210             // Haven't tested this, though it should work.
211             unichar buffer;
212             [[NSString stringWithString:@"Space"] getCharacters:&buffer];
213             charcode = buffer;
214             /*MenuRef menuRef = _NSGetCarbonMenu([item menu]);
215             NSLog(@"%@", menuRef);
216             SetMenuItemCommandKey(menuRef, 0, NO, 49);
217             SetMenuItemModifiers(menuRef, 0, kMenuNoCommandModifier);
218             SetMenuItemKeyGlyph(menuRef, 0, kMenuBlankGlyph);
219             charcode = 'b';*/
220             
221         }
222         break;
223         
224         case 51:
225             charcode = NSDeleteFunctionKey;
226         break;
227         
228         case 53:
229             charcode = '\e';
230         break;
231         
232         case 71:
233             charcode = '\e';
234         break;
235         
236         case 76:
237             charcode = '\r';
238         break;
239         
240         case 96:
241             charcode = NSF5FunctionKey;
242         break;
243         
244         case 97:
245             charcode = NSF6FunctionKey;
246         break;
247         
248         case 98:
249             charcode = NSF7FunctionKey;
250         break;
251         
252         case 99:
253             charcode = NSF3FunctionKey;
254         break;
255         
256         case 100:
257             charcode = NSF8FunctionKey;
258         break;
259         
260         case 101:
261             charcode = NSF9FunctionKey;
262         break;
263         
264         case 103:
265             charcode = NSF11FunctionKey;
266         break;
267         
268         case 105:
269             charcode = NSF3FunctionKey;
270         break;
271         
272         case 107:
273             charcode = NSF14FunctionKey;
274         break;
275         
276         case 109:
277             charcode = NSF10FunctionKey;
278         break;
279         
280         case 111:
281             charcode = NSF12FunctionKey;
282         break;
283         
284         case 113:
285             charcode = NSF13FunctionKey;
286         break;
287         
288         case 114:
289             charcode = NSInsertFunctionKey;
290         break;
291         
292         case 115:
293             charcode = NSHomeFunctionKey;
294         break;
295         
296         case 116:
297             charcode = NSPageUpFunctionKey;
298         break;
299         
300         case 117:
301             charcode = NSDeleteFunctionKey;
302         break;
303         
304         case 118:
305             charcode = NSF4FunctionKey;
306         break;
307         
308         case 119:
309             charcode = NSEndFunctionKey;
310         break;
311         
312         case 120:
313             charcode = NSF2FunctionKey;
314         break;
315         
316         case 121:
317             charcode = NSPageDownFunctionKey;
318         break;
319         
320         case 122:
321             charcode = NSF1FunctionKey;
322         break;
323         
324         case 123:
325             charcode = NSLeftArrowFunctionKey;
326         break;
327         
328         case 124:
329             charcode = NSRightArrowFunctionKey;
330         break;
331         
332         case 125:
333             charcode = NSDownArrowFunctionKey;
334         break;
335         
336         case 126:
337             charcode = NSUpArrowFunctionKey;
338         break;
339     }
340     
341     if (charcode == 'a') {
342         unsigned long state;
343         long keyTrans;
344         char charCode;
345         Ptr kchr;
346         state = 0;
347         kchr = (Ptr) GetScriptVariable(smCurrentScript, smKCHRCache);
348         keyTrans = KeyTranslate(kchr, code, &state);
349         charCode = keyTrans;
350         [item setKeyEquivalent:[NSString stringWithCString:&charCode length:1]];
351     } else if (charcode != 'b') {
352         [item setKeyEquivalent:[NSString stringWithCharacters:&charcode length:1]];
353     }
354 }
355
356 @end