Initial implementation of NSCursor.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2180 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Scott Christley 1997-02-12 22:21:43 +00:00
parent 4fc633ec79
commit 0aa42f2776
12 changed files with 410 additions and 72 deletions

View file

@ -45,9 +45,11 @@ bindir = @bindir@
MAKEDEFINES =
CC = @CC@ -g
CC = @CC@
CPPFLAGS = @CPPFLAGS@
CFLAGS = -c $(GCCFLAGS) -I../Headers $(CPPFLAGS)
CFLAGS = -g -O -Wall $(GCCFLAGS)
ALL_CPPFLAGS = $(CPPFLAGS) -I../Headers
ALL_CFLAGS = $(ALL_CPPFLAGS) $(CFLAGS)
DEFS = -DGNUSTEP_INSTALL_LIBDIR=$(gnustep_libdir) @DEFS@
GCC_LIB =
@ -240,9 +242,9 @@ OBJS = $(OBJS_WITHOUT_INIT)
.SUFFIXES: .m
.m$(oext):
$(CC) $(CFLAGS) $(DEFS) $<
$(CC) -c $(ALL_CFLAGS) $(DEFS) $<
.c$(oext):
$(CC) $(CFLAGS) $(DEFS) $<
$(CC) -c $(ALL_CFLAGS) $(DEFS) $<
#
# libraries
@ -274,7 +276,7 @@ $(MAIN_FILE)$(libext): $(OBJS)
$(INIT_FILE_OBJ): $(OBJS_WITHOUT_INIT)
nm $(OBJS_WITHOUT_INIT) | grep " __GLOBAL_" > tmpinit.c
collect tmpinit.c $(INIT_FILE)
$(CC) $(CFLAGS) $(INIT_FILE).c
$(CC) $(ALL_CFLAGS) $(INIT_FILE).c
rm tmpinit.c
install: installdirs install-lib install-headers
@ -319,6 +321,9 @@ uninstall:
rm -rf $(includedir)/DPSClient
rm -rf $(libdir)/$(MAIN_FILE)$(libext)
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; $(SHELL) config.status
#
# Cleaning
#

View file

@ -263,7 +263,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
e = [self nextEventMatchingMask:NSAnyEventMask untilDate:nil
inMode:nil dequeue:YES];
if (e)
[self postEvent:e atStart:YES];
[self sendEvent: e];
else
{
// Null event
@ -440,7 +440,7 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
if (![event_queue isEmpty])
{
j = [event_queue count];
for (i = j-1;i > 0; --i)
for (i = j-1;i >= 0; --i)
{
e = [event_queue objectAtIndex: i];
if ([self event: e matchMask: mask])
@ -469,13 +469,32 @@ NSString *NSApplicationWillUpdateNotification = @"ApplicationWillUpdate";
}
}
// Unhide the cursor if necessary
{
NSEventType type;
// Only if we should unhide when mouse moves
if ([NSCursor isHiddenUntilMouseMoves])
{
// Make sure the event is a mouse event before unhiding
type = [e type];
if ((type == NSLeftMouseDown) || (type == NSLeftMouseUp)
|| (type == NSRightMouseDown) || (type == NSRightMouseUp)
|| (type == NSMouseMoved))
[NSCursor unhide];
}
}
[self setCurrentEvent: e];
return e;
}
- (void)postEvent:(NSEvent *)event atStart:(BOOL)flag
{
[self sendEvent:event];
if (flag)
[event_queue appendObject: event];
else
[event_queue enqueueObject: event];
}
//

View file

