Home | History | Annotate | Download | only in Shared
      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