blob: b4cdbf4119b58cfd5a6010c0735a513d7df9f9bb [file] [log] [blame]
bsalomon@google.comf75b84e2011-09-29 14:58:28 +00001
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
yangsu@google.com12d177d2011-08-01 17:07:12 +00009#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;
yangsu@google.comf3493f02011-08-08 15:12:05 +000026 fMenus = NULL;
27 fShowKeys = YES;
yangsu@google.com12d177d2011-08-01 17:07:12 +000028 [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
yangsu@google.comf3493f02011-08-08 15:12:05 +000044- (IBAction)toggleKeyEquivalents:(id)sender {
45 fShowKeys = !fShowKeys;
46 NSMenuItem* item = (NSMenuItem*)sender;
47 [item setState:fShowKeys];
48 [self reloadData];
49}
50
yangsu@google.com12d177d2011-08-01 17:07:12 +000051- (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus {
52 fMenus = menus;
caryclark@google.com679ab312012-06-06 12:04:00 +000053 for (int i = 0; i < fMenus->count(); ++i) {
yangsu@google.com12d177d2011-08-01 17:07:12 +000054 [self loadMenu:(*fMenus)[i]];
55 }
56}
57
humper@google.com05af1af2013-01-07 16:47:43 +000058- (void)updateMenu:(const SkOSMenu*)menu {
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +000059 // the first menu is always assumed to be the static, the second is
60 // repopulated every time over and over again
humper@google.com05af1af2013-01-07 16:47:43 +000061
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));
yangsu@google.com12d177d2011-08-01 17:07:12 +000067 if (menuIndex >= 0 && menuIndex < fMenus->count()) {
68 NSUInteger first = 0;
reed@google.com7fa2a652014-01-27 13:42:58 +000069 for (int i = 0; i < menuIndex; ++i) {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000070 first += (*fMenus)[i]->getCount();
yangsu@google.com12d177d2011-08-01 17:07:12 +000071 }
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 {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000088 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];
yangsu@google.com12d177d2011-08-01 17:07:12 +000092 SkOptionItem* option = [[SkOptionItem alloc] init];
93 option.fItem = item;
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +000094
yangsu@google.comf3493f02011-08-08 15:12:05 +000095 if (SkOSMenu::kList_Type == item->getType()) {
96 int index = 0, count = 0;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000097 SkOSMenu::FindListItemCount(*item->getEvent(), &count);
yangsu@google.comf3493f02011-08-08 15:12:05 +000098 NSMutableArray* optionstrs = [[NSMutableArray alloc] initWithCapacity:count];
mike@reedtribe.org8c0f3d82011-10-30 16:25:09 +000099 SkAutoTDeleteArray<SkString> ada(new SkString[count]);
100 SkString* options = ada.get();
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000101 SkOSMenu::FindListItems(*item->getEvent(), options);
yangsu@google.comf3493f02011-08-08 15:12:05 +0000102 for (int i = 0; i < count; ++i)
103 [optionstrs addObject:[NSString stringWithUTF8String:options[i].c_str()]];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000104 SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &index);
yangsu@google.comf3493f02011-08-08 15:12:05 +0000105 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;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000118 SkOSMenu::FindSliderValue(*item->getEvent(), item->getSlotName(), &value);
119 SkOSMenu::FindSliderMin(*item->getEvent(), &min);
120 SkOSMenu::FindSliderMax(*item->getEvent(), &max);
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000121 option.fCell = [self createSlider:value
122 min:min
yangsu@google.comf3493f02011-08-08 15:12:05 +0000123 max:max];
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000124 break;
yangsu@google.comf3493f02011-08-08 15:12:05 +0000125 case SkOSMenu::kSwitch_Type:
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000126 SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state);
yangsu@google.comf3493f02011-08-08 15:12:05 +0000127 option.fCell = [self createSwitch:(BOOL)state];
128 break;
129 case SkOSMenu::kTriState_Type:
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000130 SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate);
yangsu@google.comf3493f02011-08-08 15:12:05 +0000131 option.fCell = [self createTriState:[self triStateToNSState:tristate]];
132 break;
133 case SkOSMenu::kTextField_Type:
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000134 SkOSMenu::FindText(*item->getEvent(),item->getSlotName(), &str);
yangsu@google.comf3493f02011-08-08 15:12:05 +0000135 option.fCell = [self createTextField:[NSString stringWithUTF8String:str.c_str()]];
136 break;
137 default:
138 break;
139 }
yangsu@google.com12d177d2011-08-01 17:07:12 +0000140 }
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 {
reed@google.com7fa2a652014-01-27 13:42:58 +0000151 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
yangsu@google.comf3493f02011-08-08 15:12:05 +0000152 if (columnIndex == 0) {
153 const SkOSMenu::Item* item = ((SkOptionItem*)[fItems objectAtIndex:row]).fItem;
154 NSString* label = [NSString stringWithUTF8String:item->getLabel()];
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000155 if (fShowKeys)
yangsu@google.comf3493f02011-08-08 15:12:05 +0000156 return [NSString stringWithFormat:@"%@ (%c)", label, item->getKeyEquivalent()];
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000157 else
yangsu@google.comf3493f02011-08-08 15:12:05 +0000158 return label;
159 }
yangsu@google.com12d177d2011-08-01 17:07:12 +0000160 else
161 return nil;
162}
163
164- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
165 if (tableColumn) {
reed@google.com7fa2a652014-01-27 13:42:58 +0000166 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000167 if (columnIndex == 1)
yangsu@google.com12d177d2011-08-01 17:07:12 +0000168 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 {
reed@google.com7fa2a652014-01-27 13:42:58 +0000176 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000177 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:
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000183 break;
yangsu@google.com12d177d2011-08-01 17:07:12 +0000184 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:
yangsu@google.com12d177d2011-08-01 17:07:12 +0000191 [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:
yangsu@google.com12d177d2011-08-01 17:07:12 +0000198 [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 {
reed@google.com7fa2a652014-01-27 13:42:58 +0000210 NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000211 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]];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000221 item->setInt([anObject intValue]);
yangsu@google.com12d177d2011-08-01 17:07:12 +0000222 break;
223 case SkOSMenu::kSlider_Type:
224 [cell setFloatValue:[anObject floatValue]];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000225 item->setScalar([anObject floatValue]);
yangsu@google.com12d177d2011-08-01 17:07:12 +0000226 break;
227 case SkOSMenu::kSwitch_Type:
228 [cell setState:[anObject boolValue]];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000229 item->setBool([anObject boolValue]);
yangsu@google.com12d177d2011-08-01 17:07:12 +0000230 break;
231 case SkOSMenu::kTextField_Type:
232 if ([anObject length] > 0) {
233 [cell setStringValue:anObject];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000234 item->setString([anObject UTF8String]);
yangsu@google.com12d177d2011-08-01 17:07:12 +0000235 }
236 break;
237 case SkOSMenu::kTriState_Type:
238 [cell setState:[anObject intValue]];
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000239 item->setTriState((SkOSMenu::TriState)[anObject intValue]);
yangsu@google.com12d177d2011-08-01 17:07:12 +0000240 break;
241 default:
242 break;
243 }
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000244 item->postEvent();
yangsu@google.com12d177d2011-08-01 17:07:12 +0000245 }
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];
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000262 return cell;
yangsu@google.com12d177d2011-08-01 17:07:12 +0000263}
264
yangsu@google.com12d177d2011-08-01 17:07:12 +0000265- (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];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000275 [cell setState:state];
yangsu@google.comf3493f02011-08-08 15:12:05 +0000276 [cell setTitle:@""];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000277 [cell setButtonType:NSSwitchButton];
278 return cell;
279}
280
commit-bot@chromium.orgfaa5ae42013-07-23 11:13:56 +0000281- (NSCell*)createTextField:(NSString*)placeHolder {
yangsu@google.com12d177d2011-08-01 17:07:12 +0000282 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];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000291 [cell setAllowsMixedState:TRUE];
yangsu@google.comf3493f02011-08-08 15:12:05 +0000292 [cell setTitle:@""];
yangsu@google.com12d177d2011-08-01 17:07:12 +0000293 [cell setState:(NSInteger)state];
294 [cell setButtonType:NSSwitchButton];
295 return cell;
296}
caryclark@google.com679ab312012-06-06 12:04:00 +0000297@end