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