OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/renderer_host/input/gestures/zoom_manager.h" |
| 6 |
| 7 #include "base/auto_reset.h" |
| 8 #include "base/logging.h" |
| 9 #include "content/browser/renderer_host/input/gestures/motion_event.h" |
| 10 |
| 11 namespace content { |
| 12 |
| 13 ZoomManager::ZoomManager(ScaleGestureDetector::Config config, |
| 14 ScaleGestureDetector::OnScaleGestureListener* listener) |
| 15 : listener_(listener), |
| 16 permanently_ignore_detector_events_(false), |
| 17 temporarily_ignore_detector_events_(false), |
| 18 pinch_event_sent_(false) { |
| 19 DCHECK(listener_); |
| 20 multi_touch_detector_.reset(new ScaleGestureDetector(config, this)); |
| 21 } |
| 22 |
| 23 ZoomManager::~ZoomManager() {} |
| 24 |
| 25 void ZoomManager::PassTouchEventThrough(const MotionEvent& event) { |
| 26 base::AutoReset<bool> temporarily_ignore_detector_events( |
| 27 &temporarily_ignore_detector_events_, true); |
| 28 multi_touch_detector_->OnTouchEvent(event); |
| 29 } |
| 30 |
| 31 bool ZoomManager::ProcessTouchEvent(const MotionEvent& event) { |
| 32 // TODO: Need to deal with multi-touch transition |
| 33 bool in_gesture = IsScaleGestureDetectionInProgress(); |
| 34 bool result = multi_touch_detector_->OnTouchEvent(event); |
| 35 if (!in_gesture && (event.GetActionMasked() == MotionEvent::ACTION_UP || |
| 36 event.GetActionMasked() == MotionEvent::ACTION_CANCEL)) { |
| 37 return false; |
| 38 } |
| 39 return result; |
| 40 } |
| 41 |
| 42 void ZoomManager::UpdateMultiTouchSupport(bool supports_multi_touch_zoom) { |
| 43 // Note that returning false from onScaleBegin / onScale makes the |
| 44 // gesture detector not to emit further scaling notifications |
| 45 // related to this gesture. Thus, if detector events are enabled in |
| 46 // the middle of the gesture, we don't need to do anything. |
| 47 permanently_ignore_detector_events_ = !supports_multi_touch_zoom; |
| 48 } |
| 49 |
| 50 bool ZoomManager::IsScaleGestureDetectionInProgress() const { |
| 51 return !permanently_ignore_detector_events_ && |
| 52 multi_touch_detector_->IsInProgress(); |
| 53 } |
| 54 |
| 55 bool ZoomManager::OnScaleBegin(const ScaleGestureDetector& detector) { |
| 56 if (IgnoreDetectorEvents()) |
| 57 return false; |
| 58 pinch_event_sent_ = false; |
| 59 // TODO(jdduke): Ignore single tap? |
| 60 return true; |
| 61 } |
| 62 |
| 63 void ZoomManager::OnScaleEnd(const ScaleGestureDetector& detector) { |
| 64 if (!pinch_event_sent_) |
| 65 return; |
| 66 listener_->OnScaleEnd(detector); |
| 67 pinch_event_sent_ = false; |
| 68 } |
| 69 |
| 70 bool ZoomManager::OnScale(const ScaleGestureDetector& detector) { |
| 71 if (IgnoreDetectorEvents()) |
| 72 return false; |
| 73 // It is possible that OnScaleBegin() was never called when we reach here. |
| 74 // This happens when webkit handles the 2nd touch down event. That causes |
| 75 // ContentView to ignore the OnScaleBegin() call. And if webkit does not |
| 76 // handle the touch move events afterwards, we will face a situation |
| 77 // that OnScale() is called without any OnScaleBegin(). |
| 78 // To solve this problem, we call OnScaleBegin() here if it is never called. |
| 79 if (!pinch_event_sent_) { |
| 80 pinch_event_sent_ = true; |
| 81 listener_->OnScaleBegin(detector); |
| 82 } |
| 83 listener_->OnScale(detector); |
| 84 return true; |
| 85 } |
| 86 |
| 87 bool ZoomManager::IgnoreDetectorEvents() const { |
| 88 return permanently_ignore_detector_events_ || |
| 89 temporarily_ignore_detector_events_; |
| 90 } |
| 91 |
| 92 } // namespace content |
OLD | NEW |