From febbfa037137a37d7ca1969af1eec73b29fb64d2 Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Mon, 9 Jul 2007 16:42:32 +0000 Subject: [PATCH] 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 --- ChangeLog | 11 +++ Source/NSAffineTransform.m | 33 +++----- Source/NSView.m | 151 ++++++++++++++++++++++++++++--------- 3 files changed, 139 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index d25364301..c7d609cf1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-07-09 Fred Kiefer + + * 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 * Source/NSCell.m (-encodeWithCoder:): Try to better key encode diff --git a/Source/NSAffineTransform.m b/Source/NSAffineTransform.m index 355da9d53..952ddbc6f 100644 --- a/Source/NSAffineTransform.m +++ b/Source/NSAffineTransform.m @@ -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; diff --git a/Source/NSView.m b/Source/NSView.m index 478cdb935..89ae86cca 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -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)