From 134e15691d8ed1e3cf33e336c484228306079962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20A=2E=20A=CC=81lvarez?= Date: Fri, 18 Nov 2016 22:12:56 +0100 Subject: [PATCH] support multi-touch mouse-down, resolves #2 --- Mini vMac/TrackPad.m | 75 ++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/Mini vMac/TrackPad.m b/Mini vMac/TrackPad.m index f5c373b..64104d3 100644 --- a/Mini vMac/TrackPad.m +++ b/Mini vMac/TrackPad.m @@ -19,7 +19,8 @@ NSTimeInterval previousClickTime, previousTouchTime; CGFloat touchDistanceThreshold; CGPoint previousTouchLoc; - BOOL click, drag; + BOOL shouldClick; + BOOL isDragging; NSMutableSet *currentTouches; } @@ -28,58 +29,84 @@ touchTimeThreshold = 0.25; touchDistanceThreshold = 16; currentTouches = [NSMutableSet setWithCapacity:4]; + self.multipleTouchEnabled = YES; } return self; } -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - click = YES; - CGPoint touchLoc = [touches.anyObject locationInView:self]; - if ((event.timestamp - previousTouchTime < touchTimeThreshold) && - fabs(previousTouchLoc.x - touchLoc.x) < touchDistanceThreshold && - fabs(previousTouchLoc.y - touchLoc.y) < touchDistanceThreshold) { - drag = YES; - [[AppDelegate sharedEmulator] setMouseButton:YES]; +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [currentTouches unionSet:touches]; + if (currentTouches.count == 1) { + [self firstTouchBegan:touches.anyObject withEvent:event]; + } else { + [self startDragging]; } - previousTouchTime = event.timestamp; - previousTouchLoc = touchLoc; } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - CGPoint touchLoc = [touches.anyObject locationInView:self]; - CGPoint locDiff = touchLoc; - locDiff.x -= previousTouchLoc.x; - locDiff.y -= previousTouchLoc.y; +- (void)firstTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { + CGPoint touchLoc = [touch locationInView:self]; + if (!isDragging && (event.timestamp - previousTouchTime < touchTimeThreshold) && + fabs(previousTouchLoc.x - touchLoc.x) < touchDistanceThreshold && + fabs(previousTouchLoc.y - touchLoc.y) < touchDistanceThreshold) { + [self startDragging]; + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch = touches.anyObject; + CGPoint touchLoc = [touch locationInView:self]; + previousTouchLoc = [touch previousLocationInView:self]; // acceleration + CGPoint locDiff = CGPointMake(touchLoc.x - previousTouchLoc.x, touchLoc.y - previousTouchLoc.y); NSTimeInterval timeDiff = 100 * (event.timestamp - previousTouchTime); NSTimeInterval accel = TRACKPAD_ACCEL_N / (TRACKPAD_ACCEL_T + ((timeDiff * timeDiff)/TRACKPAD_ACCEL_D)); locDiff.x *= accel; locDiff.y *= accel; - click = NO; + shouldClick = NO; [[AppDelegate sharedEmulator] moveMouseX:locDiff.x Y:locDiff.y]; previousTouchTime = event.timestamp; previousTouchLoc = touchLoc; } -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [currentTouches minusSet:touches]; + if (currentTouches.count > 0) { + return; + } CGPoint touchLoc = [touches.anyObject locationInView:self]; - if (click && (event.timestamp - previousTouchTime < touchTimeThreshold)) { + if (shouldClick && (event.timestamp - previousTouchTime < touchTimeThreshold)) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(mouseClick) object:nil]; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(mouseUp) object:nil]; [self performSelector:@selector(mouseClick) withObject:nil afterDelay:touchTimeThreshold]; } - click = NO; - if (drag) { - [[AppDelegate sharedEmulator] setMouseButton:NO]; - drag = NO; + shouldClick = NO; + if (isDragging) { + [self stopDragging]; } previousTouchLoc = touchLoc; previousTouchTime = event.timestamp; } +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + [currentTouches minusSet:touches]; + [self stopDragging]; +} + +- (void)startDragging { + isDragging = YES; + shouldClick = NO; + [[AppDelegate sharedEmulator] setMouseButton:YES]; +} + +- (void)stopDragging { + isDragging = NO; + shouldClick = NO; + [[AppDelegate sharedEmulator] setMouseButton:NO]; +} + - (void)mouseClick { - if (drag) { + if (isDragging) { return; } [[AppDelegate sharedEmulator] setMouseButton:YES];