scale_gesture_detector.h revision 116680a4aac90f2aa7413d9095a592090648e557
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#ifndef UI_EVENTS_GESTURE_DETECTION_SCALE_GESTURE_DETECTOR_H_ 6#define UI_EVENTS_GESTURE_DETECTION_SCALE_GESTURE_DETECTOR_H_ 7 8#include "base/memory/scoped_ptr.h" 9#include "base/time/time.h" 10#include "ui/events/gesture_detection/gesture_detection_export.h" 11#include "ui/events/gesture_detection/gesture_detector.h" 12 13namespace ui { 14 15class MotionEvent; 16 17// Port of ScaleGestureDetector.java from Android 18// * platform/frameworks/base/core/java/android/view/ScaleGestureDetector.java 19// * Change-Id: I3e7926a4f6f9ab4951f380bd004499c78b3bda69 20// * Please update the Change-Id as upstream Android changes are pulled. 21class ScaleGestureDetector : public GestureDetector::SimpleGestureListener { 22 public: 23 struct GESTURE_DETECTION_EXPORT Config { 24 Config(); 25 ~Config(); 26 GestureDetector::Config gesture_detector_config; 27 28 // Minimum accepted value for TouchMajor while scaling (in dips). 29 float min_scaling_touch_major; 30 31 // Minimum span needed to initiate a scaling gesture (in dips). 32 float min_scaling_span; 33 34 // Whether to use touch major values when determining the scale span. 35 // Defaults to false. 36 bool use_touch_major_in_span; 37 38 // Whether double-tap drag scaling is enabled. 39 bool quick_scale_enabled; 40 41 // Minimum pinch span change before pinch occurs (in dips). See 42 // crbug.com/373318. 43 float min_pinch_update_span_delta; 44 }; 45 46 class ScaleGestureListener { 47 public: 48 virtual ~ScaleGestureListener() {} 49 virtual bool OnScale(const ScaleGestureDetector& detector, 50 const MotionEvent& e) = 0; 51 virtual bool OnScaleBegin(const ScaleGestureDetector& detector, 52 const MotionEvent& e) = 0; 53 virtual void OnScaleEnd(const ScaleGestureDetector& detector, 54 const MotionEvent& e) = 0; 55 }; 56 57 // A convenience class to extend when you only want to listen for a subset of 58 // scaling-related events. This implements all methods in 59 // |ScaleGestureListener| but does nothing. 60 // |OnScale()| returns false so that a subclass can retrieve the accumulated 61 // scale factor in an overridden |OnScaleEnd()|. 62 // |OnScaleBegin() returns true. 63 class SimpleScaleGestureListener : public ScaleGestureListener { 64 public: 65 // ScaleGestureListener implementation. 66 virtual bool OnScale(const ScaleGestureDetector&, 67 const MotionEvent&) OVERRIDE; 68 virtual bool OnScaleBegin(const ScaleGestureDetector&, 69 const MotionEvent&) OVERRIDE; 70 virtual void OnScaleEnd(const ScaleGestureDetector&, 71 const MotionEvent&) OVERRIDE; 72 }; 73 74 ScaleGestureDetector(const Config& config, ScaleGestureListener* listener); 75 virtual ~ScaleGestureDetector(); 76 77 // Accepts MotionEvents and dispatches events to a |ScaleGestureListener| 78 // when appropriate. 79 // 80 // Note: Applications should pass a complete and consistent event stream to 81 // this method. A complete and consistent event stream involves all 82 // MotionEvents from the initial ACTION_DOWN to the final ACTION_UP or 83 // ACTION_CANCEL. 84 // 85 // Returns true if the event was processed and the detector wants to receive 86 // the rest of the MotionEvents in this event stream. 87 bool OnTouchEvent(const MotionEvent& event); 88 89 // Set whether the associated |ScaleGestureListener| should receive 90 // OnScale callbacks when the user performs a doubletap followed by a swipe. 91 void SetQuickScaleEnabled(bool scales); 92 bool IsQuickScaleEnabled() const; 93 bool IsInProgress() const; 94 bool InDoubleTapMode() const; 95 float GetFocusX() const; 96 float GetFocusY() const; 97 float GetCurrentSpan() const; 98 float GetCurrentSpanX() const; 99 float GetCurrentSpanY() const; 100 float GetPreviousSpan() const; 101 float GetPreviousSpanX() const; 102 float GetPreviousSpanY() const; 103 float GetScaleFactor() const; 104 base::TimeDelta GetTimeDelta() const; 105 base::TimeTicks GetEventTime() const; 106 107 private: 108 enum DoubleTapMode { DOUBLE_TAP_MODE_NONE, DOUBLE_TAP_MODE_IN_PROGRESS }; 109 110 // DoubleTapListener implementation. 111 virtual bool OnDoubleTap(const MotionEvent& ev) OVERRIDE; 112 113 // The TouchMajor/TouchMinor elements of a MotionEvent can flutter/jitter on 114 // some hardware/driver combos. Smooth out to get kinder, gentler behavior. 115 void AddTouchHistory(const MotionEvent& ev); 116 void ResetTouchHistory(); 117 118 void ResetScaleWithSpan(float span); 119 120 ScaleGestureListener* const listener_; 121 122 Config config_; 123 124 float focus_x_; 125 float focus_y_; 126 127 bool quick_scale_enabled_; 128 129 float curr_span_; 130 float prev_span_; 131 float initial_span_; 132 float curr_span_x_; 133 float curr_span_y_; 134 float prev_span_x_; 135 float prev_span_y_; 136 base::TimeTicks curr_time_; 137 base::TimeTicks prev_time_; 138 bool in_progress_; 139 float span_slop_; 140 float min_span_; 141 142 // Bounds for recently seen values. 143 bool use_touch_major_in_span_; 144 float touch_upper_; 145 float touch_lower_; 146 float touch_history_last_accepted_; 147 int touch_history_direction_; 148 base::TimeTicks touch_history_last_accepted_time_; 149 float touch_min_major_; 150 float touch_max_major_; 151 float double_tap_focus_x_; 152 float double_tap_focus_y_; 153 DoubleTapMode double_tap_mode_; 154 155 bool event_before_or_above_starting_gesture_event_; 156 157 scoped_ptr<GestureDetector> gesture_detector_; 158 159 DISALLOW_COPY_AND_ASSIGN(ScaleGestureDetector); 160}; 161 162} // namespace ui 163 164#endif // UI_EVENTS_GESTURE_DETECTION_SCALE_GESTURE_DETECTOR_H_ 165