| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.
h" | 5 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.
h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include "base/ios/ios_util.h" | |
| 11 #include "base/logging.h" | 10 #include "base/logging.h" |
| 12 #include "base/mac/objc_property_releaser.h" | 11 #include "base/mac/objc_property_releaser.h" |
| 13 #include "base/mac/scoped_nsobject.h" | 12 #include "base/mac/scoped_nsobject.h" |
| 14 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 15 #import "ios/chrome/browser/ui/browser_view_controller.h" | 14 #import "ios/chrome/browser/ui/browser_view_controller.h" |
| 16 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" | 15 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" |
| 17 #include "ios/chrome/browser/ui/rtl_geometry.h" | 16 #include "ios/chrome/browser/ui/rtl_geometry.h" |
| 18 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" | 17 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" |
| 19 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" | 18 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" |
| 19 #include "ios/chrome/browser/ui/uikit_ui_util.h" |
| 20 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h" | 20 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h" |
| 21 #import "ios/web/public/web_state/crw_web_view_proxy.h" | 21 #import "ios/web/public/web_state/crw_web_view_proxy.h" |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 // This enum is used to record the overscroll actions performed by the user on | 24 // This enum is used to record the overscroll actions performed by the user on |
| 25 // the histogram named |OverscrollActions|. | 25 // the histogram named |OverscrollActions|. |
| 26 enum { | 26 enum { |
| 27 // Records each time the user selects the new tab action. | 27 // Records each time the user selects the new tab action. |
| 28 OVERSCROLL_ACTION_NEW_TAB, | 28 OVERSCROLL_ACTION_NEW_TAB, |
| 29 // Records each time the user selects the refresh action. | 29 // Records each time the user selects the refresh action. |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 // Not doing so would result in a graphic issue where the scrollview jumps | 645 // Not doing so would result in a graphic issue where the scrollview jumps |
| 646 // when scrolling after a change in UI orientation. | 646 // when scrolling after a change in UI orientation. |
| 647 [[self scrollView] panGestureRecognizer].enabled = NO; | 647 [[self scrollView] panGestureRecognizer].enabled = NO; |
| 648 [[self scrollView] panGestureRecognizer].enabled = YES; | 648 [[self scrollView] panGestureRecognizer].enabled = YES; |
| 649 | 649 |
| 650 [self setScrollViewContentInset:UIEdgeInsetsMake(self.initialContentInset, 0, | 650 [self setScrollViewContentInset:UIEdgeInsetsMake(self.initialContentInset, 0, |
| 651 0, 0)]; | 651 0, 0)]; |
| 652 [self clear]; | 652 [self clear]; |
| 653 } | 653 } |
| 654 | 654 |
| 655 // On iOS10 and above, trigger a haptic vibration for the user selecting an | |
| 656 // action. This is a no-op for devices that do not support it. | |
| 657 - (void)triggerHapticFeedbackForAction { | |
| 658 if (base::ios::IsRunningOnIOS10OrLater()) { | |
| 659 base::scoped_nsobject<UIImpactFeedbackGenerator> generator( | |
| 660 [[UIImpactFeedbackGenerator alloc] init]); | |
| 661 [generator impactOccurred]; | |
| 662 } | |
| 663 } | |
| 664 | |
| 665 // On iOS10 and above, trigger a haptic vibration for the change in selection. | |
| 666 // This is a no-op for devices that do not support it. | |
| 667 - (void)triggerHapticFeedbackForSelectionChange { | |
| 668 if (base::ios::IsRunningOnIOS10OrLater()) { | |
| 669 base::scoped_nsobject<UISelectionFeedbackGenerator> generator( | |
| 670 [[UISelectionFeedbackGenerator alloc] init]); | |
| 671 [generator selectionChanged]; | |
| 672 } | |
| 673 } | |
| 674 | |
| 675 - (BOOL)isOverscrollActionEnabled { | 655 - (BOOL)isOverscrollActionEnabled { |
| 676 return _overscrollActionLock == 0 && _allowPullingActions && | 656 return _overscrollActionLock == 0 && _allowPullingActions && |
| 677 !_isOverscrollActionsDisabledForLoading; | 657 !_isOverscrollActionsDisabledForLoading; |
| 678 } | 658 } |
| 679 | 659 |
| 680 - (void)triggerActionIfNeeded { | 660 - (void)triggerActionIfNeeded { |
| 681 if ([self isOverscrollActionEnabled]) { | 661 if ([self isOverscrollActionEnabled]) { |
| 682 const BOOL isOverscrollStateActionReady = | 662 const BOOL isOverscrollStateActionReady = |
| 683 self.overscrollState == OverscrollState::ACTION_READY; | 663 self.overscrollState == OverscrollState::ACTION_READY; |
| 684 const BOOL isOverscrollActionNone = | 664 const BOOL isOverscrollActionNone = |
| 685 self.overscrollActionView.selectedAction == OverscrollAction::NONE; | 665 self.overscrollActionView.selectedAction == OverscrollAction::NONE; |
| 686 | 666 |
| 687 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) || | 667 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) || |
| 688 (isOverscrollStateActionReady && isOverscrollActionNone)) { | 668 (isOverscrollStateActionReady && isOverscrollActionNone)) { |
| 689 [self recordMetricForTriggeredAction:OverscrollAction::NONE]; | 669 [self recordMetricForTriggeredAction:OverscrollAction::NONE]; |
| 690 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) { | 670 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) { |
| 691 if (CACurrentMediaTime() - _lastScrollBeginTime >= | 671 if (CACurrentMediaTime() - _lastScrollBeginTime >= |
| 692 kMinimumPullDurationToTriggerActionInSeconds) { | 672 kMinimumPullDurationToTriggerActionInSeconds) { |
| 693 _performingScrollViewIndependentAnimation = YES; | 673 _performingScrollViewIndependentAnimation = YES; |
| 694 [self setScrollViewContentInset:UIEdgeInsetsMake( | 674 [self setScrollViewContentInset:UIEdgeInsetsMake( |
| 695 self.initialContentInset, 0, 0, 0)]; | 675 self.initialContentInset, 0, 0, 0)]; |
| 696 CGPoint contentOffset = [[self scrollView] contentOffset]; | 676 CGPoint contentOffset = [[self scrollView] contentOffset]; |
| 697 contentOffset.y = -self.initialContentInset; | 677 contentOffset.y = -self.initialContentInset; |
| 698 [[self scrollView] setContentOffset:contentOffset animated:YES]; | 678 [[self scrollView] setContentOffset:contentOffset animated:YES]; |
| 699 [self.overscrollActionView displayActionAnimation]; | 679 [self.overscrollActionView displayActionAnimation]; |
| 700 dispatch_async(dispatch_get_main_queue(), ^{ | 680 dispatch_async(dispatch_get_main_queue(), ^{ |
| 701 [self recordMetricForTriggeredAction:self.overscrollActionView | 681 [self recordMetricForTriggeredAction:self.overscrollActionView |
| 702 .selectedAction]; | 682 .selectedAction]; |
| 703 [self triggerHapticFeedbackForAction]; | 683 TriggerHapticFeedbackForAction(); |
| 704 [self.delegate overscrollActionsController:self | 684 [self.delegate overscrollActionsController:self |
| 705 didTriggerAction:self.overscrollActionView | 685 didTriggerAction:self.overscrollActionView |
| 706 .selectedAction]; | 686 .selectedAction]; |
| 707 }); | 687 }); |
| 708 } | 688 } |
| 709 } | 689 } |
| 710 } | 690 } |
| 711 } | 691 } |
| 712 | 692 |
| 713 - (void)setOverscrollState:(OverscrollState)overscrollState { | 693 - (void)setOverscrollState:(OverscrollState)overscrollState { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 recordMetricForTriggeredAction:self.overscrollActionView.selectedAction]; | 890 recordMetricForTriggeredAction:self.overscrollActionView.selectedAction]; |
| 911 | 891 |
| 912 // Reset all pan gesture recognizers. | 892 // Reset all pan gesture recognizers. |
| 913 _allowPullingActions = NO; | 893 _allowPullingActions = NO; |
| 914 _panGestureRecognizer.enabled = NO; | 894 _panGestureRecognizer.enabled = NO; |
| 915 _panGestureRecognizer.enabled = YES; | 895 _panGestureRecognizer.enabled = YES; |
| 916 [self scrollView].panGestureRecognizer.enabled = NO; | 896 [self scrollView].panGestureRecognizer.enabled = NO; |
| 917 [self scrollView].panGestureRecognizer.enabled = YES; | 897 [self scrollView].panGestureRecognizer.enabled = YES; |
| 918 [self startBounceWithInitialVelocity:CGPointZero]; | 898 [self startBounceWithInitialVelocity:CGPointZero]; |
| 919 | 899 |
| 920 [self triggerHapticFeedbackForAction]; | 900 TriggerHapticFeedbackForAction(); |
| 921 [self.delegate | 901 [self.delegate |
| 922 overscrollActionsController:self | 902 overscrollActionsController:self |
| 923 didTriggerAction:self.overscrollActionView.selectedAction]; | 903 didTriggerAction:self.overscrollActionView.selectedAction]; |
| 924 } | 904 } |
| 925 | 905 |
| 926 - (void)overscrollActionsView:(OverscrollActionsView*)view | 906 - (void)overscrollActionsView:(OverscrollActionsView*)view |
| 927 selectedActionDidChange:(OverscrollAction)newAction { | 907 selectedActionDidChange:(OverscrollAction)newAction { |
| 928 [self triggerHapticFeedbackForSelectionChange]; | 908 TriggerHapticFeedbackForSelectionChange(); |
| 929 } | 909 } |
| 930 | 910 |
| 931 @end | 911 @end |
| OLD | NEW |