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...
 }
}
相關文章
相關標籤/搜索