Cocoa处理mouse事件

Apple的《Handling Mouse Events》文档中有几个列子记录一下html

 

Listing 4-2  Simple handling of mouse click—sending an action messageapp

- (void)mouseDown:(NSEvent *)theEvent {
 [self setFrameColor:[NSColor redColor]];
 [self setNeedsDisplay:YES];
}
 
- (void)mouseUp:(NSEvent *)theEvent {
 [self setFrameColor:[NSColor greenColor]];
 [self setNeedsDisplay:YES];
 [NSApp sendAction:[self action] to:[self target] from:self];
}
 
- (SEL)action {return action; }
 
- (void)setAction:(SEL)newAction {
 action = newAction;
}
 
- (id)target { return target; }
 
- (void)setTarget:(id)newTarget {
 target = newTarget;
}

 

处理鼠标拖拽操做ide

Application Kit通常有两种方法处理鼠标拖动事件:oop

第一种方法重载NSResponder中mouseDown:mouseDragged:,  mouseUp:(用鼠标左键操做)。每一个拖拽动做下,首先Application Kit发送一个MouseDown消息给NSResponder对象,接着发送一个或者多个mouseDragged消息,最后发送一个mouseUp:消息。ui

第二种方法将鼠标拖动系列事件看成一个单一的事件处理,NSResponder一般必须建立事件循环机制获取鼠标事件, NSApplication和NSWindow 都有nextEventMatchingMask:untilDate:inMode:dequeue: 方法获取事件。spa

这两种方法都有本身的优势和缺点。在应用程序拖动操做期间接管鼠标跟踪循环处理事件。然而,应用程序的主线程没法处理其余事件和NSTimer也不会触发。鼠标跟踪方法更有效,由于它一般须要更少的代码,容许全部拖动变量是局部。然而,全部拖动代码在子类中继承更困难。线程

而重载mouseDown:mouseDragged:,  mouseUp:方法相比前一种方法,更逻辑更清晰,范围也明确,子类也容易继承处理鼠标拖动事件。code

 

下面是重载mouseDown:mouseDragged:,  mouseUp:htm

- (void)mouseDown:(NSEvent *)theEvent {
 // mouseInCloseBox and trackingCloseBoxHit are instance variables
 if (mouseInCloseBox = NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], closeBox)) {
 trackingCloseBoxHit = YES;
 [self setNeedsDisplayInRect:closeBox];
 }
 else if ([theEvent clickCount] > 1) {
 [[self window] miniaturize:self];
 return;
 }
}
 
- (void)mouseDragged:(NSEvent *)theEvent {
 NSPoint windowOrigin;
 NSWindow *window = [self window];
 
 if (trackingCloseBoxHit) {
 mouseInCloseBox = NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], closeBox);
 [self setNeedsDisplayInRect:closeBox];
 return;
 }
 
 windowOrigin = [window frame].origin;
 
 [window setFrameOrigin:NSMakePoint(windowOrigin.x + [theEvent deltaX], windowOrigin.y - [theEvent deltaY])];
}
 
- (void)mouseUp:(NSEvent *)theEvent {
 if (NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], closeBox)) {
 [self tryToCloseWindow];
 return;
 }
 trackingCloseBoxHit = NO;
 [self setNeedsDisplayInRect:closeBox];
}

 

下面跟踪鼠标循环方式,处理拖拽事件:(简单例子)对象

- (void)mouseDown:(NSEvent *)theEvent {
 BOOL keepOn = YES;
 BOOL isInside = YES;
 NSPoint mouseLoc;
 
 while (keepOn) {
 theEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask |
 NSLeftMouseDraggedMask];
 mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
 isInside = [self mouse:mouseLoc inRect:[self bounds]];
 
 switch ([theEvent type]) {
 case NSLeftMouseDragged:
 [self highlight:isInside];
 break;
 case NSLeftMouseUp:
 if (isInside) [self doSomethingSignificant];
 [self highlight:NO];
 keepOn = NO;
 break;
 default:
 /* Ignore any other kind of event. */
 break;
 }
 
 };
 
 return;
}

 

 

下面跟踪鼠标循环方式,处理拖拽事件:(复杂例子)

- (void)mouseDown:(NSEvent *)theEvent
{
 if ([theEvent modifierFlags] & NSAlternateKeyMask) {
 BOOL dragActive = YES;
 NSPoint location = [renderView convertPoint:[theEvent locationInWindow] fromView:nil];
 NSAutoreleasePool *myPool = nil;
 NSEvent* event = NULL;
 NSWindow *targetWindow = [renderView window];
 
 myPool = [[NSAutoreleasePool alloc] init];
 while (dragActive) {
 event = [targetWindow nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)
 untilDate:[NSDate distantFuture]
 inMode:NSEventTrackingRunLoopMode
 dequeue:YES];
 if(!event)
 continue;
 location = [renderView convertPoint:[event locationInWindow] fromView:nil];
 switch ([event type]) {
 case NSLeftMouseDragged:
 annotationPeel = (location.x * 2.0 / [renderView bounds].size.width);
 [imageLayer showLens:(annotationPeel <= 0.0)];
 [peelOffFilter setValue:[NSNumber numberWithFloat:annotationPeel] forKey:@"inputTime"];
 [self refresh];
 break;
 
 case NSLeftMouseUp:
 dragActive = NO;
 break;
 
 default:
 break;
 }
 }
 [myPool release];
 } else {
 // other tasks handled here......
 }
}

 

 

下面跟踪鼠标循环方式,处理拖拽事件:(经典例子)

- (void)mouseDown:(NSEvent *)theEvent {
 NSPoint pos;
 
 while ((theEvent = [[self window] nextEventMatchingMask:
 NSLeftMouseUpMask | NSLeftMouseDraggedMask])) {
 
 NSPoint pos = [self convertPoint:[theEvent locationInWindow]
 fromView:nil];
 
 if ([theEvent type] == NSLeftMouseUp)
 break;
 
 // Do some other processing...
 }
}
相关文章
相关标签/搜索