mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 06:51:44 +00:00
* Headers/AppKit/NSImageCell.h:
* Headers/AppKit/NSCell.h: Move NSImageScaling constants to NSCell * Source/NSImageCell.m: * Source/NSCell.m: Refactor the image scaling logic to a private method in NSCell, -_scaleImageWithSize:toFitInSize:scalingType: which can be share by NSImageCell, NSButtonCell, and any other cell classes that need it. * Source/NSButtonCell.m: * Headers/AppKit/NSButtonCell.h: Implement -imageScaling and -setImageScaling methods. * Source/GSThemeDrawing.m: * Headers/Additions/GNUstepGUI/GSTheme.h: Remove the -drawImage:inButtonCell:withFrame:position: API intended to let themes substitute images right before drawing, as IMHO it's the wrong place to hook in new images (by the time this method was caleld, sizing/positionging was already done). git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@34160 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
45d5c38825
commit
60674d5076
9 changed files with 202 additions and 119 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
2011-11-11 Eric Wasylishen <ewasylishen@gmail.com>
|
||||
|
||||
* Headers/AppKit/NSImageCell.h:
|
||||
* Headers/AppKit/NSCell.h: Move NSImageScaling constants to NSCell
|
||||
* Source/NSImageCell.m:
|
||||
* Source/NSCell.m: Refactor the image scaling logic to a private
|
||||
method in NSCell, -_scaleImageWithSize:toFitInSize:scalingType:
|
||||
which can be share by NSImageCell, NSButtonCell, and any other
|
||||
cell classes that need it.
|
||||
* Source/NSButtonCell.m:
|
||||
* Headers/AppKit/NSButtonCell.h: Implement -imageScaling and
|
||||
-setImageScaling methods.
|
||||
* Source/GSThemeDrawing.m:
|
||||
* Headers/Additions/GNUstepGUI/GSTheme.h: Remove the
|
||||
-drawImage:inButtonCell:withFrame:position: API intended
|
||||
to let themes substitute images right before drawing,
|
||||
as IMHO it's the wrong place to hook in new images (by
|
||||
the time this method was caleld, sizing/positionging
|
||||
was already done).
|
||||
|
||||
2011-11-11 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/GSXibLoader.m: Better handling for flattened properties
|
||||
|
|
|
@ -877,16 +877,6 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
|
|||
roundedLeft: (BOOL)roundedLeft
|
||||
roundedRight: (BOOL)roundedRight;
|
||||
|
||||
/**
|
||||
* In some themes it may be necessary to override the drawing
|
||||
* of an image a button cell and replace it with a rendered
|
||||
* version (from the native theme).
|
||||
*/
|
||||
- (void) drawImage: (NSImage *)image
|
||||
inButtonCell: (NSButtonCell *) cell
|
||||
withFrame: (NSRect) aRect
|
||||
position: (NSPoint) position;
|
||||
|
||||
- (void) drawBackgroundForMenuView: (NSMenuView*)menuView
|
||||
withFrame: (NSRect)bounds
|
||||
dirtyRect: (NSRect)dirtyRect
|
||||
|
|
|
@ -136,6 +136,7 @@ typedef enum _NSGradientType {
|
|||
#define _image_dims_when_disabled _cell.subclass_bool_two
|
||||
#define _shows_border_only_while_mouse_inside _cell.subclass_bool_three
|
||||
#define _mouse_inside _cell.subclass_bool_four
|
||||
NSImageScaling _imageScaling;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -165,6 +166,10 @@ typedef enum _NSGradientType {
|
|||
- (NSCellImagePosition)imagePosition;
|
||||
- (void)setAlternateImage: (NSImage *)anImage;
|
||||
- (void)setImagePosition: (NSCellImagePosition)aPosition;
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
|
||||
- (NSImageScaling)imageScaling;
|
||||
- (void)setImageScaling:(NSImageScaling)scaling;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Setting the Repeat Interval
|
||||
|
|
|
@ -118,6 +118,29 @@ enum {
|
|||
NSMixedState = -1
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>Enumeration of the ways that you can display an image in an
|
||||
* NSImageCell. The available ones are:</p>
|
||||
* <p><code>NSScaleNone</code>: The image is always displayed with
|
||||
* its natural size. If it's bigger than the cell size, it is
|
||||
* cropped.</p>
|
||||
* <p><code>NSScaleProportionally</code>: If the image is bigger
|
||||
* than the cell size, it is displayed in its natural size. If it
|
||||
* is smaller than the cell size, it is resized down proportionally
|
||||
* to fit the cell size.</p>
|
||||
* <p><code>NSScaleToFit</code>: The image is always resized (up
|
||||
* or down) to fit exactly in the cell size.</p>
|
||||
*/
|
||||
typedef enum {
|
||||
NSScaleProportionally = 0,
|
||||
NSScaleToFit = 1,
|
||||
NSScaleNone = 2,
|
||||
NSImageScaleProportionallyDown = 0,
|
||||
NSImageScaleAxesIndependently = 1,
|
||||
NSImageScaleNone = 2,
|
||||
NSImageScaleProportionallyUpOrDown = 3
|
||||
} NSImageScaling;
|
||||
|
||||
@interface NSCell : NSObject <NSCopying, NSCoding>
|
||||
{
|
||||
// Attributes
|
||||
|
|
|
@ -33,29 +33,6 @@
|
|||
|
||||
#import <AppKit/NSCell.h>
|
||||
|
||||
/**
|
||||
* <p>Enumeration of the ways that you can display an image in an
|
||||
* NSImageCell. The available ones are:</p>
|
||||
* <p><code>NSScaleNone</code>: The image is always displayed with
|
||||
* its natural size. If it's bigger than the cell size, it is
|
||||
* cropped.</p>
|
||||
* <p><code>NSScaleProportionally</code>: If the image is bigger
|
||||
* than the cell size, it is displayed in its natural size. If it
|
||||
* is smaller than the cell size, it is resized down proportionally
|
||||
* to fit the cell size.</p>
|
||||
* <p><code>NSScaleToFit</code>: The image is always resized (up
|
||||
* or down) to fit exactly in the cell size.</p>
|
||||
*/
|
||||
typedef enum {
|
||||
NSScaleProportionally = 0,
|
||||
NSScaleToFit = 1,
|
||||
NSScaleNone = 2,
|
||||
NSImageScaleProportionallyDown = 0,
|
||||
NSImageScaleAxesIndependently = 1,
|
||||
NSImageScaleNone = 2,
|
||||
NSImageScaleProportionallyUpOrDown = 3
|
||||
} NSImageScaling;
|
||||
|
||||
/**
|
||||
* <p>Enumeration of the ways that you can align an image inside an
|
||||
* NSImageCell when the image is not taking up all the space inside
|
||||
|
|
|
@ -803,25 +803,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void) drawImage: (NSImage *)image
|
||||
inButtonCell: (NSButtonCell *) cell
|
||||
withFrame: (NSRect) aRect
|
||||
position: (NSPoint) position
|
||||
{
|
||||
BOOL enabled = [cell isEnabled];
|
||||
BOOL dims = [cell imageDimsWhenDisabled];
|
||||
|
||||
if (!enabled && dims)
|
||||
{
|
||||
[image dissolveToPoint: position fraction: 0.5];
|
||||
}
|
||||
else
|
||||
{
|
||||
[image compositeToPoint: position
|
||||
operation: NSCompositeSourceOver];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) drawBackgroundForMenuView: (NSMenuView*)menuView
|
||||
withFrame: (NSRect)bounds
|
||||
dirtyRect: (NSRect)dirtyRect
|
||||
|
|
|
@ -106,6 +106,12 @@ typedef struct _GSButtonCellFlags
|
|||
#endif
|
||||
} GSButtonCellFlags;
|
||||
|
||||
@interface NSCell (Private)
|
||||
- (NSSize) _scaleImageWithSize: (NSSize)imageSize
|
||||
toFitInSize: (NSSize)canvasSize
|
||||
scalingType: (NSImageScaling)scalingType;
|
||||
@end
|
||||
|
||||
/**<p> TODO Description</p>
|
||||
*/
|
||||
@implementation NSButtonCell
|
||||
|
@ -137,6 +143,7 @@ typedef struct _GSButtonCellFlags
|
|||
_keyEquivalent = @"";
|
||||
_altContents = @"";
|
||||
_gradient_type = NSGradientNone;
|
||||
[self setImageScaling: NSImageScaleNone];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -480,6 +487,16 @@ typedef struct _GSButtonCellFlags
|
|||
return _cell.image_position;
|
||||
}
|
||||
|
||||
- (NSImageScaling) imageScaling
|
||||
{
|
||||
return _imageScaling;
|
||||
}
|
||||
|
||||
- (void) setImageScaling: (NSImageScaling)scaling
|
||||
{
|
||||
_imageScaling = scaling;
|
||||
}
|
||||
|
||||
- (void) setImage: (NSImage *)anImage
|
||||
{
|
||||
if (_cell.image_position == NSNoImage)
|
||||
|
@ -966,14 +983,26 @@ typedef struct _GSButtonCellFlags
|
|||
// Draw image
|
||||
if (imageToDisplay != nil)
|
||||
{
|
||||
const NSSize size = [imageToDisplay size];
|
||||
NSSize size = [self _scaleImageWithSize: [imageToDisplay size]
|
||||
toFitInSize: cellFrame.size
|
||||
scalingType: _imageScaling];
|
||||
|
||||
/* Pixel-align size */
|
||||
|
||||
if (controlView)
|
||||
{
|
||||
NSSize sizeInBase = [controlView convertSizeToBase: size];
|
||||
sizeInBase.width = GSRoundTowardsInfinity(sizeInBase.width);
|
||||
sizeInBase.height = GSRoundTowardsInfinity(sizeInBase.height);
|
||||
size = [controlView convertSizeFromBase: sizeInBase];
|
||||
}
|
||||
|
||||
/* Calculate an offset from the cellFrame origin */
|
||||
|
||||
NSPoint offset = NSMakePoint((NSWidth(cellFrame) - size.width) / 2.0,
|
||||
(NSHeight(cellFrame) - size.height) / 2.0);
|
||||
|
||||
/* Pixel-align the offset */
|
||||
/* Pixel-align the offset */
|
||||
|
||||
if (controlView)
|
||||
{
|
||||
|
@ -993,24 +1022,21 @@ typedef struct _GSButtonCellFlags
|
|||
offset = [controlView convertPointFromBase: inBase];
|
||||
}
|
||||
|
||||
/*
|
||||
* Images are always drawn with their bottom-left corner at the origin
|
||||
* so we must adjust the position to take account of a flipped view.
|
||||
*/
|
||||
if ([controlView isFlipped])
|
||||
{
|
||||
offset.y += size.height;
|
||||
}
|
||||
/* Draw the image */
|
||||
|
||||
{
|
||||
const NSPoint position = NSMakePoint(cellFrame.origin.x + offset.x,
|
||||
cellFrame.origin.y + offset.y);
|
||||
|
||||
[[GSTheme theme] drawImage: imageToDisplay
|
||||
inButtonCell: self
|
||||
withFrame: cellFrame
|
||||
position: position];
|
||||
}
|
||||
const NSRect rect = NSMakeRect(cellFrame.origin.x + offset.x,
|
||||
cellFrame.origin.y + offset.y,
|
||||
size.width,
|
||||
size.height);
|
||||
const CGFloat fraction = (![self isEnabled] &&
|
||||
[self imageDimsWhenDisabled]) ? 0.5 : 1.0;
|
||||
|
||||
[imageToDisplay drawInRect: rect
|
||||
fromRect: NSZeroRect
|
||||
operation: NSCompositeSourceOver
|
||||
fraction: fraction
|
||||
respectFlipped: YES
|
||||
hints: nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1642,6 +1668,23 @@ typedef struct _GSButtonCellFlags
|
|||
bFlags2 |= [self showsBorderOnlyWhileMouseInside] ? 0x8 : 0;
|
||||
bFlags2 |= (([self bezelStyle] & 0x7) | (([self bezelStyle] & 0x18) << 2));
|
||||
bFlags2 |= [self keyEquivalentModifierMask] << 8;
|
||||
|
||||
switch ([self imageScaling])
|
||||
{
|
||||
case NSImageScaleProportionallyDown:
|
||||
bFlags2 |= (2 << 6);
|
||||
break;
|
||||
case NSImageScaleAxesIndependently:
|
||||
bFlags2 |= (3 << 6);
|
||||
break;
|
||||
case NSImageScaleNone:
|
||||
default:
|
||||
break;
|
||||
case NSImageScaleProportionallyUpOrDown:
|
||||
bFlags2 |= (1 << 6);
|
||||
break;
|
||||
}
|
||||
|
||||
[aCoder encodeInt: bFlags2 forKey: @"NSButtonFlags2"];
|
||||
|
||||
// alternate image encoding...
|
||||
|
@ -1793,6 +1836,7 @@ typedef struct _GSButtonCellFlags
|
|||
}
|
||||
if ([aDecoder containsValueForKey: @"NSButtonFlags2"])
|
||||
{
|
||||
NSUInteger imageScale;
|
||||
int bFlags2;
|
||||
|
||||
bFlags2 = [aDecoder decodeIntForKey: @"NSButtonFlags2"];
|
||||
|
@ -1800,6 +1844,24 @@ typedef struct _GSButtonCellFlags
|
|||
[self setBezelStyle: (bFlags2 & 0x7) | ((bFlags2 & 0x20) >> 2)];
|
||||
[self setKeyEquivalentModifierMask: ((bFlags2 >> 8) &
|
||||
NSDeviceIndependentModifierFlagsMask)];
|
||||
|
||||
switch (bFlags2 & (3 << 6))
|
||||
{
|
||||
case 2:
|
||||
imageScale = NSImageScaleProportionallyDown;
|
||||
break;
|
||||
case 3:
|
||||
imageScale = NSImageScaleAxesIndependently;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
imageScale = NSImageScaleNone;
|
||||
break;
|
||||
case 1:
|
||||
imageScale = NSImageScaleProportionallyUpOrDown;
|
||||
break;
|
||||
}
|
||||
[self setImageScaling: imageScale];
|
||||
}
|
||||
if ([aDecoder containsValueForKey: @"NSAlternateImage"])
|
||||
{
|
||||
|
@ -1882,6 +1944,8 @@ typedef struct _GSButtonCellFlags
|
|||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &tmp];
|
||||
_shows_border_only_while_mouse_inside = tmp;
|
||||
}
|
||||
// Not encoded in non-keyed archive
|
||||
_imageScaling = NSImageScaleNone;
|
||||
}
|
||||
|
||||
// Hack to correct a Gorm problem, there "\n" is used instead of "\r".
|
||||
|
|
|
@ -3015,4 +3015,66 @@ static NSColor *dtxtCol;
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method used by NSImageCell and NSButtonCell for calculating
|
||||
* scaled image size
|
||||
*/
|
||||
|
||||
static inline NSSize
|
||||
scaleProportionally(NSSize imageSize, NSSize canvasSize, BOOL scaleUpOrDown)
|
||||
{
|
||||
CGFloat ratio;
|
||||
|
||||
if (imageSize.width <= 0
|
||||
|| imageSize.height <= 0)
|
||||
{
|
||||
return NSMakeSize(0, 0);
|
||||
}
|
||||
|
||||
/* Get the smaller ratio and scale the image size by it. */
|
||||
ratio = MIN(canvasSize.width / imageSize.width,
|
||||
canvasSize.height / imageSize.height);
|
||||
|
||||
/* Only scale down, unless scaleUpOrDown is YES */
|
||||
if (ratio < 1.0 || scaleUpOrDown)
|
||||
{
|
||||
imageSize.width *= ratio;
|
||||
imageSize.height *= ratio;
|
||||
}
|
||||
|
||||
return imageSize;
|
||||
}
|
||||
|
||||
- (NSSize) _scaleImageWithSize: (NSSize)imageSize
|
||||
toFitInSize: (NSSize)canvasSize
|
||||
scalingType: (NSImageScaling)scalingType
|
||||
{
|
||||
NSSize result;
|
||||
switch (scalingType)
|
||||
{
|
||||
case NSImageScaleProportionallyDown: // == NSScaleProportionally
|
||||
{
|
||||
result = scaleProportionally (imageSize, canvasSize, NO);
|
||||
break;
|
||||
}
|
||||
case NSImageScaleAxesIndependently: // == NSScaleToFit
|
||||
{
|
||||
result = canvasSize;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case NSImageScaleNone: // == NSScaleNone
|
||||
{
|
||||
result = imageSize;
|
||||
break;
|
||||
}
|
||||
case NSImageScaleProportionallyUpOrDown:
|
||||
{
|
||||
result = scaleProportionally (imageSize, canvasSize, YES);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
#import "GNUstepGUI/GSTheme.h"
|
||||
#import "GSGuiPrivate.h"
|
||||
|
||||
@interface NSCell (Private)
|
||||
- (NSSize) _scaleImageWithSize: (NSSize)imageSize
|
||||
toFitInSize: (NSSize)canvasSize
|
||||
scalingType: (NSImageScaling)scalingType;
|
||||
@end
|
||||
|
||||
@implementation NSImageCell
|
||||
|
||||
//
|
||||
|
@ -171,25 +177,6 @@ yBottomInRect(NSSize innerSize, NSRect outerRect, BOOL flipped)
|
|||
return NSMinY(outerRect);
|
||||
}
|
||||
|
||||
static inline NSSize
|
||||
scaleProportionally(NSSize imageSize, NSRect canvasRect, BOOL scaleUpOrDown)
|
||||
{
|
||||
float ratio;
|
||||
|
||||
/* Get the smaller ratio and scale the image size by it. */
|
||||
ratio = MIN(NSWidth(canvasRect) / imageSize.width,
|
||||
NSHeight(canvasRect) / imageSize.height);
|
||||
|
||||
/* Only scale down, unless scaleUpOrDown is YES */
|
||||
if (ratio < 1.0 || scaleUpOrDown)
|
||||
{
|
||||
imageSize.width *= ratio;
|
||||
imageSize.height *= ratio;
|
||||
}
|
||||
|
||||
return imageSize;
|
||||
}
|
||||
|
||||
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView *)controlView
|
||||
{
|
||||
NSPoint position;
|
||||
|
@ -205,35 +192,9 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect, BOOL scaleUpOrDown)
|
|||
cellFrame = [self drawingRectForBounds: cellFrame];
|
||||
|
||||
realImageSize = [_cell_image size];
|
||||
|
||||
switch (_imageScaling)
|
||||
{
|
||||
case NSScaleProportionally:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleProportionally");
|
||||
imageSize = scaleProportionally (realImageSize, cellFrame, NO);
|
||||
break;
|
||||
}
|
||||
case NSScaleToFit:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleToFit");
|
||||
imageSize = cellFrame.size;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case NSScaleNone:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleNone");
|
||||
imageSize = realImageSize;
|
||||
break;
|
||||
}
|
||||
case NSImageScaleProportionallyUpOrDown:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSImageScaleProportionallyUpOrDown");
|
||||
imageSize = scaleProportionally (realImageSize, cellFrame, YES);
|
||||
break;
|
||||
}
|
||||
}
|
||||
imageSize = [self _scaleImageWithSize: realImageSize
|
||||
toFitInSize: cellFrame.size
|
||||
scalingType: _imageScaling];
|
||||
|
||||
switch (_imageAlignment)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue