diff options
Diffstat (limited to 'Classes/HJManagedImageV.m')
-rwxr-xr-x | Classes/HJManagedImageV.m | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/Classes/HJManagedImageV.m b/Classes/HJManagedImageV.m new file mode 100755 index 0000000..eb83f7d --- /dev/null +++ b/Classes/HJManagedImageV.m @@ -0,0 +1,254 @@ +// +// HJManagedImageV.m +// hjlib +// +// Copyright Hunter and Johnson 2009, 2010, 2011 +// HJCache may be used freely in any iOS or Mac application free or commercial. +// May be redistributed as source code only if all the original files are included. +// See http://www.markj.net/hjcache-iphone-image-cache/ + +#import "HJManagedImageV.h" + +@interface UIImage (Extras) + +- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize; + +@end + +@implementation UIImage (Extras) + +#pragma mark - +#pragma mark Scale and crop image + +- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize +{ + UIImage *sourceImage = self; + UIImage *newImage = nil; + CGSize imageSize = sourceImage.size; + CGFloat width = imageSize.width; + CGFloat height = imageSize.height; + CGFloat targetWidth = targetSize.width; + CGFloat targetHeight = targetSize.height; + CGFloat scaleFactor = 0.0; + CGFloat scaledWidth = targetWidth; + CGFloat scaledHeight = targetHeight; + CGPoint thumbnailPoint = CGPointMake(0.0,0.0); + + if (CGSizeEqualToSize(imageSize, targetSize) == NO) + { + CGFloat widthFactor = targetWidth / width; + CGFloat heightFactor = targetHeight / height; + + if (widthFactor > heightFactor) + scaleFactor = widthFactor; // scale to fit height + else + scaleFactor = heightFactor; // scale to fit width + scaledWidth = width * scaleFactor; + scaledHeight = height * scaleFactor; + + // center the image + if (widthFactor > heightFactor) + { + thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; + } + else + if (widthFactor < heightFactor) + { + thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; + } + } + + UIGraphicsBeginImageContext(targetSize); // this will crop + + CGRect thumbnailRect = CGRectZero; + thumbnailRect.origin = thumbnailPoint; + thumbnailRect.size.width = scaledWidth; + thumbnailRect.size.height = scaledHeight; + + [sourceImage drawInRect:thumbnailRect]; + + newImage = UIGraphicsGetImageFromCurrentImageContext(); + if(newImage == nil) + NSLog(@"could not scale image"); + + //pop the context to get back to the default + UIGraphicsEndImageContext(); + return newImage; +} + +@end + +@implementation HJManagedImageV + + +@synthesize oid; +@synthesize url; +@synthesize moHandler; +@synthesize squareCropped; +@synthesize callbackOnSetImage; +@synthesize callbackOnCancel; +@synthesize imageView; +@synthesize modification; +@synthesize loadingWheel; +@synthesize index; + + +- (id)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + isCancelled=NO; + modification=0; + url=nil; + onImageTap = nil; + squareCropped = false; + index = -1; + self.userInteractionEnabled = NO; //because want to treat it like a UIImageView. Just turn this back on if you want to catch taps. + } + return self; +} + +- (void)dealloc { + [self clear]; + self.callbackOnCancel=nil; + self.callbackOnSetImage=nil; + self.loadingWheel=nil; + [super dealloc]; + //NSLog(@"ManagedImage dealloc"); +} + + +-(void) clear { + [self.moHandler removeUser:self]; + self.moHandler=nil; + [imageView removeFromSuperview]; + self.image = nil; + self.imageView.image=nil; + self.imageView=nil; + self.oid=nil; + self.url=nil; +} + +/* +-(void) clear { + self.url = nil; + self.callbackOnSetImage = nil; + //int rc1 = [image retainCount]; + [self.imageView removeFromSuperview]; + self.imageView = nil; + //int rc2 = [image retainCount]; + [image release]; image=nil; //do this instead of self.image=nil because setImage has more code + self.loadingWheel = nil; +} +*/ + + +-(void) changeManagedObjStateFromLoadedToReady { + //NSLog(@"managedStateReady %@",managedState); + if (moHandler.moData) { + moHandler.managedObj=[UIImage imageWithData:moHandler.moData]; + } else if (moHandler.moReadyDataFilename) { + moHandler.managedObj=[UIImage imageWithContentsOfFile:moHandler.moReadyDataFilename]; + } else { + //error? + NSLog(@"HJManagedImageV error in changeManagedObjStateFromLoadedToReady ?"); + } +} + +-(void) managedObjFailed { + NSLog(@"moHandlerFailed %@",moHandler); + [image release]; + image = nil; +} + +-(void) managedObjReady { + //NSLog(@"moHandlerReady %@",moHandler); + [self setImage:moHandler.managedObj]; +} + + +-(UIImage*) image { + return image; +} + +-(void) markCancelled { + isCancelled = YES; + [callbackOnCancel managedImageCancelled:self]; +} + +-(UIImage*) modifyImage:(UIImage*)theImage modification:(int)mod { + return theImage; +} + + +-(void) setImage:(UIImage*)theImage modification:(int)mod { + if (mod==modification) { + [self setImage:theImage]; + } else { + UIImage* modified = [self modifyImage:theImage modification:(int)mod]; + [self setImage:modified]; + } +} + + +-(void) setImage:(UIImage*)theImage { + if (theImage==image) { + //when the same image is on the screen multiple times, an image that is alredy set might be set again with the same image. + return; + } + [theImage retain]; + [image release]; + image = theImage; + + [imageView removeFromSuperview]; + + if (squareCropped) + self.imageView = [[[UIImageView alloc] initWithImage:[theImage imageByScalingAndCroppingForSize:CGSizeMake(100,100)]] autorelease]; + else + self.imageView = [[[UIImageView alloc] initWithImage:theImage] autorelease]; + + imageView.contentMode = UIViewContentModeScaleAspectFit; + imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight ); + [self addSubview:imageView]; + imageView.frame = self.bounds; + [imageView setNeedsLayout]; + [self setNeedsLayout]; + //NSLog(@"setImageCallback from %@ to %@",self,callbackOnSetImage); + [loadingWheel stopAnimating]; + [loadingWheel removeFromSuperview]; + self.loadingWheel = nil; + self.hidden=NO; + if (image!=nil) { + [callbackOnSetImage managedImageSet:self]; + } +} + +-(void) showLoadingWheel { + [loadingWheel removeFromSuperview]; + self.loadingWheel = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease]; + loadingWheel.center = self.center; + loadingWheel.hidesWhenStopped=YES; + [self addSubview:loadingWheel]; + [loadingWheel startAnimating]; +} + +-(void) setCallbackOnImageTap:(id)obj method:(SEL)m { + NSInvocation* invo = [NSInvocation invocationWithMethodSignature:[obj methodSignatureForSelector:m]]; + [invo setTarget:obj]; + [invo setSelector:m]; + [invo setArgument:&self atIndex:2]; + [invo retain]; + [onImageTap release]; + onImageTap = invo; + self.userInteractionEnabled=YES; //because it's NO in the initializer, but if we want to get a callback on tap, + //then need to get touch events. +} + +-(void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { + if (onImageTap) { + [onImageTap invoke]; + } + else { + [super touchesEnded:touches withEvent:event]; + } +} + +@end |