@ -1,7 +1,7 @@
/*
NSCursor.m
Description...
Holds an image to use as a cursor
Copyright (C) 1996 Free Software Foundation, Inc.
@ -27,6 +27,12 @@
*/
#include <gnustep/gui/NSCursor.h>
#include <gnustep/base/Stack.h>
// Class variables
static Stack *gnustep_gui_cursor_stack;
static NSCursor *gnustep_gui_current_cursor;
static BOOL gnustep_gui_hidden_until_move;
@implementation NSCursor
@ -39,6 +45,11 @@
{
// Initial version
[self setVersion:1];
// Initialize class variables
gnustep_gui_cursor_stack = [[Stack alloc] initWithCapacity: 2];
gnustep_gui_hidden_until_move = YES;
gnustep_gui_current_cursor = [NSCursor arrowCursor];
}
}
@ -46,16 +57,36 @@
// Setting the Cursor
//
+ (void)hide
{}
{
}
+ (void)pop
{}
{
// The object we pop is the current cursor
if (![gnustep_gui_cursor_stack isEmpty])
gnustep_gui_current_cursor = [gnustep_gui_cursor_stack popObject];
// If the stack isn't empty then get the new current cursor
// Otherwise the cursor will stay the same
if (![gnustep_gui_cursor_stack isEmpty])
gnustep_gui_current_cursor = [gnustep_gui_cursor_stack topObject];
[self currentCursorHasChanged];
}
+ (void)setHiddenUntilMouseMoves:(BOOL)flag
{}
{
gnustep_gui_hidden_until_move = flag;
}
+ (BOOL)isHiddenUntilMouseMoves
{
return gnustep_gui_hidden_until_move;
}
+ (void)unhide
{}
{
}
//
// Getting the Cursor
@ -67,7 +98,7 @@
+ (NSCursor *)currentCursor
{
return nil;
return gnustep_gui_current_cursor;
}
+ (NSCursor *)IBeamCursor
@ -82,9 +113,20 @@
//
// Initializing a New NSCursor Object
//
- init
{
return [self initWithImage: nil];
}
- (id)initWithImage:(NSImage *)newImage
{
return nil;
[super init];
cursor_image = newImage;
is_set_on_mouse_entered = NO;
is_set_on_mouse_exited = NO;
return self;
}
//
@ -92,53 +134,80 @@
//
- (NSPoint)hotSpot
{
return NSZeroPoint;
return hot_spot;
}
- (NSImage *)image
{
return nil;
return cursor_image;
}
- (void)setHotSpot:(NSPoint)spot
{}
{
hot_spot = spot;
}
- (void)setImage:(NSImage *)newImage
{}
{
cursor_image = newImage;
}
//
// Setting the Cursor
//
- (BOOL)isSetOnMouseEntered
{
return NO;
return is_set_on_mouse_entered;
}
- (BOOL)isSetOnMouseExited
{
return NO;
return is_set_on_mouse_exited;
}
// Hmm, how is this mouse entered/exited suppose to work?
// Is it simply what the doc says?
// If the cursor is set when the mouse enters
// then how does it get unset when the mouse exits?
- (void)mouseEntered:(NSEvent *)theEvent
{}
{
if (is_set_on_mouse_entered)
[self set];
}
- (void)mouseExited:(NSEvent *)theEvent
{}
{
if (is_set_on_mouse_exited)
[self set];
}
- (void)pop
{}
{
[NSCursor pop];
}
- (void)push
{}
{
[gnustep_gui_cursor_stack pushObject: self];
gnustep_gui_current_cursor = self;
[NSCursor currentCursorHasChanged];
}
- (void)set
{}
{
gnustep_gui_current_cursor = self;
[NSCursor currentCursorHasChanged];
}
- (void)setOnMouseEntered:(BOOL)flag
{}
{
is_set_on_mouse_entered = flag;
}
- (void)setOnMouseExited:(BOOL)flag
{}
{
is_set_on_mouse_exited = flag;
}
//
// NSCoding protocol
@ -156,3 +225,13 @@
}
@end
//
// Methods implemented by the backend
//
@implementation NSCursor (GNUstepBackend)
+ (void)currentCursorHasChanged
{}
@end

View file

