Index: ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm |
diff --git a/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm b/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3be4a45adda68520bd893dc1b0bdb8783934adf3 |
--- /dev/null |
+++ b/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm |
@@ -0,0 +1,101 @@ |
+// Copyright 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "ios/chrome/browser/ui/side_swipe_gesture_recognizer.h" |
+ |
+#include <cmath> |
+ |
+#include "base/logging.h" |
+ |
+namespace { |
+ |
+// The absolute maximum swipe angle from |x = y| for a swipe to begin. |
+CGFloat MAX_SWIPE_Y_ANGLE = 65; |
sdefresne
2015/04/02 17:20:29
style: const CGFloat kMaxSwipeYAngleDegree = 65;
|
+// The distance between touches for a swipe to begin. |
+CGFloat MIN_SWIPE_X_THRESHOLD = 4; |
sdefresne
2015/04/02 17:20:29
style: const CGFloat kMinSwipeXThresholdPoint = 4;
|
+ |
+} // namespace |
+ |
+@implementation SideSwipeGestureRecognizer |
+ |
+@synthesize swipeEdge = swipeEdge_; |
+@synthesize direction = direction_; |
+@synthesize swipeOffset = swipeOffset_; |
+ |
+// To quickly avoid interference with other gesture recognizers, fail |
+// immediately if the touches aren't at the edge of the touched view. |
+- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { |
+ [super touchesBegan:touches withEvent:event]; |
+ UITouch* touch = [[event allTouches] anyObject]; |
+ CGPoint location = [touch locationInView:self.view]; |
+ if (location.x > swipeEdge_ && |
+ location.x < CGRectGetMaxX([self.view bounds]) - swipeEdge_) { |
+ self.state = UIGestureRecognizerStateFailed; |
+ } else { |
+ if (location.x < swipeEdge_) { |
+ direction_ = UISwipeGestureRecognizerDirectionRight; |
+ } else { |
+ direction_ = UISwipeGestureRecognizerDirectionLeft; |
+ } |
+ startPoint_ = location; |
+ } |
+} |
+ |
+- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { |
+ // Revert to normal pan gesture recognizer characteristics after state began. |
+ if (self.state != UIGestureRecognizerStatePossible) { |
+ [super touchesMoved:touches withEvent:event]; |
+ return; |
+ } |
+ |
+ // Only one touch. |
+ if ([[event allTouches] count] > 1) { |
+ self.state = UIGestureRecognizerStateFailed; |
+ return; |
+ } |
+ |
+ // Don't swipe at an angle greater than |MAX_SWIPE_Y_ANGLE|. |
+ UITouch* touch = [[event allTouches] anyObject]; |
+ CGPoint currentPoint = [touch locationInView:self.view]; |
+ CGFloat dy = currentPoint.y - startPoint_.y; |
+ CGFloat dx = std::abs(currentPoint.x - startPoint_.x); |
+ CGFloat degrees = fabsf(atan2f(dy, dx) * 180 / float(M_PI)); |
sdefresne
2015/04/02 17:20:29
nit: std::fabs(std::atan2(dy, dx) * 180 / CGFloat(
|
+ if (degrees > MAX_SWIPE_Y_ANGLE) { |
+ self.state = UIGestureRecognizerStateFailed; |
+ return; |
+ } |
+ |
+ // Don't recognize swipe in the wrong direction. |
+ if ((direction_ == UISwipeGestureRecognizerDirectionRight && |
+ currentPoint.x - startPoint_.x < 0) || |
+ (direction_ == UISwipeGestureRecognizerDirectionLeft && |
+ currentPoint.x - startPoint_.x > 0)) { |
+ self.state = UIGestureRecognizerStateFailed; |
+ return; |
+ } |
+ |
+ // Begin recognizer after |MIN_SWIPE_X_THRESHOLD| distance swiped. |
+ if (ABS(currentPoint.x - startPoint_.x) > MIN_SWIPE_X_THRESHOLD) { |
sdefresne
2015/04/02 17:20:29
nit: std::abs(currentPoint.x - startPoint.x)
|
+ if (direction_ == UISwipeGestureRecognizerDirectionRight) { |
+ swipeOffset_ = currentPoint.x; |
+ } else { |
+ swipeOffset_ = -(CGRectGetMaxX([self.view bounds]) - currentPoint.x); |
+ } |
+ |
+ self.state = UIGestureRecognizerStateBegan; |
+ return; |
+ } |
+} |
+ |
+- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { |
+ startPoint_ = CGPointZero; |
+ [super touchesEnded:touches withEvent:event]; |
+} |
+ |
+- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { |
+ startPoint_ = CGPointZero; |
+ [super touchesCancelled:touches withEvent:event]; |
+} |
+ |
+@end |