Attempt to handle bounds setting on NSView better.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@25308 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2007-07-09 16:42:32 +00:00
parent 988118d5e0
commit 8da1677ce3
3 changed files with 139 additions and 56 deletions

View file

@ -1,3 +1,14 @@
2007-07-09 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSAffineTransform.m (-rectInMatrixSpace:, -translateToPoint:,
-makeIdentityMatrix): Use optimized primitive methods from base.
* Source/NSAffineTransform.m (-scaleTo::): Try to handle rotation
case better.
* Source/NSView.m (-scaleUnitSquareToSize:): Adjust origin too and
handle rotation case.
* Source/NSView.m (-setBounds:, setBoundsOrigin:): Try to handle
rotation case better.
2007-07-04 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSCell.m (-encodeWithCoder:): Try to better key encode

View file

@ -106,41 +106,33 @@ static const float pi = 3.1415926535897932384626434;
/* If it's rotated. */
if (B != 0 || C != 0)
{
// FIXME: This case does not handle shear.
float angle = [self rotationAngle];
// Keep the translation and add scaling
A = sx; B = 0;
C = 0; D = sy;
[self setTransformStruct: matrix];
// Prepend the rotation to the scaling and translation
[self rotateByDegrees: angle];
}
else
{
A = sx; B = 0;
C = 0; D = sy;
[self setTransformStruct: matrix];
}
[self setTransformStruct: matrix];
}
- (void) translateToPoint: (NSPoint)point
{
NSAffineTransformStruct matrix = [self transformStruct];
float newTX, newTY;
newTX = point.x * A + point.y * C + TX;
newTY = point.x * B + point.y * D + TY;
TX = newTX;
TY = newTY;
[self setTransformStruct: matrix];
[self translateXBy: point.x yBy: point.y];
}
- (void) makeIdentityMatrix
{
static NSAffineTransformStruct identityTransform = {
1.0, 0.0, 0.0, 1.0, 0.0, 0.0
};
[self setTransformStruct: identityTransform];
[self init];
}
- (void) setFrameOrigin: (NSPoint)point
@ -148,7 +140,8 @@ static const float pi = 3.1415926535897932384626434;
NSAffineTransformStruct matrix = [self transformStruct];
float dx = point.x - TX;
float dy = point.y - TY;
[self translateToPoint: NSMakePoint(dx, dy)];
[self translateXBy: dx yBy: dy];
}
- (void) setFrameRotation: (float)angle
@ -284,19 +277,17 @@ static const float pi = 3.1415926535897932384626434;
- (NSRect) rectInMatrixSpace: (NSRect)rect
{
NSAffineTransformStruct matrix = [self transformStruct];
NSRect new;
new.origin.x = A * rect.origin.x + C * rect.origin.y + TX;
new.size.width = A * rect.size.width + C * rect.size.height;
new.origin = [self transformPoint: rect.origin];
new.size = [self transformSize: rect.size];
if (new.size.width < 0)
{
new.origin.x += new.size.width;
new.size.width *= -1;
}
new.origin.y = B * rect.origin.x + D * rect.origin.y + TY;
new.size.height = B * rect.size.width + D * rect.size.height;
if (new.size.height < 0)
{
new.origin.y += new.size.height;

View file

@ -222,29 +222,29 @@ GSSetDragTypes(NSView* obj, NSArray *types)
_coordinates_valid = NO;
if (_rFlags.valid_rects != 0)
{
[_window invalidateCursorRectsForView: self];
}
{
[_window invalidateCursorRectsForView: self];
}
if (_rFlags.has_subviews)
{
count = [_sub_views count];
if (count > 0)
{
NSView* array[count];
unsigned i;
[_sub_views getObjects: array];
for (i = 0; i < count; i++)
{
NSView *sub = array[i];
if (sub->_coordinates_valid == YES)
{
(*invalidateImp)(sub, invalidateSel);
}
}
}
}
{
count = [_sub_views count];
if (count > 0)
{
NSView* array[count];
unsigned i;
[_sub_views getObjects: array];
for (i = 0; i < count; i++)
{
NSView *sub = array[i];
if (sub->_coordinates_valid == YES)
{
(*invalidateImp)(sub, invalidateSel);
}
}
}
}
[self renewGState];
}
}
@ -1002,6 +1002,7 @@ GSSetDragTypes(NSView* obj, NSArray *types)
float sx;
float sy;
// FIXME: The computation here is wrong when there is a rotation involved.
if (_bounds.size.width == 0)
{
if (_frame.size.width == 0)
@ -1240,16 +1241,35 @@ GSSetDragTypes(NSView* obj, NSArray *types)
{
(*invalidateImp)(self, invalidateSel);
}
_bounds.size.width = _bounds.size.width / newSize.width;
_bounds.size.height = _bounds.size.height / newSize.height;
// FIXME: This should also affect the _bounds.origin.
// I suggest implementing this method via a matrix multiplication
// on _boundsMatrix with a scaled matrix and getting the new
// bounds from the matrix.
if (_boundsMatrix == nil)
{
_boundsMatrix = [NSAffineTransform new];
}
[_boundsMatrix scaleXBy: newSize.width yBy: newSize.height];
if (_is_rotated_from_base)
{
NSAffineTransform *matrix;
NSRect frame = _frame;
frame.origin = NSMakePoint(0, 0);
// Adjust bounds
matrix = [_boundsMatrix copy];
[matrix invert];
[matrix boundingRectFor: frame result: &_bounds];
RELEASE(matrix);
}
else
{
_bounds.origin.x = _bounds.origin.x / newSize.width;
_bounds.origin.y = _bounds.origin.y / newSize.height;
_bounds.size.width = _bounds.size.width / newSize.width;
_bounds.size.height = _bounds.size.height / newSize.height;
}
_is_rotated_or_scaled_from_base = YES;
[self _updateBoundsMatrix];
if (_post_bounds_changes)
{
@ -1271,15 +1291,47 @@ GSSetDragTypes(NSView* obj, NSArray *types)
NSWarnMLog(@"given negative height", 0);
aRect.size.height = 0;
}
if (NSEqualRects(_bounds, aRect) == NO)
if (_is_rotated_from_base)
{
NSAffineTransform *matrix;
NSRect frame = _frame;
frame.origin = NSMakePoint(0, 0);
if (_coordinates_valid)
{
(*invalidateImp)(self, invalidateSel);
}
if (_boundsMatrix == nil)
{
_boundsMatrix = [NSAffineTransform new];
}
[_boundsMatrix
setFrameOrigin: NSMakePoint(-aRect.origin.x, -aRect.origin.y)];
/*
FIXME: We need to adjust the size as well, but the computation in
_updateBoundsMatrix is wrong for this case.
_bounds.size = aRect.size;
[self _updateBoundsMatrix];
*/
// Adjust bounds
matrix = [_boundsMatrix copy];
[matrix invert];
[matrix boundingRectFor: frame result: &_bounds];
RELEASE(matrix);
if (_post_bounds_changes)
{
[nc postNotificationName: NSViewBoundsDidChangeNotification
object: self];
}
}
else if (NSEqualRects(_bounds, aRect) == NO)
{
if (_coordinates_valid)
{
(*invalidateImp)(self, invalidateSel);
}
// FIXME: This is wrong, when bounds are rotated.
// In this case we should first rotate the new bounds and take
// the result values.
_bounds = aRect;
if (_boundsMatrix == nil)
{
@ -1299,7 +1351,35 @@ GSSetDragTypes(NSView* obj, NSArray *types)
- (void) setBoundsOrigin: (NSPoint)newOrigin
{
if (NSEqualPoints(_bounds.origin, newOrigin) == NO)
if (_is_rotated_from_base)
{
NSAffineTransform *matrix;
NSRect frame = _frame;
frame.origin = NSMakePoint(0, 0);
if (_coordinates_valid)
{
(*invalidateImp)(self, invalidateSel);
}
if (_boundsMatrix == nil)
{
_boundsMatrix = [NSAffineTransform new];
}
[_boundsMatrix setFrameOrigin: NSMakePoint(-newOrigin.x, -newOrigin.y)];
// Adjust bounds
matrix = [_boundsMatrix copy];
[matrix invert];
[matrix boundingRectFor: frame result: &_bounds];
RELEASE(matrix);
if (_post_bounds_changes)
{
[nc postNotificationName: NSViewBoundsDidChangeNotification
object: self];
}
}
else if (NSEqualPoints(_bounds.origin, newOrigin) == NO)
{
if (_coordinates_valid)
{
@ -1332,6 +1412,7 @@ GSSetDragTypes(NSView* obj, NSArray *types)
NSWarnMLog(@"given negative height", 0);
newSize.height = 0;
}
// FIXME: What to do in the rotation case?
if (NSEqualSizes(_bounds.size, newSize) == NO)
{
if (_coordinates_valid)