mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 15:11:37 +00:00
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:
parent
988118d5e0
commit
8da1677ce3
3 changed files with 139 additions and 56 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
151
Source/NSView.m
151
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)
|
||||
|
|
Loading…
Reference in a new issue