/* HBImageAndTextCell This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. It may be used under the terms of the GNU General Public License. */ #import "HBImageAndTextCell.h" static inline float xLeftInRect(NSSize innerSize, NSRect outerRect) { return NSMinX(outerRect); } static inline float xCenterInRect(NSSize innerSize, NSRect outerRect) { return MAX(NSMidX(outerRect) - (innerSize.width/2.0), 0.0); } static inline float xRightInRect(NSSize innerSize, NSRect outerRect) { return MAX(NSMaxX(outerRect) - innerSize.width, 0.0); } static inline float yTopInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) { if (flipped) return NSMinY(outerRect); else return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); } static inline float yCenterInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) { return MAX(NSMidY(outerRect) - innerSize.height/2.0, 0.0); } static inline float yBottomInRect(NSSize innerSize, NSRect outerRect, BOOL flipped) { if (flipped) return MAX(NSMaxY(outerRect) - innerSize.height, 0.0); else return NSMinY(outerRect); } static inline NSSize scaleProportionally(NSSize imageSize, NSRect canvasRect) { float ratio; // get the smaller ratio and scale the image size by it ratio = MIN(NSWidth(canvasRect) / imageSize.width, NSHeight(canvasRect) / imageSize.height); imageSize.width *= ratio; imageSize.height *= ratio; return imageSize; } @implementation HBImageAndTextCell -(id)initTextCell:(NSString *)aString { if (self = [super initTextCell:aString]) { imageAlignment = NSImageAlignTop; imageSpacing = NSMakeSize (3.0, 2.0); } return self; } -(id)initWithCoder:(NSCoder *)decoder { if (self = [super initWithCoder:decoder]) { imageAlignment = NSImageAlignTop; imageSpacing = NSMakeSize (3.0, 2.0); } return self; } - (void)dealloc { [image release]; image = nil; [super dealloc]; } - copyWithZone:(NSZone *)zone { HBImageAndTextCell *cell = (HBImageAndTextCell *)[super copyWithZone:zone]; cell->image = [image retain]; return cell; } - (void)setImage:(NSImage *)anImage { if (anImage != image) { [image release]; image = [anImage retain]; } } - (NSImage *)image { return image; } - (void) setImageAlignment:(NSImageAlignment)alignment; { imageAlignment = alignment; } - (NSImageAlignment) imageAlignment; { return imageAlignment; } - (void)setImageSpacing:(NSSize)aSize; { imageSpacing = aSize; } - (NSSize)imageSpacing { return imageSpacing; } - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent { NSRect textFrame, imageFrame; NSDivideRect (aRect, &imageFrame, &textFrame, (imageSpacing.width * 2) + [image size].width, NSMinXEdge); [super editWithFrame: textFrame inView: controlView editor:textObj delegate:anObject event: theEvent]; } - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength { NSRect textFrame, imageFrame; NSDivideRect (aRect, &imageFrame, &textFrame, (imageSpacing.width * 2) + [image size].width, NSMinXEdge); [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength]; } - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { #if 1 if (image != nil) { NSSize imageSize; NSRect imageFrame; imageSize = [image size]; NSDivideRect(cellFrame, &imageFrame, &cellFrame, (imageSpacing.width * 2) + imageSize.width, NSMinXEdge); if ([self drawsBackground]) { [[self backgroundColor] set]; NSRectFill(imageFrame); } imageFrame.origin.x += imageSpacing.width; imageFrame.size = imageSize; switch (imageAlignment) { default: case NSImageAlignTop: if ([controlView isFlipped]) imageFrame.origin.y += imageFrame.size.height; else imageFrame.origin.y += (cellFrame.size.height - imageFrame.size.height); break; case NSImageAlignCenter: if ([controlView isFlipped]) imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2); else imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); break; case NSImageAlignBottom: if ([controlView isFlipped]) imageFrame.origin.y += cellFrame.size.height; // for unflipped, imageFrame is already correct break; } [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver]; } [super drawWithFrame:cellFrame inView:controlView]; #endif #if 0 // this snippet supports all alignment values plus potentially scaling. if (image != nil) { NSSize imageSize; NSSize srcImageSize; NSRect imageFrame; NSPoint position; BOOL flipped = [controlView isFlipped]; imageSize = [image size]; srcImageSize = imageSize; // this will be more useful once/if we support scaling NSDivideRect(cellFrame, &imageFrame, &cellFrame, 12 + imageSize.width, NSMinXEdge); if ([self drawsBackground]) { [[self backgroundColor] set]; NSRectFill(imageFrame); } switch (imageAlignment) { default: case NSImageAlignLeft: position.x = xLeftInRect(imageSize, imageFrame); position.y = yCenterInRect(imageSize, imageFrame, flipped); break; case NSImageAlignRight: position.x = xRightInRect(imageSize, imageFrame); position.y = yCenterInRect(imageSize, imageFrame, flipped); break; case NSImageAlignCenter: position.x = xCenterInRect(imageSize, imageFrame); position.y = yCenterInRect(imageSize, imageFrame, flipped); break; case NSImageAlignTop: position.x = xCenterInRect(imageSize, imageFrame); position.y = yTopInRect(imageSize, imageFrame, flipped); break; case NSImageAlignBottom: position.x = xCenterInRect(imageSize, imageFrame); position.y = yBottomInRect(imageSize, imageFrame, flipped); break; case NSImageAlignTopLeft: position.x = xLeftInRect(imageSize, imageFrame); position.y = yTopInRect(imageSize, imageFrame, flipped); break; case NSImageAlignTopRight: position.x = xRightInRect(imageSize, imageFrame); position.y = yTopInRect(imageSize, imageFrame, flipped); break; case NSImageAlignBottomLeft: position.x = xLeftInRect(imageSize, imageFrame); position.y = yBottomInRect(imageSize, imageFrame, flipped); break; case NSImageAlignBottomRight: position.x = xRightInRect(imageSize, imageFrame); position.y = yBottomInRect(imageSize, imageFrame, flipped); break; } // account for flipped views if (flipped) { position.y += imageSize.height; imageSize.height = -imageSize.height; } // Set image flipping to match view. Don't know if this is really the best way // to deal with flipped views and images. if ([image isFlipped] != flipped) [image setFlipped: flipped]; // draw! [image drawInRect: NSMakeRect(position.x, position.y, imageSize.width, imageSize.height) fromRect: NSMakeRect(0, 0, srcImageSize.width, srcImageSize.height) operation: NSCompositeSourceOver fraction: 1.0]; } [super drawWithFrame:cellFrame inView:controlView]; #endif } - (NSSize)cellSize { NSSize cellSize = [super cellSize]; cellSize.width += (image ? [image size].width + (imageSpacing.width * 2) : 0); return cellSize; } @end