Added scaling and rotation support.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2386 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Scott Christley 1997-08-18 17:10:23 +00:00
parent 8400afb2ee
commit d4bfac2d3a
30 changed files with 545 additions and 154 deletions

View file

@ -1,3 +1,43 @@
Mon Aug 18 09:38:27 1997 Ovidiu Predescu <ovidiu@net-community.com>
Start porting to NeXT PDO under Solaris.
* Headers/gnustep/gui/NSCStringText.h: Include Foundation/NSString.h.
* Headers/gnustep/gui/NSScreen.h: Declare NSArray.
* Headers/gnustep/gui/NSText.h: Include Foundation/NSRange.h.
* Source/NSBox.m: Include Foundation/NSString.h.
* Source/NSButtonCell.m: Likewise.
* Source/NSCachedImageRep.m: Likewise.
* Source/NSCell.m: Likewise.
* Source/NSColor.m: Likewise.
* Source/NSFont.m: Likewise.
* Source/NSImage.m: Likewise.
* Source/NSMenuItem.m: Likewise.
* Source/NSOpenPanel.m: Likewise.
* Source/NSSavePanel.m: Likewise.
* Source/NSSliderCell.m: Likewise.
* Source/NSText.m: Likewise.
* Source/NSTextField.m: Likewise.
* Source/libgnustep-gui.m: Likewise.
* Source/NSDPSContext.m: Likewise. Also declare -copyWithZone: for
NSThread to make possible adding it to Foundation containers.
Add scaling and rotation support.
* Headers/gnustep/gui/NSView.h: Remove frame_rotation. Add frameMatrix
and boundsMatrix instance variables.
* Source/PSMatrix.m: New file.
* Headers/gnustep/gui/PSMatrix.h: New file.
* Source/Makefile.in: Added PSMatrix.m.
* Source/NSView.m: Use two PSMatrix to do all the scaling and rotation
stuff instead of dealing with angles and scale factors. Change the
implementation of methods that convert points and sizes to use these
matrices.
* Source/NSWindow.m (-checkCursorRectangles:forEvent:): Changed to work
with scaled and rotated views.
* Headers/gnustep/gui/config.h.in: Declare initialize_gnustep_backend.
* Source/NSMenu.m (-copyWithZone:): Create a proper copy of
NSMenuMatrix.
Sat Aug 16 16:28:31 1997 Scott Christley <scottc@net-community.com>
* Headers/gnustep/gui/NSApplication.h (+setNullEvent:): New method.

View file

@ -28,6 +28,7 @@
#ifndef _GNUstep_H_NSCStringText
#define _GNUstep_H_NSCStringText
#include <Foundation/NSString.h>
#include <AppKit/NSText.h>
#include <AppKit/NSFontManager.h>

View file

@ -33,6 +33,7 @@
#include <Foundation/NSObject.h>
#include <AppKit/NSGraphics.h>
@class NSArray;
@class NSDictionary;
@class NSMutableDictionary;

View file

@ -31,6 +31,7 @@
#include <AppKit/NSView.h>
#include <AppKit/NSSpellProtocol.h>
#include <Foundation/NSRange.h>
@class NSString;
@class NSData;

View file

