# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1617661099 0 # Node ID 5e0507e67c5d7c957b4f3426fc1a1c9a99008eb7 # Parent b0e6f8f0a1ff344a5a3b6ac0dbd21b6cc5c292db iOS: Initial implementation of DWComboBox, not fully functional yet. diff -r b0e6f8f0a1ff -r 5e0507e67c5d ios/dw.m --- a/ios/dw.m Mon Apr 05 15:29:33 2021 +0000 +++ b/ios/dw.m Mon Apr 05 22:18:19 2021 +0000 @@ -2283,6 +2283,146 @@ } @end +@interface DWComboBox : UITextField +{ + UIPickerView* pickerView; + NSMutableArray* dataArray; + UIBarStyle toolbarStyle; + int selectedIndex; +} +-(void)setToolbarStyle:(UIBarStyle)style; +-(void)append:(NSString *)item; +-(void)insert:(NSString *)item atIndex:(int)index; +-(void)clear; +-(int)count; +-(NSString *)getTextAtIndex:(int)index; +-(void)setText:(NSString *)item atIndex:(int)index; +-(void)deleteAtIndex:(int)index; +-(int)selectedIndex; +@end + +@implementation DWComboBox +-(id)init +{ + self = [super init]; + if(self) + { + [self setDelegate:self]; + + /* Set UI defaults */ + toolbarStyle = UIBarStyleDefault; + + /* Hide the caret and its blinking */ + [[self valueForKey:@"textInputTraits"] + setValue:[UIColor clearColor] + forKey:@"insertionPointColor"]; + + /* Setup the arrow image */ + UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom]; + UIImage *image = [UIImage systemImageNamed:@"chevron.down"]; + [imageButton setImage:image forState:UIControlStateNormal]; + [self setRightView:imageButton]; + [self setRightViewMode:UITextFieldViewModeAlways]; + [imageButton addTarget:self action:@selector(showPicker:) forControlEvents:UIControlEventTouchUpInside]; + selectedIndex = -1; + } + return self; +} +-(void)setToolbarStyle:(UIBarStyle)style { toolbarStyle = style; } +-(void)append:(NSString *)item { if(item) [dataArray addObject:item]; } +-(void)insert:(NSString *)item atIndex:(int)index { if(item) [dataArray insertObject:item atIndex:index]; } +-(void)clear { [dataArray removeAllObjects]; } +-(int)count { return (int)[dataArray count]; } +-(NSString *)getTextAtIndex:(int)index +{ + if(index > -1 && index < [dataArray count]) + return [dataArray objectAtIndex:index]; + return nil; +} +-(void)setText:(NSString *)item atIndex:(int)index +{ + if(item && index > -1 && index < [dataArray count]) + [dataArray replaceObjectAtIndex:index withObject:item]; +} +-(void)deleteAtIndex:(int)index { if(index > -1 && index < [dataArray count]) [dataArray removeObjectAtIndex:index]; } +-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } +-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + selectedIndex = (int)row; + [self setText:[dataArray objectAtIndex:row]]; + [self sendActionsForControlEvents:UIControlEventValueChanged]; + _dw_event_handler(self, DW_INT_TO_POINTER(selectedIndex), 11); +} +-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return [dataArray count]; } +-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + return [dataArray objectAtIndex:row]; +} +-(void)doneClicked:(id)sender +{ + /* Hides the pickerView */ + [self resignFirstResponder]; + + if([[self text] length] == 0 || ![dataArray containsObject:[self text]]) + { + selectedIndex = -1; + } + [self sendActionsForControlEvents:UIControlEventValueChanged]; +} +-(void)cancelClicked:(id)sender +{ + /* Hides the pickerView */ + [pickerView resignFirstResponder]; +} +-(void)showPicker:(id)sender +{ + pickerView = [[UIPickerView alloc] init]; + [pickerView setDataSource:self]; + [pickerView setDelegate:self]; + + /* If the text field is empty show the place holder otherwise show the last selected option */ + if([[self text] length] == 0 || ![dataArray containsObject:[self text]]) + { + [pickerView selectRow:0 inComponent:0 animated:YES]; + } + else + { + if([dataArray containsObject:[self text]]) + { + [pickerView selectRow:[dataArray indexOfObject:[self text]] inComponent:0 animated:YES]; + } + } + + UIToolbar* toolbar = [[UIToolbar alloc] init]; + [toolbar setBarStyle:toolbarStyle]; + [toolbar sizeToFit]; + + /* Space between buttons */ + UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil]; + + UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] + initWithTitle:@"Done" + style:UIBarButtonItemStyleDone + target:self + action:@selector(doneClicked:)]; + + UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] + initWithTitle:@"Cancel" + style:UIBarButtonItemStylePlain + target:self + action:@selector(cancelClicked:)]; + + [toolbar setItems:[NSArray arrayWithObjects:cancelButton, flexibleSpace, doneButton, nil]]; + + /* Custom input view */ + [self setInputView:pickerView]; + [self setInputAccessoryView:toolbar]; +} +-(int)selectedIndex { return selectedIndex; } +@end + /* Subclass for a MDI type * This is just a box for display purposes... but it is a * unique class so it can be identified when creating windows. @@ -4187,7 +4327,13 @@ DW_FUNCTION_INIT; id object = handle; - if([object isMemberOfClass:[DWContainer class]]) + if([object isMemberOfClass:[DWComboBox class]]) + { + DWComboBox *combo = handle; + + [combo append:[NSString stringWithUTF8String:text]]; + } + else if([object isMemberOfClass:[DWContainer class]]) { DWContainer *cont = handle; NSString *nstr = [NSString stringWithUTF8String:text]; @@ -4215,7 +4361,13 @@ DW_FUNCTION_INIT; id object = handle; - if([object isMemberOfClass:[DWContainer class]]) + if([object isMemberOfClass:[DWComboBox class]]) + { + DWComboBox *combo = handle; + + [combo insert:[NSString stringWithUTF8String:text] atIndex:pos]; + } + else if([object isMemberOfClass:[DWContainer class]]) { DWContainer *cont = handle; NSString *nstr = [NSString stringWithUTF8String:text]; @@ -4243,7 +4395,19 @@ DW_FUNCTION_INIT; id object = handle; - if([object isMemberOfClass:[DWContainer class]]) + if([object isMemberOfClass:[DWComboBox class]]) + { + DWComboBox *combo = handle; + int z; + + for(z=0;z