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