blob: 51d4864833077a8d9d63b86740c6a79c9ab94009 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#import "SkOptionsTableView.h"
#import "SkTextFieldCell.h"
@implementation SkOptionItem
@synthesize fCell, fItem;
- (void)dealloc {
[fCell release];
[super dealloc];
}
@end
@implementation SkOptionsTableView
@synthesize fItems;
- (id)initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
self.dataSource = self;
self.delegate = self;
fMenus = NULL;
fShowKeys = YES;
[self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
self.fItems = [NSMutableArray array];
}
return self;
}
- (void)dealloc {
self.fItems = nil;
[super dealloc];
}
- (void) view:(SkNSView*)view didAddMenu:(const SkOSMenu*)menu {}
- (void) view:(SkNSView*)view didUpdateMenu:(const SkOSMenu*)menu {
[self updateMenu:menu];
}
- (IBAction)toggleKeyEquivalents:(id)sender {
fShowKeys = !fShowKeys;
NSMenuItem* item = (NSMenuItem*)sender;
[item setState:fShowKeys];
[self reloadData];
}
- (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus {
fMenus = menus;
for (int i = 0; i < fMenus->count(); ++i) {
[self loadMenu:(*fMenus)[i]];
}
}
- (void)updateMenu:(const SkOSMenu*)menu {
// the first menu is always assumed to be the static, the second is
// repopulated every time over and over again
// seems pretty weird that we have to get rid of the const'ness here,
// but trying to propagate the const'ness through all the way to the fMenus
// vector was a non-starter.
int menuIndex = fMenus->find(const_cast<SkOSMenu *>(menu));
if (menuIndex >= 0 && menuIndex < fMenus->count()) {
NSUInteger first = 0;
for (int i = 0; i < menuIndex; ++i) {
first += (*fMenus)[i]->getCount();
}
[fItems removeObjectsInRange:NSMakeRange(first, [fItems count] - first)];
[self loadMenu:menu];
}
[self reloadData];
}
- (NSCellStateValue)triStateToNSState:(SkOSMenu::TriState)state {
if (SkOSMenu::kOnState == state)
return NSOnState;
else if (SkOSMenu::kOffState == state)
return NSOffState;
else
return NSMixedState;
}
- (void)loadMenu:(const SkOSMenu*)menu {
const SkOSMenu::Item* menuitems[menu->getCount()];
menu->getItems(menuitems);
for (int i = 0; i < menu->getCount(); ++i) {
const SkOSMenu::Item* item = menuitems[i];
SkOptionItem* option = [[SkOptionItem alloc] init];
option.fItem = item;
if (SkOSMenu::kList_Type == item->getType()) {
int index = 0, count = 0;
SkOSMenu::FindListItemCount(*item->getEvent(), &count);
NSMutableArray* optionstrs = [[NSMutableArray alloc] initWithCapacity:count];
std::unique_ptr<SkString[]> ada(new SkString[count]);
SkString* options = ada.get();
SkOSMenu::FindListItems(*item->getEvent(), options);
for (int i = 0; i < count; ++i)
[optionstrs addObject:[NSString stringWithUTF8String:options[i].c_str()]];
SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &index);
option.fCell = [self createList:optionstrs current:index];
[optionstrs release];
}
else {
bool state = false;
SkString str;
SkOSMenu::TriState tristate;
switch (item->getType()) {
case SkOSMenu::kAction_Type:
option.fCell = [self createAction];
break;
case SkOSMenu::kSlider_Type:
SkScalar min, max, value;
SkOSMenu::FindSliderValue(*item->getEvent(), item->getSlotName(), &value);
SkOSMenu::FindSliderMin(*item->getEvent(), &min);
SkOSMenu::FindSliderMax(*item->getEvent(), &max);
option.fCell = [self createSlider:value
min:min
max:max];
break;
case SkOSMenu::kSwitch_Type:
SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state);
option.fCell = [self createSwitch:(BOOL)state];
break;
case SkOSMenu::kTriState_Type:
SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate);
option.fCell = [self createTriState:[self triStateToNSState:tristate]];
break;
case SkOSMenu::kTextField_Type:
SkOSMenu::FindText(*item->getEvent(),item->getSlotName(), &str);
option.fCell = [self createTextField:[NSString stringWithUTF8String:str.c_str()]];
break;
default:
break;
}
}
[fItems addObject:option];
[option release];
}
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [self.fItems count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
if (columnIndex == 0) {
const SkOSMenu::Item* item = ((SkOptionItem*)[fItems objectAtIndex:row]).fItem;
NSString* label = [NSString stringWithUTF8String:item->getLabel()];
if (fShowKeys)
return [NSString stringWithFormat:@"%@ (%c)", label, item->getKeyEquivalent()];
else
return label;
}
else
return nil;
}
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if (tableColumn) {
NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
if (columnIndex == 1)
return [((SkOptionItem*)[fItems objectAtIndex:row]).fCell copy];
else
return [[[SkTextFieldCell alloc] init] autorelease];
}
return nil;
}
- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
if (columnIndex == 1) {
SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row];
NSCell* storedCell = option.fCell;
const SkOSMenu::Item* item = option.fItem;
switch (item->getType()) {
case SkOSMenu::kAction_Type:
break;
case SkOSMenu::kList_Type:
[cell selectItemAtIndex:[(NSPopUpButtonCell*)storedCell indexOfSelectedItem]];
break;
case SkOSMenu::kSlider_Type:
[cell setFloatValue:[storedCell floatValue]];
break;
case SkOSMenu::kSwitch_Type:
[cell setState:[(NSButtonCell*)storedCell state]];
break;
case SkOSMenu::kTextField_Type:
if ([[storedCell stringValue] length] > 0)
[cell setStringValue:[storedCell stringValue]];
break;
case SkOSMenu::kTriState_Type:
[cell setState:[(NSButtonCell*)storedCell state]];
break;
default:
break;
}
}
else {
[(SkTextFieldCell*)cell setEditable:NO];
}
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSInteger columnIndex = [tableView columnWithIdentifier:[tableColumn identifier]];
if (columnIndex == 1) {
SkOptionItem* option = (SkOptionItem*)[self.fItems objectAtIndex:row];
NSCell* cell = option.fCell;
const SkOSMenu::Item* item = option.fItem;
switch (item->getType()) {
case SkOSMenu::kAction_Type:
item->postEvent();
break;
case SkOSMenu::kList_Type:
[(NSPopUpButtonCell*)cell selectItemAtIndex:[anObject intValue]];
item->setInt([anObject intValue]);
break;
case SkOSMenu::kSlider_Type:
[cell setFloatValue:[anObject floatValue]];
item->setScalar([anObject floatValue]);
break;
case SkOSMenu::kSwitch_Type:
[cell setState:[anObject boolValue]];
item->setBool([anObject boolValue]);
break;
case SkOSMenu::kTextField_Type:
if ([anObject length] > 0) {
[cell setStringValue:anObject];
item->setString([anObject UTF8String]);
}
break;
case SkOSMenu::kTriState_Type:
[cell setState:[anObject intValue]];
item->setTriState((SkOSMenu::TriState)[anObject intValue]);
break;
default:
break;
}
item->postEvent();
}
}
- (NSCell*)createAction{
NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
[cell setTitle:@""];
[cell setButtonType:NSMomentaryPushInButton];
[cell setBezelStyle:NSSmallSquareBezelStyle];
return cell;
}
- (NSCell*)createList:(NSArray*)items current:(int)index {
NSPopUpButtonCell* cell = [[[NSPopUpButtonCell alloc] init] autorelease];
[cell addItemsWithTitles:items];
[cell selectItemAtIndex:index];
[cell setArrowPosition:NSPopUpArrowAtBottom];
[cell setBezelStyle:NSSmallSquareBezelStyle];
return cell;
}
- (NSCell*)createSlider:(float)value min:(float)min max:(float)max {
NSSliderCell* cell = [[[NSSliderCell alloc] init] autorelease];
[cell setFloatValue:value];
[cell setMinValue:min];
[cell setMaxValue:max];
return cell;
}
- (NSCell*)createSwitch:(BOOL)state {
NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
[cell setState:state];
[cell setTitle:@""];
[cell setButtonType:NSSwitchButton];
return cell;
}
- (NSCell*)createTextField:(NSString*)placeHolder {
SkTextFieldCell* cell = [[[SkTextFieldCell alloc] init] autorelease];
[cell setEditable:YES];
[cell setStringValue:@""];
[cell setPlaceholderString:placeHolder];
return cell;
}
- (NSCell*)createTriState:(NSCellStateValue)state {
NSButtonCell* cell = [[[NSButtonCell alloc] init] autorelease];
[cell setAllowsMixedState:TRUE];
[cell setTitle:@""];
[cell setState:(NSInteger)state];
[cell setButtonType:NSSwitchButton];
return cell;
}
@end