summaryrefslogtreecommitdiffstats
path: root/Classes/HJManagedImageV.m
diff options
context:
space:
mode:
Diffstat (limited to 'Classes/HJManagedImageV.m')
-rwxr-xr-xClasses/HJManagedImageV.m254
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