1#import "Parameter.h" 2#import "Utils.h" 3 4@implementation Parameter 5- (id)init 6{ 7 self = [super init]; 8 if(self) { 9 label = [[UILabel alloc] init]; 10 // set font size at 90% of default size 11 label.font = [label.font fontWithSize:(0.9 * label.font.pointSize)]; 12 [label setBackgroundColor:[UIColor clearColor]]; 13 } 14 return self; 15} 16 17- (void)refresh 18{ 19 return; 20} 21 22- (NSString *)getName 23{ 24 return name; 25} 26 27- (UILabel *)getLabel 28{ 29 return label; 30} 31 32- (void)setFrame:(CGRect)frame 33{ 34 return; 35} 36 37- (void)setLabelFrame:(CGRect)frame 38{ 39 [label setFrame:frame]; 40} 41 42- (void)editValue 43{ 44 if(onelab_cb("check") > 0) { 45 [[NSNotificationCenter defaultCenter] postNotificationName:@"requestRender" 46 object:nil]; 47 [[NSNotificationCenter defaultCenter] 48 postNotificationName:@"refreshParameters" 49 object:nil]; 50 } 51} 52 53+ (double)getHeight 54{ 55 return 65.0f; 56} 57@end 58 59@implementation ParameterStringList 60- (id)initWithString:(onelab::string)string 61{ 62 self = [super init]; 63 if(self) { 64 [label setText:[Utils getStringFromCString:string.getShortName().c_str()]]; 65 name = [Utils getStringFromCString:string.getName().c_str()]; 66 button = [UIButton buttonWithType:UIButtonTypeSystem]; 67 [button addTarget:self 68 action:@selector(selectValue) 69 forControlEvents:UIControlEventTouchDown]; 70 [button setTitle:[Utils getStringFromCString:string.getValue().c_str()] 71 forState:UIControlStateNormal]; 72 [button setEnabled:(string.getReadOnly() ? FALSE : TRUE)]; 73 [label setEnabled:(string.getReadOnly() ? FALSE : TRUE)]; 74 } 75 return self; 76} 77 78- (void)selectValue 79{ 80 std::vector<onelab::string> string; 81 onelab::server::instance()->get(string, [name UTF8String]); 82 if(string.size() < 1) return; 83 UIAlertController *alertController = [UIAlertController 84 alertControllerWithTitle:nil 85 message:nil 86 preferredStyle:UIAlertControllerStyleActionSheet]; 87 [alertController 88 addAction:[UIAlertAction actionWithTitle:@"Cancel" 89 style:UIAlertActionStyleCancel 90 handler:^(UIAlertAction *action){}]]; 91 std::vector<std::string> choices = string[0].getChoices(); 92 for(unsigned int i = 0; i < choices.size(); i++) { 93 NSString *t = [Utils getStringFromCString:choices[i].c_str()]; 94 [alertController 95 addAction:[UIAlertAction 96 actionWithTitle:t 97 style:UIAlertActionStyleDefault 98 handler:^(UIAlertAction *action) { 99 [self updateString:string[0] withValue:choices[i]]; 100 [self->button 101 setTitle:[Utils getStringFromCString:choices[i] 102 .c_str()] 103 forState:UIControlStateNormal]; 104 }]]; 105 } 106 [alertController setModalPresentationStyle:UIModalPresentationPopover]; 107 UIPopoverPresentationController *popPresenter = 108 [alertController popoverPresentationController]; 109 popPresenter.sourceView = button; 110 popPresenter.sourceRect = button.bounds; 111 // FIXME: is traverseResponderChainForUIViewController a good idea? 112 [[Utils traverseResponderChainForUIViewController:button] 113 presentViewController:alertController 114 animated:YES 115 completion:nil]; 116} 117 118- (void)updateString:(onelab::string)s withValue:(std::string)v 119{ 120 s.setValue(v); 121 onelab::server::instance()->set(s); 122 [super editValue]; 123} 124 125- (void)refresh 126{ 127 std::vector<onelab::string> string; 128 onelab::server::instance()->get(string, [name UTF8String]); 129 if(string.size() < 1) return; 130 [button setTitle:[Utils getStringFromCString:string[0].getValue().c_str()] 131 forState:UIControlStateNormal]; 132 [button setEnabled:(string[0].getReadOnly() ? FALSE : TRUE)]; 133 [label setEnabled:(string[0].getReadOnly() ? FALSE : TRUE)]; 134} 135 136- (void)setFrame:(CGRect)frame 137{ 138 [button setFrame:frame]; 139} 140 141- (UIButton *)getUIView 142{ 143 return button; 144} 145 146@end 147 148@implementation ParameterNumberList 149- (id)initWithNumber:(onelab::number)number 150{ 151 self = [super init]; 152 if(self) { 153 [label setText:[Utils getStringFromCString:number.getShortName().c_str()]]; 154 name = [Utils getStringFromCString:number.getName().c_str()]; 155 button = [UIButton buttonWithType:UIButtonTypeSystem]; 156 [button addTarget:self 157 action:@selector(selectValue) 158 forControlEvents:UIControlEventTouchDown]; 159 [button 160 setTitle:[Utils 161 getStringFromCString:number.getValueLabel(number.getValue()) 162 .c_str()] 163 forState:UIControlStateNormal]; 164 [button setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 165 [label setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 166 } 167 return self; 168} 169 170- (void)selectValue 171{ 172 std::vector<onelab::number> numbers; 173 onelab::server::instance()->get(numbers, [name UTF8String]); 174 if(numbers.size() < 1) return; 175 UIAlertController *alertController = [UIAlertController 176 alertControllerWithTitle:nil 177 message:nil 178 preferredStyle:UIAlertControllerStyleActionSheet]; 179 [alertController 180 addAction:[UIAlertAction actionWithTitle:@"Cancel" 181 style:UIAlertActionStyleCancel 182 handler:^(UIAlertAction *action){}]]; 183 std::vector<double> choices = numbers[0].getChoices(); 184 for(unsigned int i = 0; i < choices.size(); i++) { 185 NSString *t = 186 [Utils getStringFromCString:numbers[0].getValueLabel(choices[i]).c_str()]; 187 [alertController 188 addAction:[UIAlertAction 189 actionWithTitle:t 190 style:UIAlertActionStyleDefault 191 handler:^(UIAlertAction *action) { 192 [self updateNumber:numbers[0] withValue:choices[i]]; 193 [self->button 194 setTitle:[Utils 195 getStringFromCString:numbers[0] 196 .getValueLabel( 197 i) 198 .c_str()] 199 forState:UIControlStateNormal]; 200 }]]; 201 } 202 [alertController setModalPresentationStyle:UIModalPresentationPopover]; 203 UIPopoverPresentationController *popPresenter = 204 [alertController popoverPresentationController]; 205 popPresenter.sourceView = button; 206 popPresenter.sourceRect = button.bounds; 207 // FIXME: is traverseResponderChainForUIViewController a good idea? 208 [[Utils traverseResponderChainForUIViewController:button] 209 presentViewController:alertController 210 animated:YES 211 completion:nil]; 212} 213 214- (void)updateNumber:(onelab::number)n withValue:(double)v 215{ 216 n.setValue(v); 217 onelab::server::instance()->set(n); 218 [super editValue]; 219} 220 221- (void)refresh 222{ 223 std::vector<onelab::number> number; 224 onelab::server::instance()->get(number, [name UTF8String]); 225 if(number.size() < 1) return; 226 [button 227 setTitle:[Utils getStringFromCString:number[0] 228 .getValueLabel(number[0].getValue()) 229 .c_str()] 230 forState:UIControlStateNormal]; 231 [button setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 232 [label setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 233} 234 235- (void)setFrame:(CGRect)frame 236{ 237 [button setFrame:frame]; 238} 239 240- (UIButton *)getUIView 241{ 242 return button; 243} 244 245@end 246 247@implementation ParameterNumberCheckbox 248- (id)initWithNumber:(onelab::number)number 249{ 250 self = [super init]; 251 if(self) { 252 [label setText:[Utils getStringFromCString:number.getShortName().c_str()]]; 253 name = [Utils getStringFromCString:number.getName().c_str()]; 254 checkbox = [[UISwitch alloc] init]; 255 [checkbox setOn:(number.getValue() == 1)]; 256 [checkbox addTarget:self 257 action:@selector(valueChange:) 258 forControlEvents:UIControlEventValueChanged]; 259 [checkbox setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 260 [label setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 261 } 262 return self; 263} 264 265- (void)refresh 266{ 267 std::vector<onelab::number> number; 268 onelab::server::instance()->get(number, [name UTF8String]); 269 if(number.size() < 1) return; 270 [checkbox setSelected:(number[0].getValue() == 1)]; 271 [checkbox setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 272 [label setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 273} 274 275- (void)valueChange:(UISwitch *)sender 276{ 277 std::vector<onelab::number> number; 278 onelab::server::instance()->get(number, [name UTF8String]); 279 if(number.size() < 1) return; 280 number[0].setValue(([sender isOn]) ? 1 : 0); 281 onelab::server::instance()->set(number[0]); 282 [super editValue]; 283} 284 285- (void)setFrame:(CGRect)frame 286{ 287 [checkbox setFrame:frame]; 288} 289 290- (UISwitch *)getCheckbox 291{ 292 return checkbox; 293} 294 295+ (double)getHeight 296{ 297 return 45.0f; 298} 299@end 300 301@implementation ParameterNumberStepper 302- (id)initWithNumber:(onelab::number)number 303{ 304 self = [super init]; 305 if(self) { 306 name = [Utils getStringFromCString:number.getName().c_str()]; 307 stepper = [[UIStepper alloc] init]; 308 // make the stepper a bit smaller 309 stepper.transform = CGAffineTransformMakeScale(0.8, 0.8); 310 [stepper setValue:number.getValue()]; 311 [stepper setStepValue:1]; 312 [stepper setMaximumValue:number.getMax()]; 313 [stepper setMinimumValue:number.getMin()]; 314 [stepper addTarget:self 315 action:@selector(stepperValueChanged:) 316 forControlEvents:UIControlEventValueChanged]; 317 [label 318 setText:[NSString 319 stringWithFormat:@"%@ %d", 320 [Utils 321 getStringFromCString:number.getShortName() 322 .c_str()], 323 (int)number.getValue()]]; 324 [stepper setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 325 [label setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 326 } 327 return self; 328} 329 330- (void)stepperValueChanged:(UIStepper *)sender 331{ 332 std::vector<onelab::number> number; 333 onelab::server::instance()->get(number, [name UTF8String]); 334 if(number.size() < 1) return; 335 number[0].setValue(sender.value); 336 onelab::server::instance()->set(number[0]); 337 [label 338 setText:[NSString 339 stringWithFormat:@"%@ %d", 340 [Utils getStringFromCString:number[0] 341 .getShortName() 342 .c_str()], 343 (int)number[0].getValue()]]; 344 [super editValue]; 345} 346 347- (void)refresh 348{ 349 std::vector<onelab::number> number; 350 onelab::server::instance()->get(number, [name UTF8String]); 351 if(number.size() < 1) return; 352 [stepper setValue:number[0].getValue()]; 353 [label 354 setText:[NSString 355 stringWithFormat:@"%@ %d", 356 [Utils getStringFromCString:number[0] 357 .getShortName() 358 .c_str()], 359 (int)number[0].getValue()]]; 360 [stepper setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 361 [label setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 362} 363 364- (void)setFrame:(CGRect)frame 365{ 366 [stepper setFrame:frame]; 367} 368 369- (UIStepper *)getStepper 370{ 371 return stepper; 372} 373 374@end 375 376@implementation ParameterNumberRange 377- (id)initWithNumber:(onelab::number)number 378{ 379 self = [super init]; 380 if(self) { 381 name = [Utils getStringFromCString:number.getName().c_str()]; 382 slider = [[UISlider alloc] init]; 383 [slider setMaximumValue:number.getMax()]; 384 [slider setMinimumValue:number.getMin()]; 385 [slider setValue:number.getValue()]; 386 // TODO add step ? 387 [slider addTarget:self 388 action:@selector(sliderValueChanged:) 389 forControlEvents:UIControlEventTouchUpOutside]; 390 [slider addTarget:self 391 action:@selector(sliderValueChanged:) 392 forControlEvents:UIControlEventTouchUpInside]; 393 [label 394 setText:[NSString 395 stringWithFormat:@"%@ %g", 396 [Utils 397 getStringFromCString:number.getShortName() 398 .c_str()], 399 number.getValue()]]; 400 [slider setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 401 [label setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 402 } 403 return self; 404} 405 406- (void)refresh 407{ 408 std::vector<onelab::number> number; 409 onelab::server::instance()->get(number, [name UTF8String]); 410 if(number.size() < 1) return; 411 [slider setMaximumValue:number[0].getMax()]; 412 [slider setMinimumValue:number[0].getMin()]; 413 [slider setValue:number[0].getValue()]; 414 [label 415 setText:[NSString 416 stringWithFormat:@"%@ %g", 417 [Utils getStringFromCString:number[0] 418 .getShortName() 419 .c_str()], 420 number[0].getValue()]]; 421 [slider setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 422 [label setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 423} 424 425- (void)sliderValueChanged:(UISlider *)sender 426{ 427 std::vector<onelab::number> number; 428 onelab::server::instance()->get(number, [name UTF8String]); 429 if(number.size() < 1) return; 430 number[0].setValue(sender.value); 431 onelab::server::instance()->set(number[0]); 432 [label 433 setText:[NSString 434 stringWithFormat:@"%@ %g", 435 [Utils getStringFromCString:number[0] 436 .getShortName() 437 .c_str()], 438 number[0].getValue()]]; 439 [super editValue]; 440} 441 442- (void)setFrame:(CGRect)frame 443{ 444 [slider setFrame:frame]; 445} 446 447- (UISlider *)getSlider 448{ 449 return slider; 450} 451 452@end 453 454@implementation ParameterNumberTextbox 455- (id)initWithNumber:(onelab::number)number 456{ 457 self = [super init]; 458 if(self) { 459 [label setText:[Utils getStringFromCString:number.getShortName().c_str()]]; 460 name = [Utils getStringFromCString:number.getName().c_str()]; 461 textbox = [[UITextField alloc] init]; 462 [textbox setBorderStyle:UITextBorderStyleRoundedRect]; 463 [textbox setText:[NSString stringWithFormat:@"%g", number.getValue()]]; 464 [textbox setDelegate:self]; 465 UIToolbar *numberToolbar = 466 [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; 467 numberToolbar.items = [NSArray 468 arrayWithObjects: 469 [[UIBarButtonItem alloc] 470 initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 471 target:nil 472 action:nil], 473 [[UIBarButtonItem alloc] initWithTitle:@"Apply" 474 style:UIBarButtonItemStyleDone 475 target:self 476 action:@selector(doneWithNumberPad)], 477 nil]; 478 [numberToolbar sizeToFit]; 479 textbox.inputAccessoryView = numberToolbar; 480 [textbox setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 481 [label setEnabled:(number.getReadOnly() ? FALSE : TRUE)]; 482 } 483 return self; 484} 485 486- (void)refresh 487{ 488 std::vector<onelab::number> number; 489 onelab::server::instance()->get(number, [name UTF8String]); 490 if(number.size() < 1) return; 491 [textbox setText:[NSString stringWithFormat:@"%g", number[0].getValue()]]; 492 [textbox setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 493 [label setEnabled:(number[0].getReadOnly() ? FALSE : TRUE)]; 494 [textbox reloadInputViews]; 495} 496 497- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 498{ 499 std::vector<onelab::number> number; 500 onelab::server::instance()->get(number, [name UTF8String]); 501 if(number.size() < 1) return YES; 502 number[0].setValue([textField.text doubleValue]); 503 onelab::server::instance()->set(number[0]); 504 [textField setText:[NSString stringWithFormat:@"%g", number[0].getValue()]]; 505 [super editValue]; 506 return YES; 507} 508 509- (BOOL)textFieldShouldReturn:(UITextField *)textField 510{ 511 return [textField endEditing:YES]; 512} 513 514- (void)doneWithNumberPad 515{ 516 [textbox endEditing:YES]; 517} 518 519- (void)setFrame:(CGRect)frame 520{ 521 [textbox setFrame:frame]; 522} 523 524- (UITextField *)getTextbox 525{ 526 return textbox; 527} 528 529@end 530