mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-01 00:50:49 +00:00
Optimisation of handling of mouse movement.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4221 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
01d09ad926
commit
2a22d6ee9f
4 changed files with 191 additions and 111 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Fri May 7 12:16:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Headers/AppKit/GSTrackingRect.h: Add a couple of ivars and make
|
||||||
|
them public.
|
||||||
|
* Source/GSTrackingRect.m: Set ivars to say what methods the owner
|
||||||
|
responds to.
|
||||||
|
* Source/NSWindow.m: Rewrite of ([-_checkTrackingRectangles:forEvent])
|
||||||
|
and ([-_checkCursorRectangles:forEvent:])
|
||||||
|
|
||||||
1999-05-05 Adam Fedor <fedor@gnu.org>
|
1999-05-05 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
* Headers/gnustep/gui/NSGraphicsContext.h: New lock focus methods
|
* Headers/gnustep/gui/NSGraphicsContext.h: New lock focus methods
|
||||||
|
|
|
@ -33,13 +33,15 @@
|
||||||
|
|
||||||
@interface GSTrackingRect : NSObject <NSCoding>
|
@interface GSTrackingRect : NSObject <NSCoding>
|
||||||
{
|
{
|
||||||
// Attributes
|
@public
|
||||||
NSRect rectangle;
|
NSRect rectangle;
|
||||||
NSTrackingRectTag tag;
|
NSTrackingRectTag tag;
|
||||||
id owner;
|
id owner;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
BOOL inside;
|
BOOL inside;
|
||||||
BOOL isValid;
|
BOOL isValid;
|
||||||
|
BOOL ownerRespondsToMouseEntered;
|
||||||
|
BOOL ownerRespondsToMouseExited;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance methods
|
// Instance methods
|
||||||
|
@ -51,7 +53,7 @@
|
||||||
|
|
||||||
- (NSRect) rectangle;
|
- (NSRect) rectangle;
|
||||||
- (NSTrackingRectTag) tag;
|
- (NSTrackingRectTag) tag;
|
||||||
- owner;
|
- (id) owner;
|
||||||
- (void*) userData;
|
- (void*) userData;
|
||||||
- (BOOL) inside;
|
- (BOOL) inside;
|
||||||
|
|
||||||
|
@ -61,8 +63,8 @@
|
||||||
//
|
//
|
||||||
// NSCoding protocol
|
// NSCoding protocol
|
||||||
//
|
//
|
||||||
- (void) encodeWithCoder: aCoder;
|
- (void) encodeWithCoder: (NSCoder*)aCoder;
|
||||||
- initWithCoder: aDecoder;
|
- (id) initWithCoder: (NSCoder*)aDecoder;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,13 @@
|
||||||
tag = aTag;
|
tag = aTag;
|
||||||
owner = anObject;
|
owner = anObject;
|
||||||
if (owner)
|
if (owner)
|
||||||
[owner retain];
|
{
|
||||||
|
[owner retain];
|
||||||
|
if ([owner respondsToSelector: @selector(mouseEntered:)])
|
||||||
|
ownerRespondsToMouseEntered = YES;
|
||||||
|
if ([owner respondsToSelector: @selector(mouseExited:)])
|
||||||
|
ownerRespondsToMouseExited = YES;
|
||||||
|
}
|
||||||
user_data = theData;
|
user_data = theData;
|
||||||
inside = flag;
|
inside = flag;
|
||||||
isValid = YES;
|
isValid = YES;
|
||||||
|
@ -111,6 +117,8 @@
|
||||||
{
|
{
|
||||||
[owner release];
|
[owner release];
|
||||||
owner = nil;
|
owner = nil;
|
||||||
|
ownerRespondsToMouseEntered = NO;
|
||||||
|
ownerRespondsToMouseExited = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
#include <Foundation/NSCoder.h>
|
#include <Foundation/NSCoder.h>
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSGeometry.h>
|
||||||
#include <Foundation/NSNotification.h>
|
#include <Foundation/NSNotification.h>
|
||||||
#include <Foundation/NSValue.h>
|
#include <Foundation/NSValue.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
|
@ -87,6 +88,14 @@
|
||||||
|
|
||||||
@implementation NSWindow
|
@implementation NSWindow
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class variables
|
||||||
|
*/
|
||||||
|
static SEL ccSel = @selector(_checkCusrorRectangles:forEvent:);
|
||||||
|
static SEL ctSel = @selector(_checkTrackingRectangles:forEvent:);
|
||||||
|
static IMP ccImp;
|
||||||
|
static IMP ctImp;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class methods
|
// Class methods
|
||||||
//
|
//
|
||||||
|
@ -96,6 +105,8 @@
|
||||||
{
|
{
|
||||||
NSDebugLog(@"Initialize NSWindow class\n");
|
NSDebugLog(@"Initialize NSWindow class\n");
|
||||||
[self setVersion: 2];
|
[self setVersion: 2];
|
||||||
|
ccImp = [self instanceMethodForSelector: ccSel];
|
||||||
|
ctImp = [self instanceMethodForSelector: ctSel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,130 +1069,180 @@
|
||||||
accepts_mouse_moved = flag;
|
accepts_mouse_moved = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) checkTrackingRectangles: (NSView *)theView
|
- (void) _checkTrackingRectangles: (NSView *)theView
|
||||||
forEvent: (NSEvent *)theEvent
|
forEvent: (NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
NSArray *tr = [theView trackingRectangles];
|
NSArray *tr = [theView trackingRectangles];
|
||||||
NSArray *sb = [theView subviews];
|
NSArray *sb = [theView subviews];
|
||||||
GSTrackingRect *r;
|
unsigned count;
|
||||||
unsigned i, j;
|
|
||||||
BOOL last, now;
|
|
||||||
NSEvent *e;
|
|
||||||
|
|
||||||
j = [tr count]; // Loop through the tracking
|
/*
|
||||||
for (i = 0; i < j; ++i) // rectangles
|
* Loop through the tracking rectangles
|
||||||
|
*/
|
||||||
|
count = [tr count];
|
||||||
|
if (count > 0)
|
||||||
{
|
{
|
||||||
r = (GSTrackingRect *)[tr objectAtIndex: i];
|
GSTrackingRect *rects[count];
|
||||||
// Check mouse at last point
|
NSPoint loc = [theEvent locationInWindow];
|
||||||
last = [theView mouse: last_point inRect: [r rectangle]];
|
BOOL flipped = [theView isFlipped];
|
||||||
// Check mouse at current point
|
unsigned i;
|
||||||
now = [theView mouse: [theEvent locationInWindow] inRect: [r rectangle]];
|
|
||||||
|
|
||||||
if ((!last) && (now)) // Mouse entered event
|
[tr getObjects: rects];
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
id owner = [r owner];
|
BOOL last;
|
||||||
|
BOOL now;
|
||||||
|
GSTrackingRect *r = rects[i];
|
||||||
|
|
||||||
if ([owner respondsToSelector: @selector(mouseEntered:)])
|
/* Check mouse at last point */
|
||||||
|
last = NSMouseInRect(last_point, r->rectangle, flipped);
|
||||||
|
/* Check mouse at current point */
|
||||||
|
now = NSMouseInRect(loc, r->rectangle, flipped);
|
||||||
|
|
||||||
|
if ((!last) && (now)) // Mouse entered event
|
||||||
{
|
{
|
||||||
e = [NSEvent enterExitEventWithType: NSMouseEntered
|
if (r->ownerRespondsToMouseEntered)
|
||||||
location: [theEvent locationInWindow]
|
{
|
||||||
modifierFlags: [theEvent modifierFlags]
|
NSEvent *e;
|
||||||
timestamp: 0
|
|
||||||
windowNumber: [theEvent windowNumber]
|
e = [NSEvent enterExitEventWithType: NSMouseEntered
|
||||||
context: NULL
|
location: loc
|
||||||
eventNumber: 0
|
modifierFlags: [theEvent modifierFlags]
|
||||||
trackingNumber: [r tag]
|
timestamp: 0
|
||||||
userData: [r userData]];
|
windowNumber: [theEvent windowNumber]
|
||||||
[owner mouseEntered: e];
|
context: NULL
|
||||||
|
eventNumber: 0
|
||||||
|
trackingNumber: r->tag
|
||||||
|
userData: r->user_data];
|
||||||
|
[r->owner mouseEntered: e];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((last) && (!now)) // Mouse exited event
|
if ((last) && (!now)) // Mouse exited event
|
||||||
{
|
|
||||||
id owner = [r owner];
|
|
||||||
|
|
||||||
if ([owner respondsToSelector: @selector(mouseExited:)])
|
|
||||||
{
|
{
|
||||||
e = [NSEvent enterExitEventWithType: NSMouseExited
|
if (r->ownerRespondsToMouseExited)
|
||||||
location: [theEvent locationInWindow]
|
{
|
||||||
modifierFlags: [theEvent modifierFlags]
|
NSEvent *e;
|
||||||
timestamp: 0
|
|
||||||
windowNumber: [theEvent windowNumber]
|
e = [NSEvent enterExitEventWithType: NSMouseExited
|
||||||
context: NULL
|
location: loc
|
||||||
eventNumber: 0
|
modifierFlags: [theEvent modifierFlags]
|
||||||
trackingNumber: [r tag]
|
timestamp: 0
|
||||||
userData: [r userData]];
|
windowNumber: [theEvent windowNumber]
|
||||||
[owner mouseExited: e];
|
context: NULL
|
||||||
|
eventNumber: 0
|
||||||
|
trackingNumber: r->tag
|
||||||
|
userData: r->user_data];
|
||||||
|
[r->owner mouseExited: e];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
j = [sb count]; // Check tracking rectangles
|
/*
|
||||||
for (i = 0; i < j; ++i) // for the subviews
|
* Check tracking rectangles for the subviews
|
||||||
[self checkTrackingRectangles: [sb objectAtIndex: i] forEvent: theEvent];
|
*/
|
||||||
|
count = [sb count];
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
NSView *subs[count];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
[sb getObjects: subs];
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
(*ctImp)(self, ctSel, subs[i], theEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) checkCursorRectangles: (NSView *)theView forEvent: (NSEvent *)theEvent
|
- (void) _checkCursorRectangles: (NSView *)theView forEvent: (NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
NSArray *tr = [theView cursorRectangles];
|
NSArray *tr = [theView cursorRectangles];
|
||||||
NSArray *sb = [theView subviews];
|
NSArray *sb = [theView subviews];
|
||||||
GSTrackingRect *r;
|
unsigned count;
|
||||||
unsigned i, j;
|
|
||||||
BOOL last, now;
|
|
||||||
NSEvent *e;
|
|
||||||
NSPoint loc = [theEvent locationInWindow];
|
|
||||||
NSPoint lastPointConverted;
|
|
||||||
NSPoint locationConverted;
|
|
||||||
NSRect rect;
|
|
||||||
|
|
||||||
// Loop through cursor rectangles
|
// Loop through cursor rectangles
|
||||||
j = [tr count];
|
count = [tr count];
|
||||||
for (i = 0; i < j; ++i)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
r = (GSTrackingRect *)[tr objectAtIndex: i];
|
GSTrackingRect *rects[count];
|
||||||
|
NSPoint loc = [theEvent locationInWindow];
|
||||||
|
NSPoint lastConv;
|
||||||
|
NSPoint locConv;
|
||||||
|
BOOL flipped = [theView isFlipped];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
if ([r isValid] == NO)
|
/*
|
||||||
continue;
|
* Convert points from window to view coordinates.
|
||||||
lastPointConverted = [theView convertPoint: last_point fromView: nil];
|
*/
|
||||||
locationConverted = [theView convertPoint: loc fromView: nil];
|
lastConv = [theView convertPoint: last_point fromView: nil];
|
||||||
|
locConv = [theView convertPoint: loc fromView: nil];
|
||||||
|
|
||||||
rect = [r rectangle]; // Check mouse's last point
|
[tr getObjects: rects];
|
||||||
last = [theView mouse: lastPointConverted inRect: rect];
|
|
||||||
now = [theView mouse: locationConverted inRect: rect];
|
for (i = 0; i < count; ++i)
|
||||||
// Mouse entered
|
|
||||||
if ((!last) && (now))
|
|
||||||
{
|
{
|
||||||
e = [NSEvent enterExitEventWithType: NSCursorUpdate
|
GSTrackingRect *r = rects[i];
|
||||||
location: loc
|
BOOL last;
|
||||||
modifierFlags: [theEvent modifierFlags]
|
BOOL now;
|
||||||
timestamp: 0
|
|
||||||
windowNumber: [theEvent windowNumber]
|
if ([r isValid] == NO)
|
||||||
context: [theEvent context]
|
continue;
|
||||||
eventNumber: 0
|
|
||||||
trackingNumber: (int)YES
|
/*
|
||||||
userData: (void *)r];
|
* Check for presence of point in rectangle.
|
||||||
[self postEvent: e atStart: YES];
|
*/
|
||||||
}
|
last = NSMouseInRect(lastConv, r->rectangle, flipped);
|
||||||
// Mouse exited
|
now = NSMouseInRect(locConv, r->rectangle, flipped);
|
||||||
if ((last) && (!now))
|
|
||||||
{
|
// Mouse entered
|
||||||
e = [NSEvent enterExitEventWithType: NSCursorUpdate
|
if ((!last) && (now))
|
||||||
location: loc
|
{
|
||||||
modifierFlags: [theEvent modifierFlags]
|
NSEvent *e;
|
||||||
timestamp: 0
|
|
||||||
windowNumber: [theEvent windowNumber]
|
e = [NSEvent enterExitEventWithType: NSCursorUpdate
|
||||||
context: [theEvent context]
|
location: loc
|
||||||
eventNumber: 0
|
modifierFlags: [theEvent modifierFlags]
|
||||||
trackingNumber: (int)NO
|
timestamp: 0
|
||||||
userData: (void *)r];
|
windowNumber: [theEvent windowNumber]
|
||||||
[self postEvent: e atStart: YES];
|
context: [theEvent context]
|
||||||
|
eventNumber: 0
|
||||||
|
trackingNumber: (int)YES
|
||||||
|
userData: (void *)r];
|
||||||
|
[self postEvent: e atStart: YES];
|
||||||
|
}
|
||||||
|
// Mouse exited
|
||||||
|
if ((last) && (!now))
|
||||||
|
{
|
||||||
|
NSEvent *e;
|
||||||
|
|
||||||
|
e = [NSEvent enterExitEventWithType: NSCursorUpdate
|
||||||
|
location: loc
|
||||||
|
modifierFlags: [theEvent modifierFlags]
|
||||||
|
timestamp: 0
|
||||||
|
windowNumber: [theEvent windowNumber]
|
||||||
|
context: [theEvent context]
|
||||||
|
eventNumber: 0
|
||||||
|
trackingNumber: (int)NO
|
||||||
|
userData: (void *)r];
|
||||||
|
[self postEvent: e atStart: YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check cursor rectangles for the subviews
|
/*
|
||||||
j = [sb count];
|
* Check cursor rectangles for the subviews
|
||||||
for (i = 0; i < j; ++i)
|
*/
|
||||||
[self checkCursorRectangles: [sb objectAtIndex: i] forEvent: theEvent];
|
count = [sb count];
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
NSView *subs[count];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
[sb getObjects: subs];
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
(*ccImp)(self, ccSel, subs[i], theEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendEvent: (NSEvent *)theEvent
|
- (void) sendEvent: (NSEvent *)theEvent
|
||||||
|
@ -1256,14 +1317,14 @@
|
||||||
// We need to go through all of the views, and if there is any with
|
// We need to go through all of the views, and if there is any with
|
||||||
// a tracking rectangle then we need to determine if we should send
|
// a tracking rectangle then we need to determine if we should send
|
||||||
// a NSMouseEntered or NSMouseExited event.
|
// a NSMouseEntered or NSMouseExited event.
|
||||||
[self checkTrackingRectangles: content_view forEvent: theEvent];
|
(*ctImp)(self, ctSel, content_view, theEvent);
|
||||||
|
|
||||||
if (is_key)
|
if (is_key)
|
||||||
{
|
{
|
||||||
// We need to go through all of the views, and if there is any with
|
// We need to go through all of the views, and if there is any with
|
||||||
// a cursor rectangle then we need to determine if we should send a
|
// a cursor rectangle then we need to determine if we should send a
|
||||||
// cursor update event.
|
// cursor update event.
|
||||||
[self checkCursorRectangles: content_view forEvent: theEvent];
|
(*ccImp)(self, ccSel, content_view, theEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_point = [theEvent locationInWindow];
|
last_point = [theEvent locationInWindow];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue