| 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..66cb5753669a867480ab4028a552454f373b3cf0
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/side_swipe_gesture_recognizer.mm
|
| @@ -0,0 +1,106 @@
|
| +// 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 kMaxSwipeYAngle = 65;
|
| +// The distance between touches for a swipe to begin.
|
| +CGFloat kMinSwipeXThreshold = 4;
|
| +
|
| +} // namespace
|
| +
|
| +@implementation SideSwipeGestureRecognizer {
|
| + // Starting point of swipe.
|
| + CGPoint _startPoint;
|
| + // Expected direction of the swipe, based on starting point.
|
| + UISwipeGestureRecognizerDirection _direction;
|
| +}
|
| +
|
| +@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 |kMaxSwipeYAngle|.
|
| + 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 = std::fabs(std::atan2(dy, dx) * 180 / CGFloat(M_PI));
|
| + if (degrees > kMaxSwipeYAngle) {
|
| + 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 |kMinSwipeXThreshold| distance swiped.
|
| + if (std::abs(currentPoint.x - _startPoint.x) > kMinSwipeXThreshold) {
|
| + 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
|
|
|