@ -163,7 +163,8 @@
e = [[[NSEvent alloc] init] autorelease];
// Make sure it is one of the right event types
if ((type != NSMouseEntered) && (type != NSMouseExited))
if ((type != NSMouseEntered) && (type != NSMouseExited)
&& (type != NSCursorUpdate))
return nil;
// Set the event fields
@ -264,8 +265,7 @@
e = [[[NSEvent alloc] init] autorelease];
// Make sure it is one of the right event types
if ((type != NSFlagsChanged) && (type != NSCursorUpdate) &&
(type != NSPeriodic))
if ((type != NSFlagsChanged) && (type != NSPeriodic))
return nil;
// Set the event fields
@ -428,7 +428,8 @@
//
- (int)trackingNumber
{
if ((event_type != NSMouseEntered) && (event_type != NSMouseExited))
if ((event_type != NSMouseEntered) && (event_type != NSMouseExited)
&& (event_type != NSCursorUpdate))
return 0;
return event_data.tracking.tracking_num;
@ -436,7 +437,8 @@
- (void *)userData
{
if ((event_type != NSMouseEntered) && (event_type != NSMouseExited))
if ((event_type != NSMouseEntered) && (event_type != NSMouseExited)
&& (event_type != NSCursorUpdate))
return NULL;
return event_data.tracking.user_data;
@ -448,8 +450,7 @@
- (int)data1
{
// Make sure it is one of the right event types
if ((event_type != NSFlagsChanged) && (event_type != NSCursorUpdate) &&
(event_type != NSPeriodic))
if ((event_type != NSFlagsChanged) && (event_type != NSPeriodic))
return 0;
return event_data.misc.data1;
@ -458,8 +459,7 @@
- (int)data2
{
// Make sure it is one of the right event types
if ((event_type != NSFlagsChanged) && (event_type != NSCursorUpdate) &&
(event_type != NSPeriodic))
if ((event_type != NSFlagsChanged) && (event_type != NSPeriodic))
return 0;
return event_data.misc.data2;
@ -468,8 +468,7 @@
- (short)subtype
{
// Make sure it is one of the right event types
if ((event_type != NSFlagsChanged) && (event_type != NSCursorUpdate) &&
(event_type != NSPeriodic))
if ((event_type != NSFlagsChanged) && (event_type != NSPeriodic))
return 0;
return event_data.misc.sub_type;;
@ -507,6 +506,7 @@
case NSMouseEntered:
case NSMouseExited:
case NSCursorUpdate:
// Can't do anything with the user_data!?
[aCoder encodeValuesOfObjCTypes: "ii", &event_data.tracking.event_num,
&event_data.tracking.tracking_num];
@ -522,7 +522,6 @@
case NSFlagsChanged:
case NSPeriodic:
case NSCursorUpdate:
[aCoder encodeValuesOfObjCTypes: "sii", &event_data.misc.sub_type,
&event_data.misc.data1, &event_data.misc.data2];
break;
@ -555,6 +554,7 @@
case NSMouseEntered:
case NSMouseExited:
case NSCursorUpdate:
// Can't do anything with the user_data!?
[aDecoder decodeValuesOfObjCTypes: "ii", &event_data.tracking.event_num,
&event_data.tracking.tracking_num];
@ -571,7 +571,6 @@
case NSFlagsChanged:
case NSPeriodic:
case NSCursorUpdate:
[aDecoder decodeValuesOfObjCTypes: "sii", &event_data.misc.sub_type,
&event_data.misc.data1, &event_data.misc.data2];
break;

View file

@ -82,6 +82,7 @@ id MB_NSTEXTFIELDCELL_CLASS;
[[self cell] release];
[self setCell:[[MB_NSTEXTFIELDCELL_CLASS alloc] init]];
[cell setState:1];
text_cursor = [NSCursor IBeamCursor];
return self;
}
@ -395,6 +396,14 @@ id MB_NSTEXTFIELDCELL_CLASS;
return YES;
}
//
// Manage the cursor
//
- (void)resetCursorRects
{
[self addCursorRect: bounds cursor: text_cursor];
}
//
// NSCoding protocol
//

View file

@ -153,6 +153,9 @@ NSString *NSViewFocusChangedNotification;
// Initialize tracking rectangle list
tracking_rects = [NSMutableArray array];
// Initialize cursor rect list
cursor_rects = [NSMutableArray array];
super_view = nil;
window = nil;
is_flipped = NO;
@ -185,6 +188,11 @@ NSString *NSViewFocusChangedNotification;
for (i = 0;i < j; ++i)
[[tracking_rects objectAtIndex:i] release];
// Free the cursor rectangles
j = [cursor_rects count];
for (i = 0;i < j; ++i)
[[cursor_rects objectAtIndex:i] release];
[super dealloc];
}
@ -847,20 +855,55 @@ NSString *NSViewFocusChangedNotification;
//
// Managing the Cursor
//
// We utilize the tracking rectangle class
// to also maintain the cursor rects
//
- (void)addCursorRect:(NSRect)aRect
cursor:(NSCursor *)anObject
{}
{
TrackingRectangle *m;
m = [[TrackingRectangle alloc] initWithRect: aRect tag: 0 owner: anObject
userData: NULL inside: YES];
[cursor_rects addObject:m];
}
- (void)discardCursorRects
{}
{
[cursor_rects removeAllObjects];
}
- (void)removeCursorRect:(NSRect)aRect
cursor:(NSCursor *)anObject
{}
{
id e = [cursor_rects objectEnumerator];
TrackingRectangle *o;
NSCursor *c;
BOOL found = NO;
// Base remove test upon cursor object
o = [e nextObject];
while (o && (!found))
{
c = [o owner];
if (c == anObject)
found = YES;
else
o = [e nextObject];
}
if (found)
[cursor_rects removeObject: o];
}
- (void)resetCursorRects
{}
- (NSArray *)cursorRectangles
{
return cursor_rects;
}
//
// Assigning a Tag
//

View file

@ -177,6 +177,10 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
// Next responder is the application
[self setNextResponder:theApp];
// Cursor management
cursor_rects_enabled = YES;
cursor_rects_valid = NO;
// Create our content view
[self setContentView:[[NSView alloc] initWithFrame:frame]];
@ -349,6 +353,9 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
// We are the key window
is_key = YES;
// Reset the cursor rects
[self resetCursorRects];
// Post notification
[nc postNotificationName: NSWindowDidBecomeKeyNotification object: self];
}
@ -471,6 +478,9 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
is_key = NO;
// Discard the cursor rects
[self discardCursorRects];
// Post notification
[nc postNotificationName: NSWindowDidResignKeyNotification object: self];
}
@ -716,8 +726,26 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
cursor_rects_enabled = NO;
}
- (void)discardCursorRectsForView:(NSView *)theView
{
NSArray *s;
id e;
NSView *v;
// Discard for the view
[theView discardCursorRects];
// Discard for the view's subviews
s = [theView subviews];
e = [s objectEnumerator];
while ((v = [e nextObject]))
[self discardCursorRectsForView: v];
}
- (void)discardCursorRects
{}
{
[self discardCursorRectsForView: content_view];
}
- (void)enableCursorRects
{
@ -725,10 +753,34 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
}
- (void)invalidateCursorRectsForView:(NSView *)aView
{}
{
cursor_rects_valid = NO;
}
- (void)resetCursorRectsForView:(NSView *)theView
{
NSArray *s;
id e;
NSView *v;
// Reset the view
[theView resetCursorRects];
// Reset the view's subviews
s = [theView subviews];
e = [s objectEnumerator];
while ((v = [e nextObject]))
[self resetCursorRectsForView: v];
}
- (void)resetCursorRects
{}
{
// Tell all the views to reset their cursor rects
[self resetCursorRectsForView: content_view];
// Cursor rects are now valid
cursor_rects_valid = YES;
}
//
// Handling user actions and events
@ -928,27 +980,31 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
// Mouse entered event
if ((!last) && (now))
{
id owner = [r owner];
e = [NSEvent enterExitEventWithType:NSMouseEntered
location:[theEvent locationInWindow]
modifierFlags:[theEvent modifierFlags]
timestamp:0 windowNumber:[theEvent windowNumber]
context:NULL eventNumber:0
trackingNumber:[r tag] userData:[r userData]];
// Send the event to the view
[theView mouseEntered:e];
// Send the event to the owner
if ([owner respondsToSelector:@selector(mouseEntered:)])
[owner mouseEntered:e];
}
// Mouse exited event
if ((last) && (!now))
{
id owner = [r owner];
e = [NSEvent enterExitEventWithType:NSMouseExited
location:[theEvent locationInWindow]
modifierFlags:[theEvent modifierFlags]
timestamp:0 windowNumber:[theEvent windowNumber]
context:NULL eventNumber:0
trackingNumber:[r tag] userData:[r userData]];
// Send the event to the view
[theView mouseExited:e];
// Send the event to the owner
if ([owner respondsToSelector:@selector(mouseExited:)])
[owner mouseExited:e];
}
}
@ -958,12 +1014,81 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
[self checkTrackingRectangles:[sb objectAtIndex:i] forEvent:theEvent];
}
- (void)checkCursorRectangles:(NSView *)theView forEvent:(NSEvent *)theEvent
{
NSArray *tr = [theView cursorRectangles];
NSArray *sb = [theView subviews];
TrackingRectangle *r;
int i, j;
BOOL last, now;
NSEvent *e;
NSRect convRect;
NSPoint loc = [theEvent locationInWindow];
// Loop through cursor rectangles
j = [tr count];
for (i = 0;i < j; ++i)
{
// Convert cursor rectangle to window coordinates
r = (TrackingRectangle *)[tr objectAtIndex:i];
convRect = [r rectangle];
convRect = [theView convertRect: convRect toView: nil];
// Check mouse at last point
last = [theView mouse:last_point inRect: convRect];
// Check mouse at current point
now = [theView mouse: loc inRect: convRect];
// Mouse entered
if ((!last) && (now))
{
// Post cursor update event
e = [NSEvent enterExitEventWithType: NSCursorUpdate
location: loc
modifierFlags: [theEvent modifierFlags]
timestamp: 0
windowNumber: [theEvent windowNumber]
context: [theEvent context]
eventNumber: 0
trackingNumber: (int)YES
userData: (void *)r];
[self postEvent: e atStart: YES];
}
// Mouse exited event
if ((last) && (!now))
{
// Post cursor update event
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 the cursor rectangles for the subviews
j = [sb count];
for (i = 0;i < j; ++i)
[self checkCursorRectangles:[sb objectAtIndex:i] forEvent:theEvent];
}
- (void)sendEvent:(NSEvent *)theEvent
{
// If the cursor rects are invalid
// Then discard and reset
if (!cursor_rects_valid)
{
[self discardCursorRects];
[self resetCursorRects];
}
switch ([theEvent type])
{
//
// Mouse events
//
@ -1024,6 +1149,13 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
// should send a NSMouseEntered or NSMouseExited event
[self checkTrackingRectangles:content_view forEvent:theEvent];
// We need to go through all of the views, and any with
// a cursor rectangle then we need to determine if we
// should send a cursor update event
// We only do this if we are the key window
if ([self isKeyWindow])
[self checkCursorRectangles: content_view forEvent: theEvent];
last_point = [theEvent locationInWindow];
break;
}
@ -1095,6 +1227,20 @@ NSString *NSWindowWillMoveNotification = @"WindowWillMove";
//
case NSCursorUpdate:
{
// Is it a mouse entered
if ([theEvent trackingNumber])
{
// push the cursor
TrackingRectangle *r = (TrackingRectangle *)[theEvent userData];
NSCursor *c = (NSCursor *)[r owner];
[c push];
}
else
{
// it is a mouse exited
// so pop the cursor
[NSCursor pop];
}
break;
}
}