5
// Created by döme on 11.08.2009.
6
// Copyright 2009 __MyCompanyName__. All rights reserved.
10
#import "ElAnimation.h"
12
#import <QuartzCore/QuartzCore.h>
14
@class UIPopoverController;
16
void createPathInRoundedRect(CGContextRef c, CGRect rect, float radius)
18
CGContextBeginPath(c);
19
CGContextMoveToPoint(c, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) );
20
CGContextAddLineToPoint(c, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect));
21
CGContextAddArcToPoint(c, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMinY(rect) + radius, radius);
22
CGContextAddLineToPoint(c, CGRectGetMaxX(rect), CGRectGetMaxY(rect) - radius);
23
CGContextAddArcToPoint(c, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect), radius);
24
CGContextAddLineToPoint(c, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect));
25
CGContextAddArcToPoint(c, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMaxY(rect) - radius, radius);
26
CGContextAddLineToPoint(c, CGRectGetMinX(rect), CGRectGetMinY(rect) + radius );
27
CGContextAddArcToPoint(c, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMinX(rect) + radius, CGRectGetMinY(rect), radius);
28
CGContextClosePath(c);
33
@implementation UIImage (ElImageView)
35
CGImageRef CreateScaledCGImageFromCGImage(CGImageRef image, CGSize size, UIImageOrientation orientation)
37
int srcWidth = size.width;
38
int srcHeight = size.height;
39
int dstWidth = size.width;
40
int dstHeight = size.height;
44
case UIImageOrientationLeft:
45
case UIImageOrientationLeftMirrored:
46
case UIImageOrientationRight:
47
case UIImageOrientationRightMirrored:
56
//UIGraphicsPushContext(UIGraphicsGetCurrentContext());
58
// Declare the number of bytes per row. Each pixel in the bitmap in this
59
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
61
size_t bitmapBytesPerRow = (dstWidth * 4);
62
size_t bitmapByteCount = (bitmapBytesPerRow * dstHeight);
64
// Allocate memory for image data. This is the destination in memory
65
// where any drawing to the bitmap context will be rendered.
66
void* bitmapData = malloc( bitmapByteCount );
67
if (bitmapData == NULL)
72
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
73
// per component. Regardless of what the source image format is
74
// (CMYK, Grayscale, and so on) it will be converted over to the format
75
// specified here by CGBitmapContextCreate.
76
CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
77
CGContextRef context = CGBitmapContextCreate(bitmapData,dstWidth,dstHeight,8,bitmapBytesPerRow,
78
colorspace,kCGImageAlphaPremultipliedFirst);
79
CGColorSpaceRelease(colorspace);
82
// error creating context
91
case UIImageOrientationLeft:
92
case UIImageOrientationLeftMirrored:
95
case UIImageOrientationRight:
96
case UIImageOrientationRightMirrored:
99
case UIImageOrientationDown:
100
case UIImageOrientationDownMirrored:
105
CGContextTranslateCTM(context, 0.5f*(float)dstWidth, 0.5*(float)dstHeight);
106
CGContextRotateCTM(context, angle);
107
CGContextTranslateCTM(context, -0.5f*(float)srcWidth, -0.5*(float)srcHeight);
108
// Draw the image to the bitmap context. Once we draw, the memory
109
// allocated for the context for rendering will then contain the
110
// raw image data in the specified color space.
114
CGContextDrawImage(context, CGRectMake(0,0,srcWidth, srcHeight), image);
116
CGImageRef imgRef = CGBitmapContextCreateImage(context);
117
CGContextRelease(context);
120
//UIGraphicsPopContext();
126
- (UIImage*) scaledToSize: (CGSize) size
128
CGImageRef imgref = CreateScaledCGImageFromCGImage([self CGImage], size, [self imageOrientation]);
132
UIImage* img = [UIImage imageWithCGImage: imgref];
134
CGImageRelease(imgref);
141
@implementation ElImageView
143
- (id) initWithFrame: (CGRect) frame
145
if (!(self = [super initWithFrame: frame]))
148
borderColor = [[UIColor grayColor] retain];
153
[self setBackgroundColor: [UIColor redColor]];
159
- (id) initWithCoder: (NSCoder*) coder
161
if (!(self = [super initWithCoder: coder]))
164
borderColor = [[UIColor grayColor] retain];
171
[self setBackgroundColor: [UIColor clearColor]];
179
// [_cachedImageForDrawing release];
180
[borderColor release];
185
- (void) setFrame: (CGRect) frame
187
[super setFrame: frame];
188
if (!CGRectEqualToRect(frame, [self frame]))
190
[_cachedImageForDrawing release];
191
_cachedImageForDrawing = nil;
195
- (void) drawRect: (CGRect) rect
197
CGContextRef c = UIGraphicsGetCurrentContext();
198
//[[UIColor blueColor] set];
199
//CGContextFillRect(c, rect);
201
CGContextSaveGState(c);
210
img = [UIImage imageNamed: @"image-not-found-icon.png"];
212
CGRect bounds = CGRectInset([self bounds], 0.5*borderWidth,0.5*borderWidth);
213
CGSize imgSize = [img size];
217
float drawHeight = imgSize.height;
218
float drawWidth = imgSize.width;
220
float heightR = imgSize.height/bounds.size.height;
221
float widthR = imgSize.width/bounds.size.width;
225
drawHeight = bounds.size.height;
226
drawWidth *= 1.0f/heightR;
227
widthR = drawWidth/bounds.size.width;
232
drawWidth = bounds.size.width;
233
drawHeight *= 1.0f/widthR;
236
CGRect drawRect = CGRectMake(bounds.origin.x + 0.5f*(bounds.size.width - drawWidth), bounds.origin.y + 0.5f*(bounds.size.height - drawHeight), drawWidth, drawHeight);
242
if (!_cachedImageForDrawing)
244
//bounds.size.width = ceilf(bounds.origin.x + bounds.size.width) - bounds.origin.x;
245
//bounds.origin.x = ceilf(bounds.origin.x);
246
//bounds.origin.y = ceilf(bounds.origin.y);
248
_cachedImageForDrawing = [img scaledToSize: drawRect.size];
251
createPathInRoundedRect(c, drawRect, cornerRadius);
255
[img drawInRect: drawRect blendMode: kCGBlendModeNormal alpha: imageAlpha];
257
CGContextRestoreGState(c);
260
[[borderColor colorWithAlphaComponent: imageAlpha] set];
261
createPathInRoundedRect(c, drawRect, cornerRadius);
262
CGContextSetLineWidth(c, borderWidth);
263
CGContextStrokePath(c);
267
- (void) setImageAlpha: (float) a
270
[self setNeedsDisplay];
273
- (void) setImage: (UIImage*) img
280
//[_cachedImageForDrawing release];
281
//_cachedImageForDrawing = nil;
283
[self performSelectorOnMainThread: @selector(setNeedsDisplay) withObject: nil waitUntilDone: NO];
284
//[self setNeedsDisplay];
287
@synthesize image, cornerRadius, borderColor, borderWidth, fillView, imageAlpha;
293
@implementation ImageWell
296
- (id) initWithFrame: (CGRect) frame
298
if (!(self = [super initWithFrame: frame]))
304
- (id) initWithCoder: (NSCoder*) coder
306
if (!(self = [super initWithCoder: coder]))
309
instructionsView = [[UITextView alloc] initWithFrame: CGRectInset([self bounds], 0.0f, 0.0f)];
310
[instructionsView setText: NSLocalizedString(@"ImageWell instruction text", @"\n\n\nTap and hold to paste image,\n\nor\n\nDouble-tap to select image from gallery.")];
311
//[instructionsView setBackgroundColor: [UIColor yellowColor]];
312
[instructionsView setTextColor: [UIColor whiteColor]];
313
[instructionsView setBackgroundColor: [UIColor clearColor]];
314
[instructionsView setFont: [UIFont systemFontOfSize: [UIFont labelFontSize]]];
315
[instructionsView setEditable: NO];
316
[instructionsView setUserInteractionEnabled: NO];
317
[instructionsView setTextAlignment: UITextAlignmentCenter];
318
[self addSubview: instructionsView];
320
[instructionsView layer].opacity = 0.0f;
326
- (void) setFrame: (CGRect) frame
328
[super setFrame: frame];
329
[instructionsView setFrame: CGRectInset([self bounds], 0.0f, 0.0f)];
336
[imagePicker release];
337
[popoverController release];
341
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
343
[alertView dismissWithClickedButtonIndex: buttonIndex animated: YES];
349
id alert = [[UIAlertView alloc] initWithTitle: @"No Image to Paste!" message: @"Sorry, there is no usable image or image URL on the pasteboard" delegate: self cancelButtonTitle: nil otherButtonTitles: @"OK", nil];
354
- (void) pasteAction: (id) info
356
NSArray* images = [[UIPasteboard generalPasteboard] images];
359
UIImage* img = [images objectAtIndex: 0];
361
[self setImage: img];
362
[delegate imageWasSelectedInWell: self];
366
id url = [[UIPasteboard generalPasteboard] URL];
369
NSData *data = [NSData dataWithContentsOfURL:url];
370
UIImage *img = [UIImage imageWithData:data];
373
[self setImage: img];
374
[delegate imageWasSelectedInWell: self];
385
- (void) showInstructions: (float) time
387
time = MAX(1.0f, time);
389
ElFloatAnimation* anim = nil;
391
anim = [[[ElFloatAnimation alloc] init] autorelease];
393
[anim setStartValue: [[instructionsView layer] opacity]];
394
[anim setEndValue: 0.667f];
395
[anim setDuration: 0.5f];
396
[anim setTarget: [instructionsView layer]];
397
[anim setProperty: @"opacity"];
398
[anim queueForKey: @"text-opacity" atBeginning: YES cancelPending: YES];
401
anim = [[[ElFloatAnimation alloc] init] autorelease];
403
[anim setStartValue: imageAlpha];
404
[anim setEndValue: 0.333f];
405
[anim setDuration: 0.5f];
406
[anim setTarget: self];
407
[anim setProperty: @"imageAlpha"];
408
[anim queueForKey: @"image-opacity" atBeginning: YES cancelPending: YES];
410
[[ElAnimation delayedAnimationWithDelay: time - 0.5f] queueForKey: @"text-opacity" atBeginning: NO cancelPending: NO];
411
[[ElAnimation delayedAnimationWithDelay: time - 0.5f] queueForKey: @"image-opacity" atBeginning: NO cancelPending: NO];
413
anim = [[[ElFloatAnimation alloc] init] autorelease];
415
[anim setStartValue: 0.667f];
416
[anim setEndValue: 0.0f];
417
[anim setDuration: 0.5f];
418
[anim setTarget: [instructionsView layer]];
419
[anim setProperty: @"opacity"];
420
[anim queueForKey: @"text-opacity" atBeginning: NO cancelPending: NO];
423
anim = [[[ElFloatAnimation alloc] init] autorelease];
425
[anim setStartValue: 0.333f];
426
[anim setEndValue: 1.0f];
427
[anim setDuration: 0.5f];
428
[anim setTarget: self];
429
[anim setProperty: @"imageAlpha"];
430
[anim queueForKey: @"image-opacity" atBeginning: NO cancelPending: NO];
433
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
435
UITouch* touch = [touches anyObject];
437
if (([touch tapCount] == 1) && [self isItAPhone])
439
[self showInstructions: 3.0f];
443
touchBeganTime = [event timestamp];
445
pasteTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector:@selector(pasteAction:) userInfo: nil repeats: NO];
447
if ([touch tapCount] == 2)
449
[pasteTimer invalidate];
454
imagePicker = [[UIImagePickerController alloc] init];
456
//[imagePicker setSourceType: UIImagePickerControllerSourceTypeCamera];
457
[imagePicker setDelegate: self];
458
//[imagePicker setAllowsImageEditing: YES];
459
//[imagePicker setShowsCameraControls: NO];
463
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
466
if (!popoverController)
468
Class popoverClass = NSClassFromString(@"UIPopoverController");
469
popoverController = [[popoverClass alloc] initWithContentViewController: imagePicker];
471
[popoverController presentPopoverFromRect: [self bounds] inView: self permittedArrowDirections: UIPopoverArrowDirectionAny animated: YES];
475
[delegate presentModalViewController: imagePicker animated: YES];
479
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
481
// UITouch* touch = [touches anyObject];
483
[pasteTimer invalidate];
488
- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event
490
// UITouch* touch = [touches anyObject];
492
[pasteTimer invalidate];
497
- (void)imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
500
UIImage* img = [info objectForKey: UIImagePickerControllerEditedImage];
503
img = [info objectForKey: UIImagePickerControllerOriginalImage];
507
[self setImage: img];
508
[delegate imageWasSelectedInWell: self];
511
[delegate dismissModalViewControllerAnimated: YES];
514
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
516
[delegate dismissModalViewControllerAnimated: YES];
520
@synthesize delegate;