Re: Sit on it and rotate ??
Re: Sit on it and rotate ??
- Subject: Re: Sit on it and rotate ??
- From: Chris Meyer <email@hidden>
- Date: Thu, 28 Jun 2001 11:00:16 -0700
Hi Robert,
I subclassed NSImageView and overrode the drawRect: method. My
version only rotates in increments of 90 degrees but it shouldn't be
much difficulty to generalize to any value (you would probably want
to erase the non-image portion using coordinate transformations too
in that case -- my code would probably be simplified by doing that
too). By the way, my constants indicate clockwise rotation. Also,
don't forget to declare your view as opaque by implementing the
message isOpaque.
The basic trick is to apply the rotation and scaling to the CENTER of
the view, not the ORIGIN of the view.
Chris
- (void)drawRect:(NSRect)dstRect
{
NSImage *image = [self image];
if ( image != nil )
{
NSAffineTransform *transform = [NSAffineTransform transform];
NSRect fromRect, toRect;
NSSize size = [image size];
float scale,rotationDegrees;
fromRect.origin.x = 0;
fromRect.origin.y = 0;
fromRect.size = size;
if ( dstRect.size.width/size.width >
dstRect.size.height/size.height ) // scale so height fits
{
toRect.size.width = dstRect.size.height * (size.width/size.height);
toRect.size.height = dstRect.size.height;
toRect.origin.x = (dstRect.size.width - toRect.size.width)/2;
toRect.origin.y = 0;
}
else
// scale so width fits
{
toRect.size.width = dstRect.size.width;
toRect.size.height = dstRect.size.width * (size.height/size.width);
toRect.origin.x = 0;
toRect.origin.y = (dstRect.size.height - toRect.size.height)/2;
}
switch (m_rotation)
{
default:
case Zero:
{
scale = 1;
rotationDegrees = 0;
break;
}
case Ninety:
{
scale = toRect.size.width < toRect.size.height ?
dstRect.size.width/toRect.size.height :
dstRect.size.height/toRect.size.width;
rotationDegrees = -90;
break;
}
case OneEighty:
{
scale = 1;
rotationDegrees = -180;
break;
}
case TwoSeventy:
{
scale = toRect.size.width < toRect.size.height ?
dstRect.size.width/toRect.size.height :
dstRect.size.height/toRect.size.width;
rotationDegrees = 90;
break;
}
}
[transform translateXBy:dstRect.size.width/2
yBy:dstRect.size.height/2];
[transform rotateByDegrees:rotationDegrees];
[transform scaleBy:scale];
[transform translateXBy:-dstRect.size.width/2
yBy:-dstRect.size.height/2];
// erase the outside rects first so if we have pixel errors
we draw the image
// LAST!
{
NSRect toRect2;
[NSGraphicsContext saveGraphicsState];
[[NSColor blackColor] set];
toRect2.origin = [transform transformPoint:toRect.origin];
toRect2.size = [transform transformSize:toRect.size];
if ( toRect2.size.width < 0 )
{
toRect2.size.width = -toRect2.size.width;
toRect2.origin.x -= toRect2.size.width;
}
if ( toRect2.size.height < 0 )
{
toRect2.size.height = -toRect2.size.height;
toRect2.origin.y -= toRect2.size.height;
}
if ( NSMinX( dstRect ) < NSMinX( toRect2 ) )
NSRectFill( NSMakeRect( NSMinX( dstRect ), NSMinY( dstRect ),
NSMinX( toRect2 ) - NSMinX( dstRect ),
dstRect.size.height ) );
if ( NSMaxX( dstRect ) > NSMaxX( toRect2 ) )
NSRectFill( NSMakeRect( NSMaxX( toRect2 ), NSMinY( dstRect ),
NSMaxX( dstRect ) - NSMaxX( toRect2 ),
dstRect.size.height ) );
if ( NSMinY( dstRect ) < NSMinY( toRect2 ) )
NSRectFill( NSMakeRect( NSMinX( dstRect ), NSMinY( dstRect ),
dstRect.size.width, NSMinY( toRect2 ) - NSMinY(
dstRect ) ) );
if ( NSMaxY( dstRect ) > NSMaxY( toRect2 ) )
NSRectFill( NSMakeRect( NSMinX( dstRect ), NSMaxY( toRect2 ),
dstRect.size.width, NSMaxY( dstRect ) - NSMaxY(
toRect2 ) ) );
[NSGraphicsContext restoreGraphicsState];
}
[transform concat];
[image drawInRect:toRect fromRect:fromRect
operation:NSCompositeCopy fraction:1.0];
NSFrameRect( toRect );
[transform invert];
[transform concat];
}
else
{
NSEraseRect( dstRect );
}
}