|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 #import "SkOptionsTableView.h" |
|
10 #import "SkTextFieldCell.h" |
|
11 @implementation SkOptionItem |
|
12 @synthesize fCell, fItem; |
|
13 - (void)dealloc { |
|
14 [fCell release]; |
|
15 [super dealloc]; |
|
16 } |
|
17 @end |
|
18 |
|
19 @implementation SkOptionsTableView |
|
20 @synthesize fItems; |
|
21 |
|
22 - (id)initWithCoder:(NSCoder*)coder { |
|
23 if ((self = [super initWithCoder:coder])) { |
|
24 self.dataSource = self; |
|
25 self.delegate = self; |
|
26 fMenus = NULL; |
|
27 fShowKeys = YES; |
|
28 [self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone]; |
|
29 self.fItems = [NSMutableArray array]; |
|
30 } |
|
31 return self; |
|
32 } |
|
33 |
|
34 - (void)dealloc { |
|
35 self.fItems = nil; |
|
36 [super dealloc]; |
|
37 } |
|
38 |
|
39 - (void) view:(SkNSView*)view didAddMenu:(const SkOSMenu*)menu {} |
|
40 - (void) view:(SkNSView*)view didUpdateMenu:(const SkOSMenu*)menu { |
|
41 [self updateMenu:menu]; |
|
42 } |
|
43 |
|
44 - (IBAction)toggleKeyEquivalents:(id)sender { |
|
45 fShowKeys = !fShowKeys; |
|
46 NSMenuItem* item = (NSMenuItem*)sender; |
|
47 [item setState:fShowKeys]; |
|
48 [self reloadData]; |
|
49 } |
|
50 |
|
51 - (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus { |
|
52 fMenus = menus; |
|
53 for (int i = 0; i < fMenus->count(); ++i) { |
|
54 [self loadMenu:(*fMenus)[i]]; |
|
55 } |
|
56 } |
|
57 |
|
58 - (void)updateMenu:(const SkOSMenu*)menu { |
|
59 // the first menu is always assumed to be the static, the second is |
|
60 // repopulated every time over and over again |
|
61 |
|
62 // seems pretty weird that we have to get rid of the const'ness here, |
|
63 // but trying to propagate the const'ness through all the way to the fMenus |
|
64 // vector was a non-starter. |
|
65 |
|
66 int menuIndex = fMenus->find(const_cast<SkOSMenu *>(menu)); |
|
67 if (menuIndex >= 0 && menuIndex < fMenus->count()) { |
|
68 NSUInteger first = 0; |
|
69 for (int i = 0; i < menuIndex; ++i) { |
|
70 first += (*fMenus)[i]->getCount(); |
|
71 } |
|
72 [fItems removeObjectsInRange:NSMakeRange(first, [fItems count] - first)]; |
|
73 [self loadMenu:menu]; |
|
74 } |
|
75 [self reloadData]; |
|
76 } |
|
77 |
|
78 - (NSCellStateValue)triStateToNSState:(SkOSMenu::TriState)state { |
|
79 if (SkOSMenu::kOnState == state) |
|
80 return NSOnState; |
|
81 else if (SkOSMenu::kOffState == state) |
|
82 return NSOffState; |
|
83 else |
|
84 return NSMixedState; |
|
85 } |
|
86 |
|
87 - (void)loadMenu:(const SkOSMenu*)menu { |
|
88 const SkOSMenu::Item* menuitems[menu->getCount()]; |
|
89 menu->getItems(menuitems); |
|
90 for (int i = 0; i < menu->getCount(); ++i) { |
|
91 const SkOSMenu::Item* item = menuitems[i]; |
|
92 SkOptionItem* option = [[SkOptionItem alloc] init]; |
|
93 option.fItem = item; |
|
94 |
|
95 if (SkOSMenu::kList_Type == item->getType()) { |
|
96 int index = 0, count = 0; |
|
97 SkOSMenu::FindListItemCount(*item->getEvent(), &count); |
|
98 NSMutableArray* optionstrs = [[NSMutableArray alloc] initWithCapacity:count]; |
|
99 SkAutoTDeleteArray<SkString> ada(new SkString[count]); |
|
100 SkString* options = ada.get(); |
|
101 SkOSMenu::FindListItems(*item->getEvent(), options); |
|
102 for (int i = 0; i < count; ++i) |
|
103 [optionstrs addObject:[NSString stringWithUTF8String:options[i].c_str()]]; |
|
104 SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &index); |
|
105 option.fCell = [self createList:optionstrs current:index]; |
|
106 [optionstrs release]; |
|
107 } |
|
108 else { |
|
109 bool state = false; |
|
110 SkString str; |
|
111 SkOSMenu::TriState tristate; |
|
112 switch (item->getType()) { |
|
113 case SkOSMenu::kAction_Type: |
|
114 option.fCell = [self createAction]; |
|
115 break; |
|
116 case SkOSMenu::kSlider_Type: |
|
117 SkScalar min, max, value; |
|
118 SkOSMenu::FindSliderValue(*item->getEvent(), item->getSlotName(), &value); |
|
119 SkOSMenu::FindSliderMin(*item->getEvent(), &min); |
|
120 SkOSMenu::FindSliderMax(*item->getEvent(), &max); |
|
121 option.fCell = [self createSlider:value |
|
122 min:min |
|
123 max:max]; |
|
124 break; |
|
125 case SkOSMenu::kSwitch_Type: |
|
126 SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state); |
|
127 option.fCell = [self createSwitch:(BOOL)state]; |
|
128 break; |
|
129 case SkOSMenu::kTriState_Type: |
|
130 SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate); |
|
131 option.fCell = [self createTriState:[self triStateToNSState:tristate]]; |
|
132 break; |
|
133 case SkOSMenu::kTextField_Type: |
|
134 SkOSMenu::FindText(*item->getEvent(),item->getSlotName(), &str); |
|
135 option.fCell = [self createTextField:[NSString stringWithUTF8String:str.c_str()]]; |
|
136 break; |
|
137 default: |
|
138 break; |
|
139 } |
|
140 } |
|
141 [fItems addObject:option]; |
|
142 [option release]; |
|
143 } |
|
144 } |
|
145 |
|
146 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { |
|
147 return [self.fItems count]; |
|
148 } |
|
149 |
|
150 - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { |
|
151 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]]; |
|
152 if (columnIndex == 0) { |
|
153 const SkOSMenu::Item* item = ((SkOptionItem*)[fItems objectAtIndex:row]).fItem; |
|
154 NSString* label = [NSString stringWithUTF8String:item->getLabel()]; |
|
155 if (fShowKeys) |
|
156 return [NSString stringWithFormat:@"%@ (%c)", label, item->getKeyEquivalent()]; |
|
157 else |
|
158 return label; |
|
159 } |
|
160 else |
|
161 return nil; |
|
162 } |
|
163 |
|
164 - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { |
|
165 if (tableColumn) { |
|
166 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]]; |
|
167 if (columnIndex == 1) |
|
168 return [((SkOptionItem*)[fItems objectAtIndex:row]).fCell copy]; |
|
169 else |
|
170 return [[[SkTextFieldCell alloc] init] autorelease]; |
|
171 } |
|
172 return nil; |
|
173 } |
|
174 |
|
175 - (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { |
|
176 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]]; |
|
177 if (columnIndex == 1) { |
|
178 SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row]; |
|
179 NSCell* storedCell = option.fCell; |
|
180 const SkOSMenu::Item* item = option.fItem; |
|
181 switch (item->getType()) { |
|
182 case SkOSMenu::kAction_Type: |
|
183 break; |
|
184 case SkOSMenu::kList_Type: |
|
185 [cell selectItemAtIndex:[(NSPopUpButtonCell*)storedCell indexOfSelectedItem]]; |
|
186 break; |
|
187 case SkOSMenu::kSlider_Type: |
|
188 [cell setFloatValue:[storedCell floatValue]]; |
|
189 break; |
|
190 case SkOSMenu::kSwitch_Type: |
|
191 [cell setState:[(NSButtonCell*)storedCell state]]; |
|
192 break; |
|
193 case SkOSMenu::kTextField_Type: |
|
194 if ([[storedCell stringValue] length] > 0) |
|
195 [cell setStringValue:[storedCell stringValue]]; |
|
196 break; |
|
197 case SkOSMenu::kTriState_Type: |
|
198 [cell setState:[(NSButtonCell*)storedCell state]]; |
|
199 break; |
|
200 default: |
|
201 break; |
|
202 } |
|
203 } |
|
204 else { |
|
205 [(SkTextFieldCell*)cell setEditable:NO]; |
|
206 } |
|
207 } |
|
208 |
|
209 - (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { |
|
210 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]]; |
|
211 if (columnIndex == 1) { |
|
212 SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row]; |
|
213 NSCell* cell = option.fCell; |
|
214 const SkOSMenu::Item* item = option.fItem; |
|
215 switch (item->getType()) { |
|
216 case SkOSMenu::kAction_Type: |
|
217 item->postEvent(); |
|
218 break; |
|
219 case SkOSMenu::kList_Type: |
|
220 [(NSPopUpButtonCell*)cell selectItemAtIndex:[anObject intValue]]; |
|
221 item->setInt([anObject intValue]); |
|
222 break; |
|
223 case SkOSMenu::kSlider_Type: |
|
224 [cell setFloatValue:[anObject floatValue]]; |
|
225 item->setScalar([anObject floatValue]); |
|
226 break; |
|
227 case SkOSMenu::kSwitch_Type: |
|
228 [cell setState:[anObject boolValue]]; |
|
229 item->setBool([anObject boolValue]); |
|
230 break; |
|
231 case SkOSMenu::kTextField_Type: |
|
232 if ([anObject length] > 0) { |
|
233 [cell setStringValue:anObject]; |
|
234 item->setString([anObject UTF8String]); |
|
235 } |
|
236 break; |
|
237 case SkOSMenu::kTriState_Type: |
|
238 [cell setState:[anObject intValue]]; |
|
239 item->setTriState((SkOSMenu::TriState)[anObject intValue]); |
|
240 break; |
|
241 default: |
|
242 break; |
|
243 } |
|
244 item->postEvent(); |
|
245 } |
|
246 } |
|
247 |
|
248 - (NSCell*)createAction{ |
|
249 NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease]; |
|
250 [cell setTitle:@""]; |
|
251 [cell setButtonType:NSMomentaryPushInButton]; |
|
252 [cell setBezelStyle:NSSmallSquareBezelStyle]; |
|
253 return cell; |
|
254 } |
|
255 |
|
256 - (NSCell*)createList:(NSArray*)items current:(int)index { |
|
257 NSPopUpButtonCell* cell = [[[NSPopUpButtonCell alloc] init] autorelease]; |
|
258 [cell addItemsWithTitles:items]; |
|
259 [cell selectItemAtIndex:index]; |
|
260 [cell setArrowPosition:NSPopUpArrowAtBottom]; |
|
261 [cell setBezelStyle:NSSmallSquareBezelStyle]; |
|
262 return cell; |
|
263 } |
|
264 |
|
265 - (NSCell*)createSlider:(float)value min:(float)min max:(float)max { |
|
266 NSSliderCell* cell = [[[NSSliderCell alloc] init] autorelease]; |
|
267 [cell setFloatValue:value]; |
|
268 [cell setMinValue:min]; |
|
269 [cell setMaxValue:max]; |
|
270 return cell; |
|
271 } |
|
272 |
|
273 - (NSCell*)createSwitch:(BOOL)state { |
|
274 NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease]; |
|
275 [cell setState:state]; |
|
276 [cell setTitle:@""]; |
|
277 [cell setButtonType:NSSwitchButton]; |
|
278 return cell; |
|
279 } |
|
280 |
|
281 - (NSCell*)createTextField:(NSString*)placeHolder { |
|
282 SkTextFieldCell* cell = [[[SkTextFieldCell alloc] init] autorelease]; |
|
283 [cell setEditable:YES]; |
|
284 [cell setStringValue:@""]; |
|
285 [cell setPlaceholderString:placeHolder]; |
|
286 return cell; |
|
287 } |
|
288 |
|
289 - (NSCell*)createTriState:(NSCellStateValue)state { |
|
290 NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease]; |
|
291 [cell setAllowsMixedState:TRUE]; |
|
292 [cell setTitle:@""]; |
|
293 [cell setState:(NSInteger)state]; |
|
294 [cell setButtonType:NSSwitchButton]; |
|
295 return cell; |
|
296 } |
|
297 @end |