| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012 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 "ui/aura/gestures/gesture_sequence.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "ui/aura/event.h" |
| 10 #include "ui/base/events.h" |
| 11 |
| 12 namespace aura { |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Get equivalent TouchState from EventType |type|. |
| 17 GestureSequence::TouchState TouchEventTypeToTouchState(ui::EventType type) { |
| 18 switch (type) { |
| 19 case ui::ET_TOUCH_RELEASED: |
| 20 return GestureSequence::TS_RELEASED; |
| 21 case ui::ET_TOUCH_PRESSED: |
| 22 return GestureSequence::TS_PRESSED; |
| 23 case ui::ET_TOUCH_MOVED: |
| 24 return GestureSequence::TS_MOVED; |
| 25 case ui::ET_TOUCH_STATIONARY: |
| 26 return GestureSequence::TS_STATIONARY; |
| 27 case ui::ET_TOUCH_CANCELLED: |
| 28 return GestureSequence::TS_CANCELLED; |
| 29 default: |
| 30 VLOG(1) << "Unknown Touch Event type"; |
| 31 } |
| 32 return GestureSequence::TS_UNKNOWN; |
| 33 } |
| 34 |
| 35 } // namespace |
| 36 |
| 37 //////////////////////////////////////////////////////////////////////////////// |
| 38 // GestureSequence Public: |
| 39 |
| 40 GestureSequence::GestureSequence() |
| 41 : state_(GS_NO_GESTURE), |
| 42 flags_(0), |
| 43 point_count_(0) { |
| 44 } |
| 45 |
| 46 GestureSequence::~GestureSequence() { |
| 47 } |
| 48 |
| 49 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
| 50 const TouchEvent& event, |
| 51 ui::TouchStatus status) { |
| 52 if (status != ui::TOUCH_STATUS_UNKNOWN) |
| 53 return NULL; // The event was consumed by a touch sequence. |
| 54 |
| 55 // Set a limit on the number of simultaneous touches in a gesture. |
| 56 if (event.touch_id() >= kMaxGesturePoints) |
| 57 return NULL; |
| 58 |
| 59 if (event.type() == ui::ET_TOUCH_PRESSED) { |
| 60 if (point_count_ == kMaxGesturePoints) |
| 61 return NULL; |
| 62 ++point_count_; |
| 63 } |
| 64 |
| 65 scoped_ptr<Gestures> gestures(new Gestures()); |
| 66 GesturePoint& point = GesturePointForEvent(event); |
| 67 point.UpdateValues(event, state_); |
| 68 flags_ = event.flags(); |
| 69 switch (Signature(state_, event.touch_id(), event.type(), false)) { |
| 70 case GST_NO_GESTURE_FIRST_PRESSED: |
| 71 TouchDown(event, point, gestures.get()); |
| 72 break; |
| 73 case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED: |
| 74 if (Click(event, point, gestures.get())) |
| 75 point.UpdateForTap(); |
| 76 break; |
| 77 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED: |
| 78 case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY: |
| 79 if (InClickOrScroll(event, point, gestures.get())) |
| 80 point.UpdateForScroll(); |
| 81 break; |
| 82 case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED: |
| 83 NoGesture(event, point, gestures.get()); |
| 84 break; |
| 85 case GST_SCROLL_FIRST_MOVED: |
| 86 if (InScroll(event, point, gestures.get())) |
| 87 point.UpdateForScroll(); |
| 88 break; |
| 89 case GST_SCROLL_FIRST_RELEASED: |
| 90 case GST_SCROLL_FIRST_CANCELLED: |
| 91 ScrollEnd(event, point, gestures.get()); |
| 92 break; |
| 93 } |
| 94 |
| 95 if (event.type() == ui::ET_TOUCH_RELEASED) |
| 96 --point_count_; |
| 97 |
| 98 return gestures.release(); |
| 99 } |
| 100 |
| 101 void GestureSequence::Reset() { |
| 102 state_ = GS_NO_GESTURE; |
| 103 for (int i = 0; i < point_count_; ++i) |
| 104 points_[i].Reset(); |
| 105 } |
| 106 |
| 107 //////////////////////////////////////////////////////////////////////////////// |
| 108 // GestureSequence Private: |
| 109 |
| 110 unsigned int GestureSequence::Signature(GestureState gesture_state, |
| 111 unsigned int touch_id, |
| 112 ui::EventType type, |
| 113 bool touch_handled) { |
| 114 CHECK((touch_id & 0xfff) == touch_id); |
| 115 TouchState touch_state = TouchEventTypeToTouchState(type); |
| 116 return 1 + ((touch_state & 0x7) << 1 | (touch_handled ? 1 << 4 : 0) | |
| 117 ((touch_id & 0xfff) << 5) | (gesture_state << 17)); |
| 118 } |
| 119 |
| 120 GesturePoint& GestureSequence::GesturePointForEvent( |
| 121 const TouchEvent& event) { |
| 122 return points_[event.touch_id()]; |
| 123 } |
| 124 |
| 125 void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, |
| 126 Gestures* gestures) { |
| 127 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 128 ui::ET_GESTURE_TAP_DOWN, |
| 129 point.first_touch_position().x(), |
| 130 point.first_touch_position().y(), |
| 131 flags_, |
| 132 base::Time::FromDoubleT(point.last_touch_time()), |
| 133 0.f, 0.f))); |
| 134 } |
| 135 |
| 136 void GestureSequence::AppendClickGestureEvent(const GesturePoint& point, |
| 137 Gestures* gestures) { |
| 138 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 139 ui::ET_GESTURE_TAP, |
| 140 point.first_touch_position().x(), |
| 141 point.first_touch_position().y(), |
| 142 flags_, |
| 143 base::Time::FromDoubleT(point.last_touch_time()), |
| 144 0.f, 0.f))); |
| 145 } |
| 146 |
| 147 void GestureSequence::AppendDoubleClickGestureEvent(const GesturePoint& point, |
| 148 Gestures* gestures) { |
| 149 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 150 ui::ET_GESTURE_DOUBLE_TAP, |
| 151 point.first_touch_position().x(), |
| 152 point.first_touch_position().y(), |
| 153 flags_, |
| 154 base::Time::FromDoubleT(point.last_touch_time()), |
| 155 0.f, 0.f))); |
| 156 } |
| 157 |
| 158 void GestureSequence::AppendScrollGestureBegin(const GesturePoint& point, |
| 159 Gestures* gestures) { |
| 160 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 161 ui::ET_GESTURE_SCROLL_BEGIN, |
| 162 point.last_touch_position().x(), |
| 163 point.last_touch_position().y(), |
| 164 flags_, |
| 165 base::Time::FromDoubleT(point.last_touch_time()), |
| 166 0.f, 0.f))); |
| 167 } |
| 168 |
| 169 void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point, |
| 170 Gestures* gestures, |
| 171 float x_velocity, |
| 172 float y_velocity) { |
| 173 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 174 ui::ET_GESTURE_SCROLL_END, |
| 175 point.last_touch_position().x(), |
| 176 point.last_touch_position().y(), |
| 177 flags_, |
| 178 base::Time::FromDoubleT(point.last_touch_time()), |
| 179 x_velocity, y_velocity))); |
| 180 } |
| 181 |
| 182 void GestureSequence:: AppendScrollGestureUpdate(const GesturePoint& point, |
| 183 Gestures* gestures) { |
| 184 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| 185 ui::ET_GESTURE_SCROLL_UPDATE, |
| 186 point.last_touch_position().x(), |
| 187 point.last_touch_position().y(), |
| 188 flags_, |
| 189 base::Time::FromDoubleT(point.last_touch_time()), |
| 190 point.x_delta(), point.y_delta()))); |
| 191 } |
| 192 |
| 193 bool GestureSequence::Click(const TouchEvent& event, |
| 194 const GesturePoint& point, Gestures* gestures) { |
| 195 if (point.IsInClickWindow(event)) { |
| 196 AppendClickGestureEvent(point, gestures); |
| 197 if (point.IsInDoubleClickWindow(event)) |
| 198 AppendDoubleClickGestureEvent(point, gestures); |
| 199 return true; |
| 200 } |
| 201 return false; |
| 202 } |
| 203 |
| 204 bool GestureSequence::InClickOrScroll(const TouchEvent& event, |
| 205 const GesturePoint& point, Gestures* gestures) { |
| 206 if (point.IsInClickWindow(event)) { |
| 207 set_state(GS_PENDING_SYNTHETIC_CLICK); |
| 208 return false; |
| 209 } |
| 210 if (point.IsInScrollWindow(event)) { |
| 211 AppendScrollGestureBegin(point, gestures); |
| 212 AppendScrollGestureUpdate(point, gestures); |
| 213 set_state(GS_SCROLL); |
| 214 return true; |
| 215 } |
| 216 return false; |
| 217 } |
| 218 |
| 219 bool GestureSequence::InScroll(const TouchEvent& event, |
| 220 const GesturePoint& point, Gestures* gestures) { |
| 221 AppendScrollGestureUpdate(point, gestures); |
| 222 return true; |
| 223 } |
| 224 |
| 225 bool GestureSequence::NoGesture(const TouchEvent&, |
| 226 const GesturePoint& point, Gestures*) { |
| 227 Reset(); |
| 228 return false; |
| 229 } |
| 230 |
| 231 bool GestureSequence::TouchDown(const TouchEvent& event, |
| 232 const GesturePoint& point, Gestures* gestures) { |
| 233 AppendTapDownGestureEvent(point, gestures); |
| 234 set_state(GS_PENDING_SYNTHETIC_CLICK); |
| 235 return false; |
| 236 } |
| 237 |
| 238 bool GestureSequence::ScrollEnd(const TouchEvent& event, |
| 239 const GesturePoint& point, Gestures* gestures) { |
| 240 if (point.IsInFlickWindow(event)) |
| 241 AppendScrollGestureEnd(point, gestures, point.x_velocity(), |
| 242 point.y_velocity()); |
| 243 else |
| 244 AppendScrollGestureEnd(point, gestures, 0.f, 0.f); |
| 245 set_state(GS_NO_GESTURE); |
| 246 Reset(); |
| 247 return false; |
| 248 } |
| 249 |
| 250 } // namespace aura |
| OLD | NEW |