1#import "SkOptionsTableViewController.h" 2#include "SkEvent.h" 3#include "SkTArray.h" 4 5@implementation SkOptionItem 6@synthesize fCell, fItem; 7- (void)dealloc { 8 [fCell release]; 9 [super dealloc]; 10} 11@end 12 13@implementation SkOptionListItem 14@synthesize fOptions; 15- (void)dealloc { 16 [fOptions release]; 17 [super dealloc]; 18} 19@end 20 21@implementation SkOptionsTableViewController 22 23@synthesize fItems, fCurrentList; 24 25- (id)initWithStyle:(UITableViewStyle)style { 26 self = [super initWithStyle:style]; 27 if (self) { 28 self.fItems = [NSMutableArray array]; 29 } 30 return self; 31} 32 33//SkUIViewOptionsDelegate 34- (void) view:(SkUIView*)view didAddMenu:(const SkOSMenu*)menu {} 35- (void) view:(SkUIView*)view didUpdateMenu:(SkOSMenu*)menu { 36 [self updateMenu:menu]; 37} 38 39- (NSUInteger)convertPathToIndex:(NSIndexPath*)path { 40 NSUInteger index = 0; 41 for (NSInteger i = 0; i < path.section; ++i) { 42 index += (*fMenus)[i]->getCount(); 43 } 44 return index + path.row; 45} 46 47- (void)registerMenus:(const SkTDArray<SkOSMenu*>*)menus { 48 fMenus = menus; 49 for (NSUInteger i = 0; i < fMenus->count(); ++i) { 50 [self loadMenu:(*fMenus)[i]]; 51 } 52} 53 54- (void)updateMenu:(SkOSMenu*)menu { 55 // the first menu is always assumed to be the static, the second is 56 // repopulated every time over and over again 57 int menuIndex = fMenus->find(menu); 58 if (menuIndex >= 0 && menuIndex < fMenus->count()) { 59 NSUInteger first = 0; 60 for (NSInteger i = 0; i < menuIndex; ++i) { 61 first += (*fMenus)[i]->getCount(); 62 } 63 [fItems removeObjectsInRange:NSMakeRange(first, [fItems count] - first)]; 64 [self loadMenu:menu]; 65 } 66 [self.tableView reloadData]; 67} 68 69- (void)loadMenu:(SkOSMenu*)menu { 70 const SkOSMenu::Item* menuitems[menu->getCount()]; 71 menu->getItems(menuitems); 72 for (int i = 0; i < menu->getCount(); ++i) { 73 const SkOSMenu::Item* item = menuitems[i]; 74 NSString* title = [NSString stringWithUTF8String:item->getLabel()]; 75 76 if (SkOSMenu::kList_Type == item->getType()) { 77 int value = 0; 78 SkOptionListItem* List = [[SkOptionListItem alloc] init]; 79 80 List.fItem = item; 81 List.fOptions = [[SkOptionListController alloc] initWithStyle:UITableViewStyleGrouped]; 82 83 int count = 0; 84 SkOSMenu::FindListItemCount(*item->getEvent(), &count); 85 SkTArray<SkString> options; 86 options.resize_back(count); 87 SkOSMenu::FindListItems(*item->getEvent(), &options.front()); 88 for (int i = 0; i < count; ++i) 89 [List.fOptions addOption:[NSString stringWithUTF8String:options[i].c_str()]]; 90 SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &value); 91 92 List.fOptions.fSelectedIndex = value; 93 List.fCell = [self createList:title 94 default:[List.fOptions getSelectedOption]]; 95 List.fOptions.fParentCell = List.fCell; 96 [fItems addObject:List]; 97 [List release]; 98 } 99 else { 100 SkOptionItem* option = [[SkOptionItem alloc] init]; 101 option.fItem = item; 102 103 bool state = false; 104 SkString str; 105 SkOSMenu::TriState tristate; 106 switch (item->getType()) { 107 case SkOSMenu::kAction_Type: 108 option.fCell = [self createAction:title]; 109 break; 110 case SkOSMenu::kSwitch_Type: 111 SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state); 112 option.fCell = [self createSwitch:title default:(BOOL)state]; 113 break; 114 case SkOSMenu::kSlider_Type: 115 SkScalar min, max, value; 116 SkOSMenu::FindSliderValue(*item->getEvent(), item->getSlotName(), &value); 117 SkOSMenu::FindSliderMin(*item->getEvent(), &min); 118 SkOSMenu::FindSliderMax(*item->getEvent(), &max); 119 option.fCell = [self createSlider:title 120 min:min 121 max:max 122 default:value]; 123 break; 124 case SkOSMenu::kTriState_Type: 125 SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate); 126 option.fCell = [self createTriState:title default:(int)tristate]; 127 break; 128 case SkOSMenu::kTextField_Type: 129 SkOSMenu::FindText(*item->getEvent(), item->getSlotName(), &str); 130 option.fCell = [self createTextField:title 131 default:[NSString stringWithUTF8String:str.c_str()]]; 132 break; 133 default: 134 break; 135 } 136 [fItems addObject:option]; 137 [option release]; 138 } 139 } 140} 141 142- (void)valueChanged:(id)sender { 143 UITableViewCell* cell = (UITableViewCell*)(((UIView*)sender).superview); 144 NSUInteger index = [self convertPathToIndex:[self.tableView indexPathForCell:cell]]; 145 SkOptionItem* item = (SkOptionItem*)[fItems objectAtIndex:index]; 146 if ([sender isKindOfClass:[UISlider class]]) {//Slider 147 UISlider* slider = (UISlider *)sender; 148 cell.detailTextLabel.text = [NSString stringWithFormat:@"%1.1f", slider.value]; 149 item.fItem->setScalar(slider.value); 150 } 151 else if ([sender isKindOfClass:[UISwitch class]]) {//Switch 152 UISwitch* switch_ = (UISwitch *)sender; 153 item.fItem->setBool(switch_.on); 154 } 155 else if ([sender isKindOfClass:[UITextField class]]) { //TextField 156 UITextField* textField = (UITextField *)sender; 157 [textField resignFirstResponder]; 158 item.fItem->setString([textField.text UTF8String]); 159 } 160 else if ([sender isKindOfClass:[UISegmentedControl class]]) { //Action 161 UISegmentedControl* segmented = (UISegmentedControl *)sender; 162 SkOSMenu::TriState state; 163 if (2 == segmented.selectedSegmentIndex) { 164 state = SkOSMenu::kMixedState; 165 } else { 166 state = (SkOSMenu::TriState)segmented.selectedSegmentIndex; 167 } 168 item.fItem->setTriState(state); 169 } 170 else{ 171 NSLog(@"unknown"); 172 } 173 item.fItem->postEvent(); 174} 175 176- (UITableViewCell*)createAction:(NSString*)title { 177 UITableViewCell* cell = [[[UITableViewCell alloc] 178 initWithStyle:UITableViewCellStyleValue1 179 reuseIdentifier:nil] autorelease]; 180 cell.textLabel.text = title; 181 return cell; 182} 183 184- (UITableViewCell*)createSwitch:(NSString*)title default:(BOOL)state { 185 UITableViewCell* cell = [[[UITableViewCell alloc] 186 initWithStyle:UITableViewCellStyleValue1 187 reuseIdentifier:nil] autorelease]; 188 cell.textLabel.text = title; 189 cell.selectionStyle = UITableViewCellSelectionStyleNone; 190 UISwitch* switchView = [[UISwitch alloc] initWithFrame:CGRectZero]; 191 [switchView setOn:state animated:NO]; 192 [switchView addTarget:self 193 action:@selector(valueChanged:) 194 forControlEvents:UIControlEventValueChanged]; 195 cell.accessoryView = switchView; 196 [switchView release]; 197 return cell; 198} 199 200- (UITableViewCell*)createSlider:(NSString*)title 201 min:(float)min 202 max:(float)max 203 default:(float)value { 204 UITableViewCell* cell = [[[UITableViewCell alloc] 205 initWithStyle:UITableViewCellStyleValue1 206 reuseIdentifier:nil] autorelease]; 207 cell.textLabel.text = title; 208 cell.selectionStyle = UITableViewCellSelectionStyleNone; 209 UISlider* sliderView = [[UISlider alloc] init]; 210 sliderView.value = value; 211 sliderView.minimumValue = min; 212 sliderView.maximumValue = max; 213 [sliderView addTarget:self 214 action:@selector(valueChanged:) 215 forControlEvents:UIControlEventValueChanged]; 216 cell.detailTextLabel.text = [NSString stringWithFormat:@"%1.1f", value]; 217 cell.accessoryView = sliderView; 218 [sliderView release]; 219 return cell; 220} 221 222- (UITableViewCell*)createTriState:(NSString*)title default:(int)index { 223 UITableViewCell* cell = [[[UITableViewCell alloc] 224 initWithStyle:UITableViewCellStyleValue1 225 reuseIdentifier:nil] autorelease]; 226 cell.textLabel.text = title; 227 cell.selectionStyle = UITableViewCellSelectionStyleNone; 228 NSArray* items = [NSArray arrayWithObjects:@"Off", @"On", @"Mixed", nil]; 229 UISegmentedControl* segmented = [[UISegmentedControl alloc] initWithItems:items]; 230 segmented.selectedSegmentIndex = (index == -1) ? 2 : index; 231 segmented.segmentedControlStyle = UISegmentedControlStyleBar; 232 [segmented addTarget:self 233 action:@selector(valueChanged:) 234 forControlEvents:UIControlEventValueChanged]; 235 cell.accessoryView = segmented; 236 [segmented release]; 237 return cell; 238} 239 240- (UITableViewCell*)createTextField:(NSString*)title 241 default:(NSString*)value { 242 UITableViewCell* cell = [[[UITableViewCell alloc] 243 initWithStyle:UITableViewCellStyleValue1 244 reuseIdentifier:nil] autorelease]; 245 cell.textLabel.text = title; 246 cell.selectionStyle = UITableViewCellSelectionStyleNone; 247 UITextField* textField = [[UITextField alloc] 248 initWithFrame:CGRectMake(0, 10, 150, 25)]; 249 textField.adjustsFontSizeToFitWidth = YES; 250 textField.textAlignment = NSTextAlignmentRight; 251 textField.textColor = cell.detailTextLabel.textColor; 252 textField.placeholder = value; 253 textField.returnKeyType = UIReturnKeyDone; 254 [textField addTarget:self 255 action:@selector(valueChanged:) 256 forControlEvents:UIControlEventEditingDidEndOnExit]; 257 cell.accessoryView = textField; 258 [textField release]; 259 return cell; 260} 261 262- (UITableViewCell*)createList:(NSString*)title default:(NSString*)value{ 263 UITableViewCell* cell = [[[UITableViewCell alloc] 264 initWithStyle:UITableViewCellStyleValue1 265 reuseIdentifier:nil] autorelease]; 266 cell.textLabel.text = title; 267 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 268 cell.detailTextLabel.text = value; 269 return cell; 270} 271 272#pragma mark - 273#pragma mark Table view data source 274 275- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 276 return fMenus->count(); 277} 278 279- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 280 return [NSString stringWithUTF8String:(*fMenus)[section]->getTitle()]; 281} 282 283- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 284 return (*fMenus)[section]->getCount(); 285} 286 287- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 288 return ((SkOptionItem*)[fItems objectAtIndex:[self convertPathToIndex:indexPath]]).fCell; 289} 290 291#pragma mark - 292#pragma mark Table view delegate 293 294- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 295 UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath]; 296 id item = [fItems objectAtIndex:[self convertPathToIndex:indexPath]]; 297 298 if ([item isKindOfClass:[SkOptionListItem class]]) { 299 SkOptionListItem* list = (SkOptionListItem*)item; 300 self.fCurrentList = list; 301 self.navigationController.delegate = self; 302 [self.navigationController pushViewController:list.fOptions animated:YES]; 303 } 304 else if ([item isKindOfClass:[SkOptionItem class]]) { 305 if (UITableViewCellSelectionStyleNone != cell.selectionStyle) { //Actions 306 SkOptionItem* action = (SkOptionItem*)item; 307 action.fItem->postEvent(); 308 } 309 } 310 else{ 311 NSLog(@"unknown"); 312 } 313 314 [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 315} 316 317#pragma mark - 318#pragma mark Navigation controller delegate 319 320- (void)navigationController:(UINavigationController *)navigationController 321 willShowViewController:(UIViewController *)viewController 322 animated:(BOOL)animated { 323 if (self == viewController) { //when a List option is popped, trigger event 324 NSString* selectedOption = [fCurrentList.fOptions getSelectedOption]; 325 fCurrentList.fCell.detailTextLabel.text = selectedOption; 326 fCurrentList.fItem->setInt(fCurrentList.fOptions.fSelectedIndex); 327 fCurrentList.fItem->postEvent(); 328 } 329} 330 331#pragma mark - 332#pragma mark Memory management 333 334- (void)dealloc { 335 self.fItems = nil; 336 [super dealloc]; 337} 338 339@end