| #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 |