Chromium Code Reviews| 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 |