[iphone] now decoders need to be injected into ZXingWidgetController to enhance perfo...
[zxing.git] / iphone / ZXingWidget / Classes / OverlayView.m
1 /**
2  * Copyright 2009 Jeff Verkoeyen
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #import "OverlayView.h"
18
19 static const CGFloat kPadding = 10;
20
21 @interface OverlayView()
22 @property (nonatomic,assign) UIButton *cancelButton;
23 @end
24
25
26 @implementation OverlayView
27
28 @synthesize delegate, oneDMode;
29 @synthesize points = _points;
30 @synthesize cancelButton;
31
32 ////////////////////////////////////////////////////////////////////////////////////////////////////
33 - (id) initWithFrame:(CGRect)theFrame cancelEnabled:(BOOL)isCancelEnabled oneDMode:(BOOL)isOneDModeEnabled {
34         if( self = [super initWithFrame:theFrame] ) {
35                 self.backgroundColor = [UIColor clearColor];
36     self.oneDMode = isOneDModeEnabled;
37     if (isCancelEnabled) {
38       UIButton *butt = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
39       self.cancelButton = butt;
40       [cancelButton setTitle:@"Cancel" forState:UIControlStateNormal];
41       if (oneDMode) {
42         [cancelButton setTransform:CGAffineTransformMakeRotation(M_PI/2)];
43         [cancelButton setFrame:CGRectMake(20, 175, 45, 130)];
44       }
45       else {
46         [cancelButton setFrame:CGRectMake(95, 420, 130, 45)];                   
47       }
48       
49       [cancelButton addTarget:self action:@selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
50       [self addSubview:cancelButton];
51     }
52   }
53         return self;
54 }
55
56 - (void)cancel:(id)sender {
57         // call delegate to cancel this scanner
58         if (delegate != nil) {
59                 [delegate cancelled];
60         }
61 }
62
63 ////////////////////////////////////////////////////////////////////////////////////////////////////
64 - (void) dealloc {
65         [imageView release];
66         imageView = nil;
67         [_points release];
68         _points = nil;
69         [super dealloc];
70 }
71
72
73 - (void)drawRect:(CGRect)rect inContext:(CGContextRef)context {
74         CGContextBeginPath(context);
75         CGContextMoveToPoint(context, rect.origin.x, rect.origin.y);
76         CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y);
77         CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
78         CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height);
79         CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
80         CGContextStrokePath(context);
81 }
82
83
84 ////////////////////////////////////////////////////////////////////////////////////////////////////
85 - (void)drawRect:(CGRect)rect {
86         [super drawRect:rect];
87         CGContextRef c = UIGraphicsGetCurrentContext();
88   
89         CGRect cropRect = [self cropRect];
90         
91         if (nil != _points) {
92     //          [imageView.image drawAtPoint:cropRect.origin];
93         }
94         
95         CGFloat white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
96         CGContextSetStrokeColor(c, white);
97         CGContextSetFillColor(c, white);
98         [self drawRect:cropRect inContext:c];
99         
100   //    CGContextSetStrokeColor(c, white);
101         //      CGContextSetStrokeColor(c, white);
102         CGContextSaveGState(c);
103         if (oneDMode) {
104                 char *text = "Place a red line over the bar code to be scanned.";
105                 CGContextSelectFont(c, "Helvetica", 15, kCGEncodingMacRoman);
106                 CGContextScaleCTM(c, -1.0, 1.0);
107                 CGContextRotateCTM(c, M_PI/2);
108                 CGContextShowTextAtPoint(c, 74.0, 285.0, text, 49);
109         }
110         else {
111                 char *text = "Place a barcode inside the";
112                 char *text2 = "viewfinder rectangle to scan it.";
113                 CGContextSelectFont(c, "Helvetica", 18, kCGEncodingMacRoman);
114                 CGContextScaleCTM(c, -1.0, 1.0);
115                 CGContextRotateCTM(c, M_PI);
116                 CGContextShowTextAtPoint(c, 48.0, -45.0, text, 26);
117                 CGContextShowTextAtPoint(c, 33.0, -70.0, text2, 32);
118         }
119         CGContextRestoreGState(c);
120         int offset = rect.size.width / 2;
121         if (oneDMode) {
122                 CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
123                 CGContextSetStrokeColor(c, red);
124                 CGContextSetFillColor(c, red);
125                 CGContextBeginPath(c);
126                 //              CGContextMoveToPoint(c, rect.origin.x + kPadding, rect.origin.y + offset);
127                 //              CGContextAddLineToPoint(c, rect.origin.x + rect.size.width - kPadding, rect.origin.y + offset);
128                 CGContextMoveToPoint(c, rect.origin.x + offset, rect.origin.y + kPadding);
129                 CGContextAddLineToPoint(c, rect.origin.x + offset, rect.origin.y + rect.size.height - kPadding);
130                 CGContextStrokePath(c);
131         }
132         if( nil != _points ) {
133                 CGFloat blue[4] = {0.0f, 1.0f, 0.0f, 1.0f};
134                 CGContextSetStrokeColor(c, blue);
135                 CGContextSetFillColor(c, blue);
136                 if (oneDMode) {
137                         CGPoint val1 = [[_points objectAtIndex:0] CGPointValue];
138                         CGPoint val2 = [[_points objectAtIndex:1] CGPointValue];
139                         CGContextMoveToPoint(c, offset, val1.x);
140                         CGContextAddLineToPoint(c, offset, val2.x);
141                         CGContextStrokePath(c);
142                 }
143                 else {
144                         CGRect smallSquare = CGRectMake(0, 0, 10, 10);
145                         for( NSValue* value in _points ) {
146                                 CGPoint point = [value CGPointValue];
147                                 smallSquare.origin = CGPointMake(
148                                          cropRect.origin.x + point.x - smallSquare.size.width / 2,
149                                          cropRect.origin.y + point.y - smallSquare.size.height / 2);
150                                 [self drawRect:smallSquare inContext:c];
151                         }
152                 }
153         }
154 }
155
156
157 ////////////////////////////////////////////////////////////////////////////////////////////////////
158 /*
159  - (void) setImage:(UIImage*)image {
160  if( nil == _imageView ) {
161  _imageView = [[UIImageView alloc] initWithImage:image];
162  _imageView.alpha = 0.5;
163  } else {
164  _imageView.image = image;
165  }
166  
167  CGRect frame = _imageView.frame;
168  frame.origin.x = self.cropRect.origin.x;
169  frame.origin.y = self.cropRect.origin.y;
170  _imageView.frame = frame;
171  
172  [_points release];
173  _points = nil;
174  self.backgroundColor = [UIColor clearColor];
175  
176  [self setNeedsDisplay];
177  }
178  */
179
180 ////////////////////////////////////////////////////////////////////////////////////////////////////
181 - (UIImage*) image {
182         return imageView.image;
183 }
184
185
186 ////////////////////////////////////////////////////////////////////////////////////////////////////
187 - (CGRect) cropRect {
188         CGFloat rectSize = self.frame.size.width - kPadding * 2;
189         if (!oneDMode) {
190                 return CGRectMake(kPadding, (self.frame.size.height - rectSize) / 2, rectSize, rectSize);
191         }
192         else {
193                 CGFloat rectSize2 = self.frame.size.height - kPadding * 2;
194                 return CGRectMake(kPadding, kPadding, rectSize, rectSize2);             
195         }
196 }
197
198
199 ////////////////////////////////////////////////////////////////////////////////////////////////////
200 - (void) setPoints:(NSArray*)pnts {
201         [pnts retain];
202         [_points release];
203         _points = pnts;
204         
205         if (pnts != nil) {
206                 self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.25];
207         }
208         [self setNeedsDisplay];
209 }
210
211
212 @end