VLCSiriRemoteGestureRecognizer.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*****************************************************************************
  2. * VLC for iOS
  3. *****************************************************************************
  4. * Copyright (c) 2015 VideoLAN. All rights reserved.
  5. * $Id$
  6. *
  7. * Authors: Tobias Conradi <videolan # tobias-conradi.de>
  8. *
  9. * Refer to the COPYING file of the official project for license.
  10. *****************************************************************************/
  11. #import "VLCSiriRemoteGestureRecognizer.h"
  12. #import <UIKit/UIGestureRecognizerSubclass.h>
  13. @interface UIEvent (VLCDigitizerLocation)
  14. - (CGPoint)vlc_digitizerLocation;
  15. @end
  16. @interface VLCSiriRemoteGestureRecognizer ()
  17. {
  18. NSTimer *_longPressTimer;
  19. }
  20. @end
  21. @implementation VLCSiriRemoteGestureRecognizer
  22. @dynamic delegate;
  23. - (instancetype)initWithTarget:(id)target action:(SEL)action
  24. {
  25. self = [super initWithTarget:target action:action];
  26. if (self) {
  27. self.allowedTouchTypes = @[@(UITouchTypeIndirect)];
  28. self.allowedPressTypes = @[@(UIPressTypeSelect)];
  29. self.minLongPressDuration = 0.5;
  30. self.cancelsTouchesInView = NO;
  31. }
  32. return self;
  33. }
  34. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  35. {
  36. self.state = UIGestureRecognizerStateBegan;
  37. [self updateTouchLocationWithEvent:event];
  38. }
  39. - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  40. {
  41. self.state = UIGestureRecognizerStateChanged;
  42. [self updateTouchLocationWithEvent:event];
  43. }
  44. - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  45. {
  46. self.state = UIGestureRecognizerStateCancelled;
  47. [self updateTouchLocation:VLCSiriRemoteTouchLocationUnknown];
  48. }
  49. - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  50. {
  51. self.state = UIGestureRecognizerStateEnded;
  52. [self updateTouchLocationWithEvent:event];
  53. }
  54. - (void)updateTouchLocationWithEvent:(UIEvent *)event
  55. {
  56. CGPoint digitizerLocation = [event vlc_digitizerLocation];
  57. VLCSiriRemoteTouchLocation location = VLCSiriRemoteTouchLocationUnknown;
  58. if (digitizerLocation.x <= 0.2) {
  59. location = VLCSiriRemoteTouchLocationLeft;
  60. } else if (0.8 <= digitizerLocation.x) {
  61. location = VLCSiriRemoteTouchLocationRight;
  62. } else if (digitizerLocation.y <= 0.2) {
  63. location = VLCSiriRemoteTouchLocationUp;
  64. } else if (0.8 <= digitizerLocation.y) {
  65. location = VLCSiriRemoteTouchLocationDown;
  66. }
  67. [self updateTouchLocation:location];
  68. }
  69. - (void)updateTouchLocation:(VLCSiriRemoteTouchLocation)location
  70. {
  71. if (_touchLocation == location) {
  72. return;
  73. }
  74. _touchLocation = location;
  75. }
  76. - (void)reset
  77. {
  78. _click = NO;
  79. _touchLocation = VLCSiriRemoteTouchLocationUnknown;
  80. _longPress = NO;
  81. [_longPressTimer invalidate];
  82. _longPressTimer = nil;
  83. [super reset];
  84. }
  85. - (void)longPressTimerFired
  86. {
  87. if (_click && (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged)) {
  88. _longPress = YES;
  89. self.state = UIGestureRecognizerStateChanged;
  90. }
  91. }
  92. - (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
  93. {
  94. if ([self.allowedPressTypes containsObject:@(presses.anyObject.type)]) {
  95. _click = YES;
  96. _longPressTimer = [NSTimer scheduledTimerWithTimeInterval:self.minLongPressDuration target:self selector:@selector(longPressTimerFired) userInfo:nil repeats:NO];
  97. self.state = UIGestureRecognizerStateChanged;
  98. }
  99. }
  100. - (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
  101. {
  102. self.state = UIGestureRecognizerStateChanged;
  103. }
  104. - (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
  105. {
  106. self.state = UIGestureRecognizerStateCancelled;
  107. }
  108. - (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
  109. {
  110. if (_click) {
  111. self.state = UIGestureRecognizerStateEnded;
  112. }
  113. }
  114. @end
  115. @implementation UIEvent (VLCDigitizerLocation)
  116. - (CGPoint)vlc_digitizerLocation
  117. {
  118. /*
  119. * !!! Attention: We are using private API !!!
  120. * !!! Might break in any future release !!!
  121. *
  122. * The digitizer location is the absolut location of the touch on the touch pad.
  123. * The location is in a 0,0 (top left) to 1,1 (bottom right) coordinate system.
  124. */
  125. NSString *key = [@"digitiz" stringByAppendingString:@"erLocation"];
  126. NSNumber *value = [self valueForKey:key];
  127. if ([value isKindOfClass:[NSValue class]]) {
  128. return [value CGPointValue];
  129. }
  130. // default to center position as undefined position
  131. return CGPointMake(0.5,0.5);
  132. }
  133. @end