From 636d2f27a9a2f4ed855d6d73a8fe497e1cf184fa Mon Sep 17 00:00:00 2001 From: Paul Gardiner Date: Mon, 14 Oct 2013 16:55:57 +0100 Subject: iOS: add support for selecting form choice fields --- platform/ios/Classes/MuChoiceFieldController.h | 20 + platform/ios/Classes/MuChoiceFieldController.m | 82 +++ platform/ios/Classes/MuChoiceFieldController.xib | 639 +++++++++++++++++++++++ platform/ios/Classes/MuDialogCreator.h | 1 + platform/ios/Classes/MuDocumentController.m | 9 + platform/ios/Classes/MuPageViewNormal.m | 78 ++- 6 files changed, 826 insertions(+), 3 deletions(-) create mode 100644 platform/ios/Classes/MuChoiceFieldController.h create mode 100644 platform/ios/Classes/MuChoiceFieldController.m create mode 100644 platform/ios/Classes/MuChoiceFieldController.xib (limited to 'platform/ios/Classes') diff --git a/platform/ios/Classes/MuChoiceFieldController.h b/platform/ios/Classes/MuChoiceFieldController.h new file mode 100644 index 00000000..d99f8cd5 --- /dev/null +++ b/platform/ios/Classes/MuChoiceFieldController.h @@ -0,0 +1,20 @@ +// +// MuChoiceFieldController.h +// MuPDF +// +// Copyright (c) 2013 Artifex Software, Inc. All rights reserved. +// + +#import + +@interface MuChoiceFieldController : UIViewController +{ + void (^okayBlock)(NSArray *); + NSArray *choices; + int selected; +} +@property (retain, nonatomic) IBOutlet UIPickerView *picker; +- (id)initWithChoices:(NSArray *)choices okayAction:(void (^)(NSArray *))block; +- (IBAction)okayTapped:(id)sender; +- (IBAction)cancelTapped:(id)sender; +@end diff --git a/platform/ios/Classes/MuChoiceFieldController.m b/platform/ios/Classes/MuChoiceFieldController.m new file mode 100644 index 00000000..ffd4c212 --- /dev/null +++ b/platform/ios/Classes/MuChoiceFieldController.m @@ -0,0 +1,82 @@ +// +// MuChoiceFieldController.m +// MuPDF +// +// Copyright (c) 2013 Artifex Software, Inc. All rights reserved. +// + +#import "MuChoiceFieldController.h" + +@interface MuChoiceFieldController () + +@end + +@implementation MuChoiceFieldController + +- (id)initWithChoices:(NSArray *)_choices okayAction:(void (^)(NSArray *))block +{ + self = [super initWithNibName:@"MuChoiceFieldController" bundle:nil]; + if (self) + { + okayBlock = Block_copy(block); + choices = [_choices retain]; + selected = -1; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + _picker.dataSource = self; + _picker.delegate = self; + // Do any additional setup after loading the view from its nib. +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)dealloc +{ + [okayBlock release]; + [choices release]; + [_picker release]; + [super dealloc]; +} + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return [choices count]; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + return [choices objectAtIndex:row]; +} + +- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + selected = row; +} + +- (IBAction)okayTapped:(id)sender +{ + if (selected > -1) + okayBlock([NSArray arrayWithObject:[choices objectAtIndex:selected]]); + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (IBAction)cancelTapped:(id)sender +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/platform/ios/Classes/MuChoiceFieldController.xib b/platform/ios/Classes/MuChoiceFieldController.xib new file mode 100644 index 00000000..0b225782 --- /dev/null +++ b/platform/ios/Classes/MuChoiceFieldController.xib @@ -0,0 +1,639 @@ + + + + 1552 + 11G63b + 3084 + 1138.51 + 569.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 2083 + + + IBNSLayoutConstraint + IBProxyObject + IBUIButton + IBUILabel + IBUIPickerView + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + + + 292 + {{20, 47}, {281, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Choose value + + 3 + MQA + + + 0 + 1 + + 1 + 17 + + + Helvetica + 17 + 16 + + NO + + + + 292 + {{20, 416}, {280, 44}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Okay + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + 2 + 15 + + + Helvetica-Bold + 15 + 16 + + + + + 292 + {{20, 476}, {281, 44}} + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + 1 + Cancel + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + + + 290 + {{20, 119}, {280, 216}} + + + + _NS:9 + IBCocoaTouchFramework + YES + + + {{0, 20}, {320, 548}} + + + + + 3 + MC4zMzMzMzMzMzMzAA + + + + IBUIScreenMetrics + + YES + + + + + + {320, 568} + {568, 320} + + + IBCocoaTouchFramework + Retina 4 Full Screen + 2 + + IBCocoaTouchFramework + + + + + + + view + + + + 3 + + + + picker + + + + 87 + + + + okayTapped: + + + 7 + + 88 + + + + cancelTapped: + + + 7 + + 89 + + + + + + 0 + + + + + + 1 + + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 4 + 0 + + 4 + 1 + + 29 + + 1000 + + 3 + 9 + 3 + + + + 4 + 0 + + 4 + 1 + + 89 + + 1000 + + 3 + 9 + 3 + + + + 9 + 0 + + 9 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 119 + + 1000 + + 3 + 9 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 3 + 0 + + 3 + 1 + + 47 + + 1000 + + 3 + 9 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + 11 + + + + + 22 + + + + + + 41 + + + + + 48 + + + + + 49 + + + + + 59 + + + + + + 60 + + + + + 62 + + + + + 64 + + + + + 68 + + + + + 73 + + + + + 74 + + + + + 8 + 0 + + 0 + 1 + + 216 + + 1000 + + 3 + 9 + 1 + + + + + + 76 + + + + + 83 + + + + + 81 + + + + + 82 + + + + + + + MuChoiceFieldController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + + + + + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 89 + + + + + MuChoiceFieldController + UIViewController + + id + id + + + + cancelTapped: + id + + + okayTapped: + id + + + + picker + UIPickerView + + + picker + + picker + UIPickerView + + + + IBProjectSource + ./Classes/MuChoiceFieldController.h + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + + 0 + IBCocoaTouchFramework + YES + 3 + YES + 2083 + + diff --git a/platform/ios/Classes/MuDialogCreator.h b/platform/ios/Classes/MuDialogCreator.h index 9417facf..cba863af 100644 --- a/platform/ios/Classes/MuDialogCreator.h +++ b/platform/ios/Classes/MuDialogCreator.h @@ -9,4 +9,5 @@ @protocol MuDialogCreator - (void) invokeTextDialog:(NSString *)aString okayAction:(void (^)(NSString *))block; +- (void) invokeChoiceDialog:(NSArray *)anArray okayAction:(void (^)(NSArray *))block; @end diff --git a/platform/ios/Classes/MuDocumentController.m b/platform/ios/Classes/MuDocumentController.m index 7b52f3e8..01583ac3 100644 --- a/platform/ios/Classes/MuDocumentController.m +++ b/platform/ios/Classes/MuDocumentController.m @@ -11,6 +11,7 @@ #import "MuPageViewReflow.h" #import "MuDocumentController.h" #import "MuTextFieldController.h" +#import "MuChoiceFieldController.h" #define GAP 20 #define INDICATOR_Y -44-24 @@ -629,6 +630,14 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [tf release]; } +- (void) invokeChoiceDialog:(NSArray *)anArray okayAction:(void (^)(NSArray *))block +{ + MuChoiceFieldController *cf = [[MuChoiceFieldController alloc] initWithChoices:anArray okayAction:block]; + cf.modalPresentationStyle = UIModalPresentationFormSheet; + [self presentViewController:cf animated:YES completion:nil]; + [cf release]; +} + - (void) onGotoPageFinished { scroll_animating = NO; diff --git a/platform/ios/Classes/MuPageViewNormal.m b/platform/ios/Classes/MuPageViewNormal.m index a342ae8e..8c247297 100644 --- a/platform/ios/Classes/MuPageViewNormal.m +++ b/platform/ios/Classes/MuPageViewNormal.m @@ -95,6 +95,31 @@ static int setFocussedWidgetText(fz_document *doc, fz_page *page, const char *te return accepted; } +static int setFocussedWidgetChoice(fz_document *doc, fz_page *page, const char *text) +{ + int accepted; + + fz_try(ctx) + { + pdf_document *idoc = pdf_specifics(doc); + if (idoc) + { + pdf_widget *focus = pdf_focused_widget(idoc); + if (focus) + { + pdf_choice_widget_set_value(idoc, focus, 1, (char **)&text); + accepted = 1; + } + } + } + fz_catch(ctx) + { + accepted = 0; + } + + return accepted; +} + static fz_display_list *create_page_list(fz_document *doc, fz_page *page) { fz_display_list *list; @@ -763,6 +788,32 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa }]; } +- (void) invokeChoiceDialog:(NSArray *)choices +{ + [dialogCreator invokeChoiceDialog:choices okayAction:^(NSArray *selection) { + CGRect tframe = tileFrame; + float tscale = tileScale; + CGRect vframe = tframe; + vframe.origin.x -= imageView.frame.origin.x; + vframe.origin.y -= imageView.frame.origin.y; + + dispatch_async(queue, ^{ + BOOL accepted = setFocussedWidgetChoice(doc, page, [[selection objectAtIndex:0] UTF8String]); + if (accepted) + { + [self updatePageAndTileWithTileFrame:tframe tileScale:tscale viewFrame:vframe]; + } + else + { + dispatch_async(dispatch_get_main_queue(), ^{ + [self invokeChoiceDialog:choices]; + }); + } + }); + + }]; +} + - (int) passTapToPage:(CGPoint)pt { pdf_document *idoc = pdf_specifics(doc); @@ -770,10 +821,14 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa pdf_ui_event event; int changed = 0; pdf_widget *focus; + char **opts = NULL; + char *text = NULL; if (!idoc) return; + fz_var(opts); + fz_var(text); fz_try(ctx) { event.etype = PDF_EVENT_TYPE_POINTER; @@ -791,18 +846,30 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa { case PDF_WIDGET_TYPE_TEXT: { - char *text = pdf_text_widget_text(idoc, focus); - NSString *stext = [NSString stringWithUTF8String:text?text:""]; - fz_free(ctx, text); + text = pdf_text_widget_text(idoc, focus); + NSString *stext = [[NSString stringWithUTF8String:text?text:""] retain]; dispatch_async(dispatch_get_main_queue(), ^{ [self invokeTextDialog:stext]; + [stext release]; }); break; } case PDF_WIDGET_TYPE_LISTBOX: case PDF_WIDGET_TYPE_COMBOBOX: + { + int nopts = pdf_choice_widget_options(idoc, focus, NULL); + opts = fz_malloc(ctx, nopts * sizeof(*opts)); + (void)pdf_choice_widget_options(idoc, focus, opts); + NSMutableArray *arr = [[NSMutableArray arrayWithCapacity:nopts] retain]; + for (int i = 0; i < nopts; i++) + [arr addObject:[NSString stringWithUTF8String:opts[i]]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self invokeChoiceDialog:arr]; + [arr release]; + }); break; + } case PDF_WIDGET_TYPE_SIGNATURE: break; @@ -812,6 +879,11 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa } } } + fz_always(ctx) + { + fz_free(ctx, text); + fz_free(ctx, opts); + } fz_catch(ctx) { } -- cgit v1.2.3