@ -6,7 +6,8 @@
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Ovidiu Predescu <ovidiu@net-community.com>
Date: 1996, 1997
This file is part of the GNUstep GUI Library.
@ -68,7 +69,8 @@ enum {
// Attributes
NSRect frame;
NSRect bounds;
float frame_rotation;
id frameMatrix;
id boundsMatrix;
id super_view;
NSMutableArray *sub_views;

View file

@ -0,0 +1,68 @@
/*
PSMatrix.h
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Ovidiu Predescu <ovidiu@net-community.com>
Date: August 1997
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _GNUstep_H_PSMatrix
#define _GNUstep_H_PSMatrix
#include <Foundation/NSObject.h>
#include <Foundation/NSGeometry.h>
@interface PSMatrix : NSObject <NSCopying>
{
float matrix[6];
float rotationAngle;
}
+ matrixFrom:(float[6])matrix;
- (void)translateToPoint:(NSPoint)point;
- (void)rotateByAngle:(float)angle;
- (void)scaleBy:(float)sx :(float)sy;
- (void)makeIdentityMatrix;
- (float)rotationAngle;
- (void)setFrameOrigin:(NSPoint)point;
- (void)setFrameRotation:(float)angle;
- (void)inverse;
/* Returns anotherMatrix * self */
- (void)concatenateWith:(PSMatrix*)anotherMatrix;
- (NSPoint)pointInMatrixSpace:(NSPoint)point;
- (NSSize)sizeInMatrixSpace:(NSSize)size;
@end
@interface PSMatrix (BackendMethods)
- (void)set;
@end
/* Private definitions */
#define A matrix[0]
#define B matrix[1]
#define C matrix[2]
#define D matrix[3]
#define TX matrix[4]
#define TY matrix[5]
#endif /* _GNUstep_H_PSMatrix */

View file

@ -48,5 +48,7 @@
# endif
#endif /* !NSDebugLog */
extern BOOL initialize_gnustep_backend (void);
#endif /* _GNUstep_H_AppKitConfig */

View file

@ -230,6 +230,7 @@ NSView$(oext) \
NSWindow$(oext) \
NSWorkspace$(oext) \
TrackingRectangle$(oext) \
PSMatrix$(oext) \
tiff$(oext) \
externs$(oext)

View file

@ -27,6 +27,8 @@
*/
#include <Foundation/NSArray.h>
#include <Foundation/NSString.h>
#include <AppKit/NSBox.h>
#include <AppKit/NSTextFieldCell.h>

View file

@ -28,6 +28,8 @@
#include <Foundation/NSLock.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSString.h>
#include <AppKit/NSButtonCell.h>
#include <AppKit/NSButton.h>
#include <AppKit/NSWindow.h>

View file

@ -30,7 +30,10 @@
message initFromWindow:rect: is sent with a nil window, one is created
using the rect information.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSException.h>
#include <AppKit/NSCachedImageRep.h>
#include <AppKit/NSWindow.h>

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSApplication.h>

View file

@ -26,6 +26,8 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSColorPrivate.h>
#include <AppKit/NSView.h>

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSThread.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSData.h>
@ -58,6 +59,15 @@ static NSRecursiveLock *GNU_CONTEXT_LOCK = nil;
static BOOL GNU_CONTEXT_TRACED = NO;
static BOOL GNU_CONTEXT_SYNCHRONIZED = NO;
#if defined(NeXT_PDO)
@implementation NSThread (Containers)
- copyWithZone:(NSZone*)zone
{
return [self retain];
}
@end
#endif
@implementation NSDPSContext
+ (void)initialize

View file

@ -27,6 +27,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSSet.h>

View file

@ -32,6 +32,7 @@
*/
#include <string.h>
#include <Foundation/NSString.h>
#include <Foundation/NSException.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSValue.h>

View file

@ -349,7 +349,7 @@ static int mouseDownFlags = 0;
{
int i, j;
[super initWithFrame: frameRect];
[super initWithFrame:frameRect];
ASSIGN(cellPrototype, prototype);

View file

@ -84,11 +84,10 @@ static NSFont* menuFont = nil;
- (id)copyWithZone:(NSZone*)zone
{
NSMenuMatrix* copy = NSAllocateObject (isa, 0, zone);
NSMenuMatrix* copy = [[isa alloc] initWithFrame:[self frame]];
int i, count;
NSDebugLog (@"copy menu matrix of menu with title '%@'", [menu title]);
copy->cells = [[NSMutableArray alloc] initWithCapacity:[cells count]];
for (i = 0, count = [cells count]; i < count; i++) {
id aCell = [cells objectAtIndex:i];
id cellCopy = [[aCell copyWithZone:zone] autorelease];

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDictionary.h>
#include <AppKit/NSMenuItem.h>

View file

@ -27,6 +27,7 @@
*/
#include <string.h>
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <AppKit/NSOpenPanel.h>

View file

@ -28,6 +28,7 @@
#include <string.h>
#include <Foundation/NSString.h>
#include <Foundation/NSCoder.h>
#include <AppKit/NSSavePanel.h>

View file

@ -496,6 +496,9 @@ static NSButtonCell* knobCell = nil;
- (void)drawRect:(NSRect)rect
{
NSLog (@"NSScroller drawRect: ((%f, %f), (%f, %f))",
rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
/* Draw the scroller buttons */
[self drawArrow:NSScrollerDecrementArrow highlight:NO];
[self drawArrow:NSScrollerIncrementArrow highlight:NO];

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <AppKit/NSSliderCell.h>
#include <AppKit/NSControl.h>
#include <AppKit/NSApplication.h>

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <AppKit/NSText.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSWindow.h>

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <AppKit/NSTextField.h>
#include <AppKit/NSWindow.h>
#include <AppKit/NSTextFieldCell.h>

View file

@ -26,6 +26,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <AppKit/NSTextFieldCell.h>
#include <AppKit/NSTextField.h>

View file

@ -6,7 +6,8 @@
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Ovidiu Predescu <ovidiu@net-community.com>
Date: 1996, 1997
This file is part of the GNUstep GUI Library.
@ -26,6 +27,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSThread.h>
@ -35,7 +37,8 @@
#include <AppKit/NSView.h>
#include <AppKit/NSWindow.h>
#include <gnustep/gui/TrackingRectangle.h>
#include <AppKit/TrackingRectangle.h>
#include <AppKit/PSMatrix.h>
//
// Class variables
@ -150,6 +153,10 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
bounds.origin = NSZeroPoint;
bounds.size = frame.size;
frameMatrix = [PSMatrix new];
boundsMatrix = [PSMatrix new];
[frameMatrix setFrameOrigin:frame.origin];
// Initialize subview list
sub_views = [NSMutableArray new];
@ -186,21 +193,11 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
//
- (void)addSubview:(NSView *)aView
{
// Not a NSView --then forget it
// xxx but NSView will really be the backend class
// so how do we check that its really a subclass of NSView
// and not of the backend class?
#if 0
if (![aView isKindOfClass:[NSView class]])
// make sure we aren't making ourself a subview of ourself or we're not
// creating a cycle in the views hierarchy
if ([self isDescendantOf:aView])
{
return;
}
#endif
// make sure we aren't making ourself a subview of ourself
if (self == aView)
{
NSLog(@"Attempt to make view a subview of itself\n");
NSLog(@"Operation addSubview: will create a cycle in the views tree!\n");
return;
}
@ -215,13 +212,14 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
positioned:(NSWindowOrderingMode)place
relativeTo:(NSView *)otherView
{
// Not a NSView --then forget it
// xxx but NSView will really be the backend class
// so how do we check that its really a subclass of NSView
// and not of the backend class?
#if 0
if (![aView isKindOfClass:[NSView class]]) return;
#endif
// make sure we aren't making ourself a subview of ourself or we're not
// creating a cycle in the views hierarchy
if ([self isDescendantOf:aView])
{
NSLog(@"Operation addSubview:positioned:relativeTo: will create a cycle "
@"in the views tree!\n");
return;
}
// Add to our subview list
[sub_views addObject:(id)aView];
@ -262,14 +260,6 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (BOOL)isDescendantOf:(NSView *)aView
{
// Not a NSView --then forget it
// xxx but NSView will really be the backend class
// so how do we check that its really a subclass of NSView
// and not of the backend class?
#if o
if (![aView isKindOfClass:[NSView class]]) return NO;
#endif
// Quick check
if (aView == self) return YES;
@ -350,9 +340,10 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
//
// Modifying the Frame Rectangle
//
- (float)frameRotation
{
return frame_rotation;
return [frameMatrix rotationAngle];
}
- (NSRect)frame
@ -362,6 +353,8 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)rotateByAngle:(float)angle
{
[boundsMatrix rotateByAngle:angle];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -373,6 +366,7 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
frame = frameRect;
bounds.size = frame.size;
[frameMatrix setFrameOrigin:frame.origin];
// Resize subviews
[self resizeSubviewsWithOldSize: old_size];
@ -384,25 +378,19 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)setFrameOrigin:(NSPoint)newOrigin
{
frame.origin = newOrigin;
[frameMatrix setFrameOrigin:frame.origin];
if (post_frame_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewFrameDidChangeNotification object:self];
}
- (void)setFrameRotation:(float)angle
{
if (post_frame_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewFrameDidChangeNotification object:self];
}
- (void)setFrameSize:(NSSize)newSize
{
NSSize old_size = bounds.size;
frame.size = newSize;
bounds.size = newSize;
frame.size = bounds.size = newSize;
// Resize subviews
[self resizeSubviewsWithOldSize: old_size];
@ -411,13 +399,22 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
postNotificationName:NSViewFrameDidChangeNotification object:self];
}
- (void)setFrameRotation:(float)angle
{
[frameMatrix setFrameRotation:angle];
if (post_frame_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewFrameDidChangeNotification object:self];
}
//
// Modifying the Coordinate System
//
- (float)boundsRotation
{
return 0;
return [boundsMatrix rotationAngle];
}
- (NSRect)bounds
@ -432,16 +429,29 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (BOOL)isRotatedFromBase
{
// TODO
return is_rotated_from_base;
}
- (BOOL)isRotatedOrScaledFromBase
{
// TODO
return is_rotated_or_scaled_from_base;
}
- (void)scaleUnitSquareToSize:(NSSize)newSize
{
if (!newSize.width)
newSize.width = 1;
if (!newSize.height)
newSize.height = 1;
bounds.size.width = frame.size.width / newSize.width;
bounds.size.height = frame.size.height / newSize.height;
[boundsMatrix scaleBy:frame.size.width / bounds.size.width
:frame.size.height / bounds.size.height];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -450,6 +460,10 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)setBounds:(NSRect)aRect
{
bounds = aRect;
[boundsMatrix setFrameOrigin:bounds.origin];
[boundsMatrix scaleBy:frame.size.width / bounds.size.width
:frame.size.height / bounds.size.height];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -458,13 +472,8 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)setBoundsOrigin:(NSPoint)newOrigin
{
bounds.origin = newOrigin;
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
}
[boundsMatrix setFrameOrigin:newOrigin];
- (void)setBoundsRotation:(float)angle
{
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -473,6 +482,18 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)setBoundsSize:(NSSize)newSize
{
bounds.size = newSize;
[boundsMatrix scaleBy:frame.size.width / bounds.size.width
:frame.size.height / bounds.size.height];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
}
- (void)setBoundsRotation:(float)angle
{
[boundsMatrix setFrameRotation:angle];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -480,6 +501,8 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (void)translateOriginToPoint:(NSPoint)point
{
[boundsMatrix translateToPoint:point];
if (post_bounds_changes)
[[NSNotificationCenter defaultCenter]
postNotificationName:NSViewBoundsDidChangeNotification object:self];
@ -488,107 +511,79 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
//
// Converting Coordinates
//
- (NSPoint)convertPointToWindow:(NSPoint)p
{
NSRect f, t;
NSPoint a;
id s;
a = p;
f = [self frame];
if ([self isFlipped])
a.y = f.size.height - p.y;
s = [self superview];
// climb up the superview chain
while (s)
{
t = [s frame];
// translate frame
f.origin.x += t.origin.x;
if ([s isFlipped])
f.origin.y += t.size.height + t.origin.y;
else
f.origin.y += t.origin.y;
s = [s superview];
}
a.x += f.origin.x;
a.y += f.origin.y;
return a;
}
- (NSRect)convertRectToWindow:(NSRect)r
{
NSRect a;
a.origin = [self convertPointToWindow:r.origin];
a.size = r.size;
return a;
}
- (NSRect)centerScanRect:(NSRect)aRect
{
return NSZeroRect;
}
- (NSPoint)convertPoint:(NSPoint)aPoint
fromView:(NSView *)aView
- (PSMatrix*)_concatenateMatricesInReverseOrderFromPath:(NSArray*)viewsPath
{
NSPoint p, q;
int i, count = [viewsPath count];
PSMatrix* matrix = [[PSMatrix new] autorelease];
// Must belong to the same window
if (([self window] != [aView window]) && (aView))
return NSZeroPoint;
for (i = count - 1; i >= 0; i--) {
NSView* view = [viewsPath objectAtIndex:i];
// if aView is nil
// then converting from window
// so convert from the content from the content view of the window
if (aView == nil)
return [self convertPoint: aPoint fromView:[[self window] contentView]];
[matrix concatenateWith:view->frameMatrix];
[matrix concatenateWith:view->boundsMatrix];
}
// Convert the point to window coordinates
p = [aView convertPointToWindow: aPoint];
return matrix;
}
// Convert out origin to window coordinates
q = [self convertPointToWindow: bounds.origin];
- (NSArray*)_pathBetweenSubview:(NSView*)subview
toSuperview:(NSView*)_superview
{
NSMutableArray* array = [NSMutableArray array];
NSView* view = subview;
NSDebugLog(@"point convert: %f %f %f %f\n", p.x, p.y, q.x, q.y);
while (view != _superview) {
[array addObject:view];
view = view->super_view;
}
// now translate
p.x -= q.x;
p.y -= q.y;
return array;
}
return p;
- (NSPoint)convertPoint:(NSPoint)aPoint
fromView:(NSView*)aView
{
NSPoint new;
PSMatrix* matrix;
if (!aView)
aView = [[self window] contentView];
if ([self isDescendantOf:aView]) {
NSArray* path = [self _pathBetweenSubview:self toSuperview:aView];
matrix = [self _concatenateMatricesInReverseOrderFromPath:path];
[matrix inverse];
new = [matrix pointInMatrixSpace:aPoint];
}
else if ([aView isDescendantOf:self]) {
NSArray* path = [self _pathBetweenSubview:aView toSuperview:self];
matrix = [self _concatenateMatricesInReverseOrderFromPath:path];
new = [matrix pointInMatrixSpace:aPoint];
}
else {
/* The views are not on the same hierarchy of views. Convert the point to
window from the other's view coordinates and then to our view
coordinates. */
new = [aView convertPoint:aPoint toView:nil];
new = [self convertPoint:new fromView:nil];
}
return new;
}
- (NSPoint)convertPoint:(NSPoint)aPoint
toView:(NSView *)aView
{
NSPoint p, q;
NSRect r;
if (!aView)
aView = [[self window] contentView];
// Must belong to the same window
if (([self window] != [aView window]) && (aView))
return NSZeroPoint;
// if aView is nil
// then converting to window
if (aView == nil)
return [self convertPointToWindow: aPoint];
// convert everything to window coordinates
p = [self convertPointToWindow: aPoint];
r = [aView bounds];
q = [aView convertPointToWindow: r.origin];
NSDebugLog(@"point convert: %f %f %f %f\n", p.x, p.y, q.x, q.y);
// now translate
p.x -= q.x;
p.y -= q.y;
return p;
return [aView convertPoint:aPoint fromView:self];
}
- (NSRect)convertRect:(NSRect)aRect
@ -597,7 +592,7 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
NSRect r;
// Must belong to the same window
if (([self window] != [aView window]) && (aView))
if (aView && [self window] != [aView window])
return NSZeroRect;
r = aRect;
@ -612,7 +607,7 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
NSRect r;
// Must belong to the same window
if (([self window] != [aView window]) && (aView))
if (aView && [self window] != [aView window])
return NSZeroRect;
r = aRect;
@ -621,18 +616,59 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
return r;
}
- (PSMatrix*)_concatenateBoundsMatricesInReverseOrderFromPath:(NSArray*)viewsPath
{
int i, count = [viewsPath count];
PSMatrix* matrix = [[PSMatrix new] autorelease];
for (i = count - 1; i >= 0; i--) {
NSView* view = [viewsPath objectAtIndex:i];
[matrix concatenateWith:view->boundsMatrix];
}
return matrix;
}
- (NSSize)convertSize:(NSSize)aSize
fromView:(NSView *)aView
{
// Size would only change under scaling
return aSize;
NSSize new;
PSMatrix* matrix;
if (!aView)
aView = [[self window] contentView];
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];
}
else {
/* The views are not on the same hierarchy of views. Convert the point to
window from the other's view coordinates and then to our view
coordinates. */
new = [aView convertSize:aSize toView:nil];
new = [self convertSize:new fromView:nil];
}
return new;
}
- (NSSize)convertSize:(NSSize)aSize
toView:(NSView *)aView
{
// Size would only change under scaling
return aSize;
if (!aView)
aView = [[self window] contentView];
return [aView convertSize:aSize fromView:self];
}
//
@ -764,6 +800,10 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
{
int i, j;
if (!boundsMatrix || !frameMatrix)
NSLog (@"warning: %@ %p has not setup the PS matrices",
NSStringFromClass(isa), self);
[self lockFocus];
[self drawRect:bounds];
[self unlockFocus];
@ -798,8 +838,7 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
{}
- (void)drawRect:(NSRect)rect
{
}
{}
- (NSRect)visibleRect
{
@ -949,18 +988,18 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil;
- (NSView *)hitTest:(NSPoint)aPoint
{
NSPoint p;
int i, j;
int i, count;
NSView *v = nil, *w;
// If not within our bounds then immediately return
if (![self mouse:aPoint inRect:bounds]) return nil;
p = [self convertPoint:aPoint fromView:super_view];
if (![self mouse:p inRect:bounds]) return nil;
// Check our sub_views
j = [sub_views count];
for (i = 0;i < j; ++i)
count = [sub_views count];
for (i = 0; i < count; ++i)
{
w = [sub_views objectAtIndex:i];
p = [self convertPoint:aPoint toView:w];
v = [w hitTest:p];
if (v) break;
}

View file

@ -27,6 +27,7 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSNotification.h>
@ -1012,8 +1013,10 @@
int i, j;
BOOL last, now;
NSEvent *e;
NSRect convRect;
NSPoint loc = [theEvent locationInWindow];
NSPoint lastPointConverted;
NSPoint locationConverted;
NSRect rect;
// Loop through cursor rectangles
j = [tr count];
@ -1021,12 +1024,14 @@
{
// Convert cursor rectangle to window coordinates
r = (TrackingRectangle *)[tr objectAtIndex:i];
convRect = [r rectangle];
convRect = [theView convertRect: convRect toView: nil];
lastPointConverted = [theView convertPoint:last_point fromView:nil];
locationConverted = [theView convertPoint:loc fromView:nil];
// Check mouse at last point
last = [theView mouse:last_point inRect: convRect];
// Check mouse at current point
now = [theView mouse: loc inRect: convRect];
rect = [r rectangle];
last = [theView mouse:lastPointConverted inRect:rect];
now = [theView mouse:locationConverted inRect:rect];
// Mouse entered
if ((!last) && (now))

198
Source/PSMatrix.m Normal file
View file

@ -0,0 +1,198 @@
/*
PSMatrix.m
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Ovidiu Predescu <ovidiu@net-community.com>
Date: August 1997
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <math.h>
#include <AppKit/config.h>
#include <AppKit/PSMatrix.h>
/* A Postscript matrix look like this:
/ a b 0 \
| c d 0 |
\ tx ty 1 /
*/
static const float pi = 3.1415926535897932384626433;
@implementation PSMatrix
+ matrixFrom:(float[6])_matrix
{
PSMatrix* m = [[self alloc] autorelease];
memcpy (m->matrix, _matrix, sizeof (m->matrix));
return m;
}
- init
{
[self makeIdentityMatrix];
rotationAngle = 0;
return self;
}
- (id)copyWithZone:(NSZone*)zone
{
PSMatrix* new = [isa alloc];
memcpy (new->matrix, matrix, sizeof(matrix));
new->rotationAngle = rotationAngle;
return new;
}
- (void)scaleBy:(float)sx :(float)sy
{
A *= sx; B *= sx;
C *= sy; D *= sy;
}
- (void)translateToPoint:(NSPoint)point
{
float newTX, newTY;
newTX = point.x * A + point.y * C + TX;
newTY = point.x * B + point.y * D + TY;
TX = newTX;
TY = newTY;
}
- (void)rotateByAngle:(float)angle
{
float newA, newB, newC, newD;
float angleRad = pi * angle / 180;
float sine = sin (angleRad);
float cosine = cos (angleRad);
newA = A * cosine + C * sine; newB = B * cosine + D * sine;
newC = -A * sine + C * cosine; newD = -B * sine + D * cosine;
A = newA; B = newB;
C = newC; D = newD;
rotationAngle += angle;
}
- (void)makeIdentityMatrix
{
A = 1; B = 0;
C = 0; D = 1;
TX = 0; TY = 0;
rotationAngle = 0;
}
- (void)setFrameOrigin:(NSPoint)point
{
float dx = point.x - TX;
float dy = point.y - TY;
[self translateToPoint:NSMakePoint (dx, dy)];
}
- (void)setFrameRotation:(float)angle
{
float newAngle = angle - rotationAngle;
[self rotateByAngle:newAngle];
}
- (float)rotationAngle
{
return rotationAngle;
}
- (void)concatenateWith:(PSMatrix*)other
{
float newA, newB, newC, newD, newTX, newTY;
newA = other->A * A + other->B * C;
newB = other->A * B + other->B * D;
newC = other->C * A + other->D * C;
newD = other->C * B + other->D * D;
newTX = other->TX * A + other->TY * C + TX;
newTY = other->TX * B + other->TY * D + TY;
A = newA; B = newB;
C = newC; D = newD;
TX = newTX; TY = newTY;
rotationAngle += other->rotationAngle;
}
- (void)inverse
{
float newA, newB, newC, newD, newTX, newTY;
float det;
det = A * D - B * C;
if (!det) {
NSLog (@"error: determinant of matrix is 0!");
return;
}
newA = D / det;
newB = -B / det;
newC = -C / det;
newD = A / det;
newTX = (-D * TX + C * TY) / det;
newTY = (B * TX - A * TY) / det;
NSDebugLog (@"inverse of matrix ((%f, %f) (%f, %f) (%f, %f))\n"
@"is ((%f, %f) (%f, %f) (%f, %f))",
A, B, C, D, TX, TY,
newA, newB, newC, newD, newTX, newTY);
A = newA; B = newB;
C = newC; D = newD;
TX = newTX; TY = newTY;
}
- (NSPoint)pointInMatrixSpace:(NSPoint)point
{
NSPoint new;
new.x = A * point.x + C * point.y + TX;
new.y = B * point.x + D * point.y + TY;
return new;
}
- (NSSize)sizeInMatrixSpace:(NSSize)size
{
NSSize new;
new.width = A * size.width + C * size.height + TX;
new.height = B * size.width + D * size.height + TY;
return new;
}
- (NSString*)description
{
return [NSString stringWithFormat:@"PSMatrix ((%f, %f) (%f, %f) (%f, %f))",
A, B, C, D, TX, TY];
}
@end /* PSMatrix */

View file

@ -26,6 +26,8 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSString.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSFontManager.h>
#include <AppKit/NSFont.h>