blob: e6adfd0bd1f839bef94af2568d5108d0fd89616c [file] [log] [blame]
#import "SkOptionsTableViewController.h"
#include "SkEvent.h"
#include "SkTArray.h"
@implementation SkOptionItem
@synthesize fCell, fItem;
- (void)dealloc {
[fCell release];
[super dealloc];
}
@end
@implementation SkOptionListItem
@synthesize fOptions;
- (void)dealloc {
[fOptions release];
[super dealloc];
}
@end
@implementation SkOptionsTableViewController
@synthesize fItems, fCurrentList;
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.fItems = [NSMutableArray array];
}
return self;
}
//SkUIViewOptionsDelegate
- (void) view:(SkUIView*)view didAddMenu:(const SkOSMenu*)menu {}
- (void) view:(SkUIView*)view didUpdateMenu:(SkOSMenu*)menu {
[self updateMenu:menu];
}
- (NSUInteger)convertPathToIndex:(NSIndexPath*)path {
NSUInteger index = 0;
for (NSInteger i = 0; i < path.section; ++i) {
index += (*fMenus)[i]->getCount();
}
return index + path.row;
}
- (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus {
fMenus = menus;
for (NSUInteger i = 0; i < fMenus->count(); ++i) {
[self loadMenu:(*fMenus)[i]];
}
}
- (void)updateMenu:(SkOSMenu*)menu {
// the first menu is always assumed to be the static, the second is
// repopulated every time over and over again
int menuIndex = fMenus->find(menu);
if (menuIndex >= 0 && menuIndex < fMenus->count()) {
NSUInteger first = 0;
for (NSInteger i = 0; i < menuIndex; ++i) {
first += (*fMenus)[i]->getCount();
}
[fItems removeObjectsInRange:NSMakeRange(first, [fItems count] - first)];
[self loadMenu:menu];
}
[self.tableView reloadData];
}
- (void)loadMenu:(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];
NSString* title = [NSString stringWithUTF8String:item->getLabel()];
if (SkOSMenu::kList_Type == item->getType()) {
int value = 0;
SkOptionListItem* List = [[SkOptionListItem alloc] init];
List.fItem = item;
List.fOptions = [[SkOptionListController alloc] initWithStyle:UITableViewStyleGrouped];
int count = 0;
SkOSMenu::FindListItemCount(*item->getEvent(), &count);
SkTArray<SkString> options;
options.resize_back(count);
SkOSMenu::FindListItems(*item->getEvent(), &options.front());
for (int i = 0; i < count; ++i)
[List.fOptions addOption:[NSString stringWithUTF8String:options[i].c_str()]];
SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &value);
List.fOptions.fSelectedIndex = value;
List.fCell = [self createList:title
default:[List.fOptions getSelectedOption]];
List.fOptions.fParentCell = List.fCell;
[fItems addObject:List];
[List release];
}
else {
SkOptionItem* option = [[SkOptionItem alloc] init];
option.fItem = item;
bool state = false;
SkString str;
SkOSMenu::TriState tristate;
switch (item->getType()) {
case SkOSMenu::kAction_Type:
option.fCell = [self createAction:title];
break;
case SkOSMenu::kSwitch_Type:
SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state);
option.fCell = [self createSwitch:title default:(BOOL)state];
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:title
min:min
max:max
default:value];
break;
case SkOSMenu::kTriState_Type:
SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate);
option.fCell = [self createTriState:title default:(int)tristate];
break;
case SkOSMenu::kTextField_Type:
SkOSMenu::FindText(*item->getEvent(), item->getSlotName(), &str);
option.fCell = [self createTextField:title
default:[NSString stringWithUTF8String:str.c_str()]];
break;
default:
break;
}
[fItems addObject:option];
[option release];
}
}
}
- (void)valueChanged:(id)sender {
UITableViewCell* cell = (UITableViewCell*)(((UIView*)sender).superview);
NSUInteger index = [self convertPathToIndex:[self.tableView indexPathForCell:cell]];
SkOptionItem* item = (SkOptionItem*)[fItems objectAtIndex:index];
if ([sender isKindOfClass:[UISlider class]]) {//Slider
UISlider* slider = (UISlider *)sender;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%1.1f", slider.value];
item.fItem->setScalar(slider.value);
}
else if ([sender isKindOfClass:[UISwitch class]]) {//Switch
UISwitch* switch_ = (UISwitch *)sender;
item.fItem->setBool(switch_.on);
}
else if ([sender isKindOfClass:[UITextField class]]) { //TextField
UITextField* textField = (UITextField *)sender;
[textField resignFirstResponder];
item.fItem->setString([textField.text UTF8String]);
}
else if ([sender isKindOfClass:[UISegmentedControl class]]) { //Action
UISegmentedControl* segmented = (UISegmentedControl *)sender;
SkOSMenu::TriState state;
if (2 == segmented.selectedSegmentIndex) {
state = SkOSMenu::kMixedState;
} else {
state = (SkOSMenu::TriState)segmented.selectedSegmentIndex;
}
item.fItem->setTriState(state);
}
else{
NSLog(@"unknown");
}
item.fItem->postEvent();
}
- (UITableViewCell*)createAction:(NSString*)title {
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
return cell;
}
- (UITableViewCell*)createSwitch:(NSString*)title default:(BOOL)state {
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch* switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
[switchView setOn:state animated:NO];
[switchView addTarget:self
action:@selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
cell.accessoryView = switchView;
[switchView release];
return cell;
}
- (UITableViewCell*)createSlider:(NSString*)title
min:(float)min
max:(float)max
default:(float)value {
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UISlider* sliderView = [[UISlider alloc] init];
sliderView.value = value;
sliderView.minimumValue = min;
sliderView.maximumValue = max;
[sliderView addTarget:self
action:@selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
cell.detailTextLabel.text = [NSString stringWithFormat:@"%1.1f", value];
cell.accessoryView = sliderView;
[sliderView release];
return cell;
}
- (UITableViewCell*)createTriState:(NSString*)title default:(int)index {
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSArray* items = [NSArray arrayWithObjects:@"Off", @"On", @"Mixed", nil];
UISegmentedControl* segmented = [[UISegmentedControl alloc] initWithItems:items];
segmented.selectedSegmentIndex = (index == -1) ? 2 : index;
segmented.segmentedControlStyle = UISegmentedControlStyleBar;
[segmented addTarget:self
action:@selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
cell.accessoryView = segmented;
[segmented release];
return cell;
}
- (UITableViewCell*)createTextField:(NSString*)title
default:(NSString*)value {
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UITextField* textField = [[UITextField alloc]
initWithFrame:CGRectMake(0, 10, 150, 25)];
textField.adjustsFontSizeToFitWidth = YES;
textField.textAlignment = NSTextAlignmentRight;
textField.textColor = cell.detailTextLabel.textColor;
textField.placeholder = value;
textField.returnKeyType = UIReturnKeyDone;
[textField addTarget:self
action:@selector(valueChanged:)
forControlEvents:UIControlEventEditingDidEndOnExit];
cell.accessoryView = textField;
[textField release];
return cell;
}
- (UITableViewCell*)createList:(NSString*)title default:(NSString*)value{
UITableViewCell* cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:nil] autorelease];
cell.textLabel.text = title;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.detailTextLabel.text = value;
return cell;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return fMenus->count();
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [NSString stringWithUTF8String:(*fMenus)[section]->getTitle()];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return (*fMenus)[section]->getCount();
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return ((SkOptionItem*)[fItems objectAtIndex:[self convertPathToIndex:indexPath]]).fCell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
id item = [fItems objectAtIndex:[self convertPathToIndex:indexPath]];
if ([item isKindOfClass:[SkOptionListItem class]]) {
SkOptionListItem* list = (SkOptionListItem*)item;
self.fCurrentList = list;
self.navigationController.delegate = self;
[self.navigationController pushViewController:list.fOptions animated:YES];
}
else if ([item isKindOfClass:[SkOptionItem class]]) {
if (UITableViewCellSelectionStyleNone != cell.selectionStyle) { //Actions
SkOptionItem* action = (SkOptionItem*)item;
action.fItem->postEvent();
}
}
else{
NSLog(@"unknown");
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark -
#pragma mark Navigation controller delegate
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated {
if (self == viewController) { //when a List option is popped, trigger event
NSString* selectedOption = [fCurrentList.fOptions getSelectedOption];
fCurrentList.fCell.detailTextLabel.text = selectedOption;
fCurrentList.fItem->setInt(fCurrentList.fOptions.fSelectedIndex);
fCurrentList.fItem->postEvent();
}
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
self.fItems = nil;
[super dealloc];
}
@end