/**
NSImageCell
The image cell class
Copyright (C) 1999, 2005 Free Software Foundation, Inc.
Author: Jonathan Gapen
Date: 1999
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#import
#import "AppKit/NSAffineTransform.h"
#import "AppKit/NSCell.h"
#import "AppKit/NSGraphics.h"
#import "AppKit/NSImageCell.h"
#import "AppKit/NSImage.h"
#import "GNUstepGUI/GSTheme.h"
#import "GSGuiPrivate.h"
@interface NSCell (Private)
- (NSSize) _scaleImageWithSize: (NSSize)imageSize
toFitInSize: (NSSize)canvasSize
scalingType: (NSImageScaling)scalingType;
@end
@implementation NSImageCell
//
// Class methods
//
+ (void) initialize
{
if (self == [NSImageCell class])
{
[self setVersion: 1];
}
}
//
// Instance methods
//
- (id) init
{
return [self initImageCell: nil];
}
- (void) setImage:(NSImage *)anImage
{
[super setImage:anImage];
if (anImage)
_original_image_size = [anImage size];
else
_original_image_size = NSMakeSize(1,1);
}
- (void)setObjectValue:(id)object
{
if ((object == nil) || ([object isKindOfClass:[NSImage class]]))
{
[self setImage: object];
}
else
{
[super setObjectValue: object];
}
}
//
// Aligning and scaling the image
//
- (NSImageAlignment) imageAlignment
{
return _imageAlignment;
}
- (void) setImageAlignment: (NSImageAlignment)anAlignment
{
NSDebugLLog(@"NSImageCell", @"NSImageCell -setImageAlignment");
_imageAlignment = anAlignment;
}
- (NSImageScaling) imageScaling
{
return _imageScaling;
}
- (void) setImageScaling: (NSImageScaling)scaling
{
_imageScaling = scaling;
}
//
// Choosing the frame
//
- (NSImageFrameStyle) imageFrameStyle
{
return _frameStyle;
}
- (void) setImageFrameStyle: (NSImageFrameStyle)aFrameStyle
{
// We could set _cell.is_bordered and _cell.is_bezeled here to
// reflect the border type, but this wont be used.
_frameStyle = aFrameStyle;
}
//
// Displaying
//
- (void) _drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
inView: (NSView *)controlView
{
NSDebugLLog(@"NSImageCell", @"NSImageCell -_drawBorderAndBackgroundWithFrame");
[[GSTheme theme] drawBorderForImageFrameStyle: _frameStyle
frame: cellFrame
view: controlView];
}
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);
}
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView *)controlView
{
NSPoint position;
BOOL is_flipped = [controlView isFlipped];
NSSize imageSize, realImageSize;
NSRect rect;
NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called");
if (!_cell_image)
return;
// leave room for the frame
cellFrame = [self drawingRectForBounds: cellFrame];
realImageSize = [_cell_image size];
imageSize = [self _scaleImageWithSize: realImageSize
toFitInSize: cellFrame.size
scalingType: _imageScaling];
switch (_imageAlignment)
{
default:
case NSImageAlignLeft:
position.x = xLeftInRect(imageSize, cellFrame);
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignRight:
position.x = xRightInRect(imageSize, cellFrame);
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignCenter:
position.x = xCenterInRect(imageSize, cellFrame);
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignTop:
position.x = xCenterInRect(imageSize, cellFrame);
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignBottom:
position.x = xCenterInRect(imageSize, cellFrame);
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignTopLeft:
position.x = xLeftInRect(imageSize, cellFrame);
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignTopRight:
position.x = xRightInRect(imageSize, cellFrame);
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignBottomLeft:
position.x = xLeftInRect(imageSize, cellFrame);
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
break;
case NSImageAlignBottomRight:
position.x = xRightInRect(imageSize, cellFrame);
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
break;
}
rect = NSMakeRect(position.x, position.y,
imageSize.width, imageSize.height);
if (nil != controlView)
{
rect = [controlView centerScanRect: rect];
}
CGFloat fraction = 1.0;
if (_frameStyle == NSImageFrameNone
&& ![self isEnabled])
{
fraction = 0.5;
}
// draw!
[_cell_image drawInRect: rect
fromRect: NSMakeRect(0, 0, realImageSize.width,
realImageSize.height)
operation: NSCompositeSourceOver
fraction: fraction
respectFlipped: YES
hints: nil];
}
- (NSSize) cellSize
{
NSSize borderSize, s;
// Get border size
borderSize = [[GSTheme theme] sizeForImageFrameStyle: _frameStyle];
// Get Content Size
s = _original_image_size;
// Add in border size
s.width += 2 * borderSize.width;
s.height += 2 * borderSize.height;
return s;
}
- (NSRect) drawingRectForBounds: (NSRect)theRect
{
NSSize borderSize;
// Get border size
borderSize = [[GSTheme theme] sizeForImageFrameStyle: _frameStyle];
return NSInsetRect (theRect, borderSize.width, borderSize.height);
}
//
// NSCoding protocol
//
- (void) encodeWithCoder: (NSCoder *)aCoder
{
[super encodeWithCoder: aCoder];
if ([aCoder allowsKeyedCoding])
{
[aCoder encodeInt: _imageAlignment forKey: @"NSAlign"];
[aCoder encodeInt: _imageScaling forKey: @"NSScale"];
[aCoder encodeInt: _frameStyle forKey: @"NSStyle"];
[aCoder encodeBool: NO forKey: @"NSAnimates"];
}
else
{
[aCoder encodeValueOfObjCType: @encode(int) at: &_imageAlignment];
[aCoder encodeValueOfObjCType: @encode(int) at: &_frameStyle];
[aCoder encodeValueOfObjCType: @encode(int) at: &_imageScaling];
[aCoder encodeSize: _original_image_size];
}
}
- (id) initWithCoder: (NSCoder *)aDecoder
{
if ((self = [super initWithCoder: aDecoder]) != nil)
{
if ([aDecoder allowsKeyedCoding])
{
if ([aDecoder containsValueForKey: @"NSAlign"])
{
[self setImageAlignment: [aDecoder decodeIntForKey: @"NSAlign"]];
}
if ([aDecoder containsValueForKey: @"NSScale"])
{
[self setImageScaling: [aDecoder decodeIntForKey: @"NSScale"]];
}
if ([aDecoder containsValueForKey: @"NSStyle"])
{
[self setImageFrameStyle: [aDecoder decodeIntForKey: @"NSStyle"]];
}
if ([aDecoder containsValueForKey: @"NSAnimates"])
{
//BOOL animates = [aDecoder decodeBoolForKey: @"NSAnimates"];
}
}
else
{
[aDecoder decodeValueOfObjCType: @encode(int) at: &_imageAlignment];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_frameStyle];
[aDecoder decodeValueOfObjCType: @encode(int) at: &_imageScaling];
_original_image_size = [aDecoder decodeSize];
}
}
return self;
}
@end