mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Much optimised coordinate conversion
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@3783 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f99c78791f
commit
a136e2ee9c
3 changed files with 104 additions and 205 deletions
|
@ -1,3 +1,9 @@
|
|||
Mon Feb 22 8:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* NSView.m: Tidied coordinate conversion code to use new system with
|
||||
a cached conversion matrix to convert to/from window coordinates.
|
||||
* NSView.h: Cache conversion matrices.
|
||||
|
||||
Mon Feb 22 6:06:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* NSView.m: Tidied coordinate conversion code to use new system with
|
||||
|
|
|
@ -76,7 +76,8 @@ enum {
|
|||
NSRect bounds;
|
||||
id frameMatrix;
|
||||
id boundsMatrix;
|
||||
id windowMatrix;
|
||||
id matrixToWindow;
|
||||
id matrixFromWindow;
|
||||
|
||||
NSView* super_view;
|
||||
NSMutableArray *sub_views;
|
||||
|
@ -374,13 +375,8 @@ enum {
|
|||
- (void) _invalidateCoordinates;
|
||||
- (void) _rebuildCoordinates;
|
||||
|
||||
- (PSMatrix*)_frameMatrix;
|
||||
- (PSMatrix*)_boundsMatrix;
|
||||
- (PSMatrix*)_windowMatrix;
|
||||
- (PSMatrix*) _concatenateBoundsMatricesInReverseOrderFromPath: (NSArray*)p;
|
||||
- (PSMatrix*) _concatenateMatricesInReverseOrderFromPath: (NSArray*)p;
|
||||
- (NSMutableArray*) _pathBetweenSubview: (NSView*)subview
|
||||
toSuperview: (NSView*)superview;
|
||||
- (PSMatrix*)_matrixToWindow;
|
||||
- (PSMatrix*)_matrixFromWindow;
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
|
291
Source/NSView.m
291
Source/NSView.m
|
@ -174,9 +174,10 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
bounds.origin = NSZeroPoint; // Set bounds rectangle
|
||||
bounds.size = frame.size;
|
||||
|
||||
frameMatrix = [PSMatrix new]; // init PS matrix for
|
||||
boundsMatrix = [PSMatrix new]; // frame and bounds
|
||||
windowMatrix = [PSMatrix new]; // map to window coordinates
|
||||
frameMatrix = [PSMatrix new]; // Map fromsuperview to frame
|
||||
boundsMatrix = [PSMatrix new]; // Map fromsuperview to bounds
|
||||
matrixToWindow = [PSMatrix new]; // Map to window coordinates
|
||||
matrixFromWindow = [PSMatrix new]; // Map from window coordinates
|
||||
[frameMatrix setFrameOrigin: frame.origin];
|
||||
|
||||
sub_views = [NSMutableArray new];
|
||||
|
@ -199,7 +200,8 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[windowMatrix release];
|
||||
[matrixToWindow release];
|
||||
[matrixFromWindow release];
|
||||
[frameMatrix release];
|
||||
[boundsMatrix release];
|
||||
[sub_views release];
|
||||
|
@ -636,45 +638,15 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aPoint;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* Convert from aView to window
|
||||
*/
|
||||
matrix = [aView _windowMatrix];
|
||||
matrix = [aView _matrixToWindow];
|
||||
new = [matrix pointInMatrixSpace: aPoint];
|
||||
/*
|
||||
* Convert from window to self.
|
||||
*/
|
||||
matrix = [[self _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
new = [matrix pointInMatrixSpace: new];
|
||||
[matrix release];
|
||||
#else
|
||||
if ([self isDescendantOf: aView])
|
||||
{
|
||||
NSMutableArray *path;
|
||||
|
||||
path = [self _pathBetweenSubview: self toSuperview: aView];
|
||||
[path addObject: aView];
|
||||
matrix = [self _concatenateMatricesInReverseOrderFromPath: path];
|
||||
[matrix inverse];
|
||||
new = [matrix pointInMatrixSpace: aPoint];
|
||||
}
|
||||
else if ([aView isDescendantOf: self])
|
||||
{
|
||||
NSMutableArray *path;
|
||||
|
||||
path = [self _pathBetweenSubview: aView toSuperview: self];
|
||||
[path addObject: self];
|
||||
matrix = [self _concatenateMatricesInReverseOrderFromPath: path];
|
||||
new = [matrix pointInMatrixSpace: aPoint];
|
||||
}
|
||||
if (coordinates_valid)
|
||||
matrix = matrixFromWindow;
|
||||
else
|
||||
{
|
||||
new = [aView convertPoint: aPoint toView: nil];
|
||||
new = [self convertPoint: new fromView: nil];
|
||||
}
|
||||
#endif
|
||||
matrix = [self _matrixFromWindow];
|
||||
new = [matrix pointInMatrixSpace: new];
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
@ -689,17 +661,16 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aPoint;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
matrix = [self _windowMatrix];
|
||||
if (coordinates_valid)
|
||||
matrix = matrixToWindow;
|
||||
else
|
||||
matrix = [self _matrixToWindow];
|
||||
new = [matrix pointInMatrixSpace: aPoint];
|
||||
matrix = [[aView _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
|
||||
matrix = [aView _matrixFromWindow];
|
||||
new = [matrix pointInMatrixSpace: new];
|
||||
[matrix release];
|
||||
|
||||
return new;
|
||||
#else
|
||||
return [aView convertPoint: aPoint fromView: self];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSRect) convertRect: (NSRect)aRect fromView: (NSView*)aView
|
||||
|
@ -713,22 +684,20 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aRect;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
matrix = [aView _windowMatrix];
|
||||
matrix = [aView _matrixToWindow];
|
||||
r.origin = [matrix pointInMatrixSpace: aRect.origin];
|
||||
r.size = [matrix sizeInMatrixSpace: aRect.size];
|
||||
matrix = [[self _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
|
||||
if (coordinates_valid)
|
||||
matrix = matrixFromWindow;
|
||||
else
|
||||
matrix = [self _matrixFromWindow];
|
||||
r.origin = [matrix pointInMatrixSpace: r.origin];
|
||||
r.size = [matrix sizeInMatrixSpace: r.size];
|
||||
[matrix release];
|
||||
#else
|
||||
r = aRect;
|
||||
r.origin = [self convertPoint: r.origin fromView: aView];
|
||||
r.size = [self convertSize: r.size fromView: aView];
|
||||
#endif
|
||||
|
||||
if ([aView isFlipped] != [self isFlipped])
|
||||
r.origin.y -= r.size.height;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -743,20 +712,17 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aRect;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
matrix = [self _windowMatrix];
|
||||
if (coordinates_valid)
|
||||
matrix = matrixToWindow;
|
||||
else
|
||||
matrix = [self _matrixToWindow];
|
||||
r.origin = [matrix pointInMatrixSpace: aRect.origin];
|
||||
r.size = [matrix sizeInMatrixSpace: aRect.size];
|
||||
matrix = [[aView _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
|
||||
matrix = [aView _matrixFromWindow];
|
||||
r.origin = [matrix pointInMatrixSpace: r.origin];
|
||||
r.size = [matrix sizeInMatrixSpace: r.size];
|
||||
[matrix release];
|
||||
#else
|
||||
r = aRect;
|
||||
r.origin = [self convertPoint: r.origin toView: aView];
|
||||
r.size = [self convertSize: r.size toView: aView];
|
||||
#endif
|
||||
|
||||
if ([aView isFlipped] != [self isFlipped])
|
||||
r.origin.y -= r.size.height;
|
||||
|
||||
|
@ -774,41 +740,15 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aSize;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* Convert from aView to window
|
||||
*/
|
||||
matrix = [aView _windowMatrix];
|
||||
matrix = [aView _matrixToWindow];
|
||||
new = [matrix sizeInMatrixSpace: aSize];
|
||||
/*
|
||||
* Convert from window to self.
|
||||
*/
|
||||
matrix = [[self _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
new = [matrix sizeInMatrixSpace: new];
|
||||
[matrix release];
|
||||
#else
|
||||
if ([self isDescendantOf: aView])
|
||||
{
|
||||
NSArray* path = [self _pathBetweenSubview: self toSuperview: aView];
|
||||
|
||||
matrix = [self _concatenateBoundsMatricesInReverseOrderFromPath: path];
|
||||
[matrix inverse];
|
||||
new = [matrix sizeInMatrixSpace: aSize];
|
||||
}
|
||||
else if ([aView isDescendantOf: self])
|
||||
{
|
||||
NSArray* path = [self _pathBetweenSubview: aView toSuperview: self];
|
||||
|
||||
matrix = [self _concatenateBoundsMatricesInReverseOrderFromPath: path];
|
||||
new = [matrix sizeInMatrixSpace: aSize];
|
||||
}
|
||||
if (coordinates_valid)
|
||||
matrix = matrixFromWindow;
|
||||
else
|
||||
{
|
||||
new = [aView convertSize: aSize toView: nil];
|
||||
new = [self convertSize: new fromView: nil];
|
||||
}
|
||||
#endif
|
||||
matrix = [self _matrixFromWindow];
|
||||
new = [matrix sizeInMatrixSpace: new];
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
@ -823,17 +763,16 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
return aSize;
|
||||
NSAssert(window == [aView window], NSInvalidArgumentException);
|
||||
|
||||
#if 1
|
||||
matrix = [self _windowMatrix];
|
||||
if (coordinates_valid)
|
||||
matrix = matrixToWindow;
|
||||
else
|
||||
matrix = [self _matrixToWindow];
|
||||
new = [matrix sizeInMatrixSpace: aSize];
|
||||
matrix = [[aView _windowMatrix] copy];
|
||||
[matrix inverse];
|
||||
|
||||
matrix = [aView _matrixFromWindow];
|
||||
new = [matrix sizeInMatrixSpace: new];
|
||||
[matrix release];
|
||||
|
||||
return new;
|
||||
#else
|
||||
return [aView convertSize: aSize fromView: self];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) setPostsFrameChangedNotifications: (BOOL)flag
|
||||
|
@ -1846,68 +1785,15 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
* Private methods.
|
||||
*/
|
||||
|
||||
- (NSRect) _boundingRectFor: (NSRect)rect
|
||||
{
|
||||
NSRect new;
|
||||
|
||||
[frameMatrix boundingRectFor: rect result: &new];
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
- (PSMatrix*) _boundsMatrix
|
||||
{
|
||||
return boundsMatrix;
|
||||
}
|
||||
|
||||
- (PSMatrix*) _concatenateBoundsMatricesInReverseOrderFromPath: (NSArray*)viewsPath
|
||||
{
|
||||
unsigned count = [viewsPath count];
|
||||
PSMatrix* matrix = [[PSMatrix new] autorelease];
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
NSView* view = [viewsPath objectAtIndex: --count];
|
||||
|
||||
[matrix concatenateWith: view->boundsMatrix];
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
- (PSMatrix*) _concatenateMatricesInReverseOrderFromPath: (NSArray*)viewsPath
|
||||
{
|
||||
PSMatrix *matrix = [[PSMatrix new] autorelease];
|
||||
unsigned i = [viewsPath count];
|
||||
NSView *matrices[i];
|
||||
NSView *parent;
|
||||
BOOL wasFlipped;
|
||||
BOOL isFlipped;
|
||||
|
||||
if (i-- < 2)
|
||||
return matrix;
|
||||
[viewsPath getObjects: matrices];
|
||||
parent = matrices[i];
|
||||
wasFlipped = [parent isFlipped];
|
||||
while (i-- > 0)
|
||||
{
|
||||
NSView *view = matrices[i];
|
||||
|
||||
(*concatImp)(matrix, concatSel, view->frameMatrix);
|
||||
isFlipped = [view isFlipped];
|
||||
if (isFlipped != wasFlipped)
|
||||
{
|
||||
flip->matrix[5] = view->bounds.size.height;
|
||||
(*concatImp)(matrix, concatSel, flip);
|
||||
}
|
||||
(*concatImp)(matrix, concatSel, view->boundsMatrix);
|
||||
parent = view;
|
||||
wasFlipped = isFlipped;
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/*
|
||||
* The [-_invalidateCoordinates] method marks the coordinate mapping
|
||||
* matrices (matrixFromWindof and matrixToWindow) and the cached visible
|
||||
* rectangle as invalid. It recursively invalidates the coordinates for
|
||||
* all subviews as well.
|
||||
* This method must be called whenever the size, shape or position of
|
||||
* the view is changed in any way.
|
||||
*/
|
||||
- (void) _invalidateCoordinates
|
||||
{
|
||||
if (coordinates_valid == YES)
|
||||
|
@ -1933,26 +1819,39 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
}
|
||||
}
|
||||
|
||||
- (PSMatrix*) _frameMatrix
|
||||
/*
|
||||
* The [-_matrixFromWindow] method returns a matrix that can be used to
|
||||
* map coordinates in the windows coordinate system to coordinates in the
|
||||
* views coordinate system. It rebuilds the mapping matrices and
|
||||
* visible rectangle cache if necessary.
|
||||
* All coordinate transformations use this matrix.
|
||||
*/
|
||||
- (PSMatrix*) _matrixFromWindow
|
||||
{
|
||||
return frameMatrix;
|
||||
if (coordinates_valid == NO)
|
||||
[self _rebuildCoordinates];
|
||||
return matrixFromWindow;
|
||||
}
|
||||
|
||||
- (NSMutableArray*) _pathBetweenSubview: (NSView*)subview
|
||||
toSuperview: (NSView*)_superview
|
||||
/*
|
||||
* The [-_matrixToWindow] method returns a matrix that can be used to
|
||||
* map coordinates in the views coordinate system to coordinates in the
|
||||
* windows coordinate system. It rebuilds the mapping matrices and
|
||||
* visible rectangle cache if necessary.
|
||||
* All coordinate transformations use this matrix.
|
||||
*/
|
||||
- (PSMatrix*) _matrixToWindow
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
NSView *view = subview;
|
||||
|
||||
while (view && view != _superview)
|
||||
{
|
||||
[array addObject: view];
|
||||
view = view->super_view;
|
||||
}
|
||||
|
||||
return array;
|
||||
if (coordinates_valid == NO)
|
||||
[self _rebuildCoordinates];
|
||||
return matrixToWindow;
|
||||
}
|
||||
|
||||
/*
|
||||
* The [-_rebuildCoordinates] method rebuilds the coordinate mapping
|
||||
* matrices (matrixFromWindof and matrixToWindow) and the cached visible
|
||||
* rectangle if they have been invalidated.
|
||||
*/
|
||||
- (void) _rebuildCoordinates
|
||||
{
|
||||
if (coordinates_valid == NO)
|
||||
|
@ -1961,29 +1860,34 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
if (!window)
|
||||
{
|
||||
visibleRect = NSZeroRect;
|
||||
[windowMatrix makeIdentityMatrix];
|
||||
[matrixToWindow makeIdentityMatrix];
|
||||
[matrixFromWindow makeIdentityMatrix];
|
||||
}
|
||||
if (!super_view)
|
||||
{
|
||||
visibleRect = bounds;
|
||||
[windowMatrix makeIdentityMatrix];
|
||||
[matrixToWindow makeIdentityMatrix];
|
||||
[matrixFromWindow makeIdentityMatrix];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRect superviewsVisibleRect;
|
||||
BOOL wasFlipped = [super_view isFlipped];
|
||||
float vals[6];
|
||||
PSMatrix *pMatrix = [super_view _windowMatrix];
|
||||
PSMatrix *pMatrix = [super_view _matrixToWindow];
|
||||
|
||||
[pMatrix getMatrix: vals];
|
||||
[windowMatrix setMatrix: vals];
|
||||
(*concatImp)(windowMatrix, concatSel, frameMatrix);
|
||||
[matrixToWindow setMatrix: vals];
|
||||
(*concatImp)(matrixToWindow, concatSel, frameMatrix);
|
||||
if ([self isFlipped] != wasFlipped)
|
||||
{
|
||||
flip->matrix[5] = bounds.size.height;
|
||||
(*concatImp)(windowMatrix, concatSel, flip);
|
||||
(*concatImp)(matrixToWindow, concatSel, flip);
|
||||
}
|
||||
(*concatImp)(windowMatrix, concatSel, boundsMatrix);
|
||||
(*concatImp)(matrixToWindow, concatSel, boundsMatrix);
|
||||
[matrixToWindow getMatrix: vals];
|
||||
[matrixFromWindow setMatrix: vals];
|
||||
[matrixFromWindow inverse];
|
||||
|
||||
superviewsVisibleRect = [self convertRect: [super_view visibleRect]
|
||||
fromView: super_view];
|
||||
|
@ -1993,12 +1897,5 @@ static SEL invalidateSel = @selector(_invalidateCoordinates);
|
|||
}
|
||||
}
|
||||
|
||||
- (PSMatrix*) _windowMatrix
|
||||
{
|
||||
if (coordinates_valid == NO)
|
||||
[self _rebuildCoordinates];
|
||||
return windowMatrix;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in a new issue