// // AbsoluteTouchHandler.m // Moonlight // // Created by Cameron Gutman on 11/1/20. // Copyright © 2020 Moonlight Game Streaming Project. All rights reserved. // #import "AbsoluteTouchHandler.h" #include // How long the fingers must be stationary to start a right click #define LONG_PRESS_ACTIVATION_DELAY 0.650f // How far the finger can move before it cancels a right click #define LONG_PRESS_ACTIVATION_DELTA 0.01f // How long the double tap deadzone stays in effect between touch up and touch down #define DOUBLE_TAP_DEAD_ZONE_DELAY 0.250f // How far the finger can move before it can override the double tap deadzone #define DOUBLE_TAP_DEAD_ZONE_DELTA 0.025f @implementation AbsoluteTouchHandler { StreamView* view; NSTimer* longPressTimer; UITouch* lastTouchDown; CGPoint lastTouchDownLocation; UITouch* lastTouchUp; CGPoint lastTouchUpLocation; } - (id)initWithView:(StreamView*)view { self = [self init]; self->view = view; return self; } //- (void)onLongPressStart:(NSTimer*)timer { // // Raise the left click and start a right click // LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); // LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT); //} // //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // // Ignore touch down events with more than one finger // return; // if ([[event allTouches] count] > 1) { // return; // } // // UITouch* touch = [touches anyObject]; // CGPoint touchLocation = [touch locationInView:view]; // // // Don't reposition for finger down events within the deadzone. This makes double-clicking easier. // if (touch.timestamp - lastTouchUp.timestamp > DOUBLE_TAP_DEAD_ZONE_DELAY || // sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchUpLocation.x / view.bounds.size.width), 2) + // pow((touchLocation.y / view.bounds.size.height) - (lastTouchUpLocation.y / view.bounds.size.height), 2)) > DOUBLE_TAP_DEAD_ZONE_DELTA) { // [view updateCursorLocation:touchLocation isMouse:NO]; // } // // // Press the left button down // LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT); // // // Start the long press timer // longPressTimer = [NSTimer scheduledTimerWithTimeInterval:LONG_PRESS_ACTIVATION_DELAY // target:self // selector:@selector(onLongPressStart:) // userInfo:nil // repeats:NO]; // // lastTouchDown = touch; // lastTouchDownLocation = touchLocation; //} // //- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { // // Ignore touch move events with more than one finger // return; // if ([[event allTouches] count] > 1) { // return; // } // // UITouch* touch = [touches anyObject]; // CGPoint touchLocation = [touch locationInView:view]; // // if (sqrt(pow((touchLocation.x / view.bounds.size.width) - (lastTouchDownLocation.x / view.bounds.size.width), 2) + // pow((touchLocation.y / view.bounds.size.height) - (lastTouchDownLocation.y / view.bounds.size.height), 2)) > LONG_PRESS_ACTIVATION_DELTA) { // // Moved too far since touch down. Cancel the long press timer. // [longPressTimer invalidate]; // longPressTimer = nil; // } // // [view updateCursorLocation:[[touches anyObject] locationInView:view] isMouse:NO]; //} // //- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // // Only fire this logic if all touches have ended // if ([[event allTouches] count] == [touches count]) { // // Cancel the long press timer // [longPressTimer invalidate]; // longPressTimer = nil; // // // Left button up on finger up // LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); // // // Raise right button too in case we triggered a long press gesture // LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT); // // // Remember this last touch for touch-down deadzoning // lastTouchUp = [touches anyObject]; // lastTouchUpLocation = [lastTouchUp locationInView:view]; // } //} // //- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { // // Treat this as a normal touchesEnded event // [self touchesEnded:touches withEvent:event]; //} @end