Skip to content

Instantly share code, notes, and snippets.

@smic
Created July 1, 2014 14:46
Show Gist options
  • Save smic/1ab001d6c62e9a6e6cbf to your computer and use it in GitHub Desktop.
Save smic/1ab001d6c62e9a6e6cbf to your computer and use it in GitHub Desktop.
Gesture recognition before NSGestureRecognizer
- (void)mouseDown:(NSEvent *)downEvent {
CGFloat doubleClickTime = [NSEvent doubleClickInterval] ;
NSEventMask eventMask = NSLeftMouseDraggedMask | NSLeftMouseUpMask;
// Is this a singe, double or triple click? Or long click, or a drag?
NSEvent *nextEvent = [NSApp nextEventMatchingMask:eventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:doubleClickTime] inMode:NSEventTrackingRunLoopMode dequeue:YES];
if (nextEvent) {
// could be an up or a drag
if (nextEvent.type == NSLeftMouseUp) {
// got at least a single click, make sure it's not performing a double click
if ( (nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:doubleClickTime] inMode:NSEventTrackingRunLoopMode dequeue:YES]) ) {
// start of a double (or triple) click
if ( (nextEvent = [NSApp nextEventMatchingMask:eventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:doubleClickTime] inMode:NSEventTrackingRunLoopMode dequeue:YES]) ) {
if (nextEvent.type == NSLeftMouseUp) {
// got at least a double click, make sure user is not performing a triple click
if ( (nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:doubleClickTime] inMode:NSEventTrackingRunLoopMode dequeue:YES]) ) {
// start of a triple click?
if ( (nextEvent = [NSApp nextEventMatchingMask:eventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:doubleClickTime] inMode:NSEventTrackingRunLoopMode dequeue:YES]) ) {
if (nextEvent.type == NSLeftMouseUp) {
// triple click! This is as far as we care about
[self handleTripleClick];
} else {
// double click and drag. That means nothing to us. Eat all events until we get a mouse up
nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseUp untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
[NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
}
} else {
// double click and a half. That means nothing to us. Eat all events until we get a mouse up
nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseUp untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
[NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
}
} else {
// double click!
[self handleDoubleClick];
}
} else {
// tap and a drag, That means nothing to us. Eat all events until we get a mouse up
nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseUp untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
[NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
}
} else {
// tap and a half. That means nothing to us. Eat all events until we get a mouse up
nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseUp untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
[NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
}
} else {
// This is a single click. This view doesn't care about single clicks, but perhaps the superview cares.
[NSApp postEvent:nextEvent atStart:YES];
[super mouseDown:downEvent];
}
} else {
[NSApp postEvent:nextEvent atStart:YES];
[self handleMouseDragWithEvent:downEvent];
}
} else {
// a long single click
[self handleLongClick];
// eat all events until we get a mouse up
nextEvent = [NSApp nextEventMatchingMask:NSLeftMouseUp untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
[NSApp discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment