OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include "ui/aura/gestures/gesture_sequence.h" | 5 #include "ui/aura/gestures/gesture_sequence.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 #include "ui/aura/event.h" | 10 #include "ui/aura/event.h" |
11 #include "ui/aura/root_window.h" | 11 #include "ui/aura/root_window.h" |
12 #include "ui/aura/gestures/gesture_configuration.h" | 12 #include "ui/aura/gestures/gesture_configuration.h" |
13 #include "ui/base/events.h" | 13 #include "ui/base/events.h" |
14 | 14 |
15 // TODO(sad): Pinch gestures currently always assume that the first two | |
16 // touch-points (i.e. at indices 0 and 1) are involved. This may not | |
17 // always be the case. This needs to be fixed eventually. | |
18 // http://crbug.com/113144 | |
19 | |
20 namespace { | 15 namespace { |
21 | 16 |
22 // TODO(girard): Make these configurable in sync with this CL | 17 // TODO(girard): Make these configurable in sync with this CL |
23 // http://crbug.com/100773 | 18 // http://crbug.com/100773 |
24 const float kMinimumPinchUpdateDistance = 5; // in pixels | 19 const float kMinimumPinchUpdateDistance = 5; // in pixels |
25 const float kMinimumDistanceForPinchScroll = 20; | 20 const float kMinimumDistanceForPinchScroll = 20; |
26 const float kLongPressTimeInMilliseconds = 500; | 21 const float kLongPressTimeInMilliseconds = 500; |
27 | 22 |
28 } // namespace | 23 } // namespace |
29 | 24 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 87 |
93 GST_SCROLL_FIRST_RELEASED = | 88 GST_SCROLL_FIRST_RELEASED = |
94 G(GS_SCROLL, 0, TS_RELEASED, false), | 89 G(GS_SCROLL, 0, TS_RELEASED, false), |
95 | 90 |
96 GST_SCROLL_FIRST_MOVED = | 91 GST_SCROLL_FIRST_MOVED = |
97 G(GS_SCROLL, 0, TS_MOVED, false), | 92 G(GS_SCROLL, 0, TS_MOVED, false), |
98 | 93 |
99 GST_SCROLL_FIRST_CANCELLED = | 94 GST_SCROLL_FIRST_CANCELLED = |
100 G(GS_SCROLL, 0, TS_CANCELLED, false), | 95 G(GS_SCROLL, 0, TS_CANCELLED, false), |
101 | 96 |
102 GST_SCROLL_FIRST_PRESSED = | |
103 G(GS_SCROLL, 0, TS_PRESSED, false), | |
104 | |
105 GST_SCROLL_SECOND_RELEASED = | |
106 G(GS_SCROLL, 1, TS_RELEASED, false), | |
107 | |
108 GST_SCROLL_SECOND_MOVED = | |
109 G(GS_SCROLL, 1, TS_MOVED, false), | |
110 | |
111 GST_SCROLL_SECOND_CANCELLED = | |
112 G(GS_SCROLL, 1, TS_CANCELLED, false), | |
113 | |
114 GST_SCROLL_SECOND_PRESSED = | 97 GST_SCROLL_SECOND_PRESSED = |
115 G(GS_SCROLL, 1, TS_PRESSED, false), | 98 G(GS_SCROLL, 1, TS_PRESSED, false), |
116 | 99 |
117 GST_PINCH_FIRST_MOVED = | 100 GST_PINCH_FIRST_MOVED = |
118 G(GS_PINCH, 0, TS_MOVED, false), | 101 G(GS_PINCH, 0, TS_MOVED, false), |
119 | 102 |
120 GST_PINCH_SECOND_MOVED = | 103 GST_PINCH_SECOND_MOVED = |
121 G(GS_PINCH, 1, TS_MOVED, false), | 104 G(GS_PINCH, 1, TS_MOVED, false), |
122 | 105 |
123 GST_PINCH_FIRST_RELEASED = | 106 GST_PINCH_FIRST_RELEASED = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // GestureSequence Public: | 140 // GestureSequence Public: |
158 | 141 |
159 GestureSequence::GestureSequence(RootWindow* root_window) | 142 GestureSequence::GestureSequence(RootWindow* root_window) |
160 : state_(GS_NO_GESTURE), | 143 : state_(GS_NO_GESTURE), |
161 flags_(0), | 144 flags_(0), |
162 pinch_distance_start_(0.f), | 145 pinch_distance_start_(0.f), |
163 pinch_distance_current_(0.f), | 146 pinch_distance_current_(0.f), |
164 long_press_timer_(CreateTimer()), | 147 long_press_timer_(CreateTimer()), |
165 point_count_(0), | 148 point_count_(0), |
166 root_window_(root_window) { | 149 root_window_(root_window) { |
167 for (int i = 0; i < kMaxGesturePoints; ++i) { | |
168 points_[i].set_touch_id(i); | |
169 } | |
170 } | 150 } |
171 | 151 |
172 GestureSequence::~GestureSequence() { | 152 GestureSequence::~GestureSequence() { |
173 } | 153 } |
174 | 154 |
175 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( | 155 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
176 const TouchEvent& event, | 156 const TouchEvent& event, |
177 ui::TouchStatus status) { | 157 ui::TouchStatus status) { |
178 if (status != ui::TOUCH_STATUS_UNKNOWN) | 158 if (status != ui::TOUCH_STATUS_UNKNOWN) |
179 return NULL; // The event was consumed by a touch sequence. | 159 return NULL; // The event was consumed by a touch sequence. |
180 | 160 |
181 // Set a limit on the number of simultaneous touches in a gesture. | 161 // Set a limit on the number of simultaneous touches in a gesture. |
182 if (event.touch_id() >= kMaxGesturePoints) | 162 if (event.touch_id() >= kMaxGesturePoints) |
183 return NULL; | 163 return NULL; |
184 | 164 |
185 if (event.type() == ui::ET_TOUCH_PRESSED) { | 165 if (event.type() == ui::ET_TOUCH_PRESSED) { |
186 if (point_count_ == kMaxGesturePoints) | 166 if (point_count_ == kMaxGesturePoints) |
187 return NULL; | 167 return NULL; |
188 ++point_count_; | 168 GesturePoint* new_point = &points_[event.touch_id()]; |
| 169 // Eventually, we shouldn't be able to get two PRESSED events without either |
| 170 // a RELEASE or CANCEL. Currently if a RELEASE is preventDefaulted, |
| 171 // this could occur: crbug.com/116537 |
| 172 // TODO(tdresser): Enable this DCHECK, and remove the following condition |
| 173 // DCHECK(!points_[event.touch_id()].in_use()); |
| 174 if (!points_[event.touch_id()].in_use()) |
| 175 new_point->set_point_id(point_count_++); |
189 } | 176 } |
190 | 177 |
191 GestureState last_state = state_; | 178 GestureState last_state = state_; |
192 | 179 |
193 // NOTE: when modifying these state transitions, also update gestures.dot | 180 // NOTE: when modifying these state transitions, also update gestures.dot |
194 scoped_ptr<Gestures> gestures(new Gestures()); | 181 scoped_ptr<Gestures> gestures(new Gestures()); |
195 GesturePoint& point = GesturePointForEvent(event); | 182 GesturePoint& point = GesturePointForEvent(event); |
196 point.UpdateValues(event); | 183 point.UpdateValues(event); |
197 flags_ = event.flags(); | 184 flags_ = event.flags(); |
198 switch (Signature(state_, event.touch_id(), event.type(), false)) { | 185 const int point_id = points_[event.touch_id()].point_id(); |
| 186 if (point_id < 0) |
| 187 return NULL; |
| 188 switch (Signature(state_, point_id, event.type(), false)) { |
199 case GST_NO_GESTURE_FIRST_PRESSED: | 189 case GST_NO_GESTURE_FIRST_PRESSED: |
200 TouchDown(event, point, gestures.get()); | 190 TouchDown(event, point, gestures.get()); |
201 set_state(GS_PENDING_SYNTHETIC_CLICK); | 191 set_state(GS_PENDING_SYNTHETIC_CLICK); |
202 break; | 192 break; |
203 case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED: | 193 case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED: |
204 if (Click(event, point, gestures.get())) | 194 if (Click(event, point, gestures.get())) |
205 point.UpdateForTap(); | 195 point.UpdateForTap(); |
206 set_state(GS_NO_GESTURE); | 196 set_state(GS_NO_GESTURE); |
207 break; | 197 break; |
208 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED: | 198 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED: |
209 case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY: | 199 case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY: |
210 if (ScrollStart(event, point, gestures.get())) { | 200 if (ScrollStart(event, point, gestures.get())) { |
211 set_state(GS_SCROLL); | 201 set_state(GS_SCROLL); |
212 if (ScrollUpdate(event, point, gestures.get())) | 202 if (ScrollUpdate(event, point, gestures.get())) |
213 point.UpdateForScroll(); | 203 point.UpdateForScroll(); |
214 } | 204 } |
215 break; | 205 break; |
216 case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED: | 206 case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED: |
217 NoGesture(event, point, gestures.get()); | 207 NoGesture(event, point, gestures.get()); |
218 break; | 208 break; |
219 case GST_SCROLL_FIRST_MOVED: | 209 case GST_SCROLL_FIRST_MOVED: |
220 case GST_SCROLL_SECOND_MOVED: | |
221 if (scroll_type_ == ST_VERTICAL || | 210 if (scroll_type_ == ST_VERTICAL || |
222 scroll_type_ == ST_HORIZONTAL) | 211 scroll_type_ == ST_HORIZONTAL) |
223 BreakRailScroll(event, point, gestures.get()); | 212 BreakRailScroll(event, point, gestures.get()); |
224 if (ScrollUpdate(event, point, gestures.get())) | 213 if (ScrollUpdate(event, point, gestures.get())) |
225 point.UpdateForScroll(); | 214 point.UpdateForScroll(); |
226 break; | 215 break; |
227 case GST_SCROLL_FIRST_RELEASED: | 216 case GST_SCROLL_FIRST_RELEASED: |
228 case GST_SCROLL_FIRST_CANCELLED: | 217 case GST_SCROLL_FIRST_CANCELLED: |
229 case GST_SCROLL_SECOND_RELEASED: | |
230 case GST_SCROLL_SECOND_CANCELLED: | |
231 ScrollEnd(event, point, gestures.get()); | 218 ScrollEnd(event, point, gestures.get()); |
232 set_state(GS_NO_GESTURE); | 219 set_state(GS_NO_GESTURE); |
233 break; | 220 break; |
234 case GST_SCROLL_FIRST_PRESSED: | |
235 case GST_SCROLL_SECOND_PRESSED: | 221 case GST_SCROLL_SECOND_PRESSED: |
236 case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED: | 222 case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED: |
237 PinchStart(event, point, gestures.get()); | 223 PinchStart(event, point, gestures.get()); |
238 set_state(GS_PINCH); | 224 set_state(GS_PINCH); |
239 break; | 225 break; |
240 case GST_PINCH_FIRST_MOVED: | 226 case GST_PINCH_FIRST_MOVED: |
241 case GST_PINCH_SECOND_MOVED: | 227 case GST_PINCH_SECOND_MOVED: |
242 if (PinchUpdate(event, point, gestures.get())) { | 228 if (PinchUpdate(event, point, gestures.get())) { |
243 points_[0].UpdateForScroll(); | 229 GetPointByPointId(0)->UpdateForScroll(); |
244 points_[1].UpdateForScroll(); | 230 GetPointByPointId(1)->UpdateForScroll(); |
245 } | 231 } |
246 break; | 232 break; |
247 case GST_PINCH_FIRST_RELEASED: | 233 case GST_PINCH_FIRST_RELEASED: |
248 case GST_PINCH_SECOND_RELEASED: | 234 case GST_PINCH_SECOND_RELEASED: |
249 case GST_PINCH_FIRST_CANCELLED: | 235 case GST_PINCH_FIRST_CANCELLED: |
250 case GST_PINCH_SECOND_CANCELLED: | 236 case GST_PINCH_SECOND_CANCELLED: |
251 PinchEnd(event, point, gestures.get()); | 237 PinchEnd(event, point, gestures.get()); |
252 | 238 |
253 // Once pinch ends, it should still be possible to scroll with the | 239 // Once pinch ends, it should still be possible to scroll with the |
254 // remaining finger on the screen. | 240 // remaining finger on the screen. |
255 scroll_type_ = ST_FREE; | 241 scroll_type_ = ST_FREE; |
256 set_state(GS_SCROLL); | 242 set_state(GS_SCROLL); |
257 break; | 243 break; |
258 } | 244 } |
259 | 245 |
260 if (state_ != last_state) | 246 if (state_ != last_state) |
261 VLOG(4) << "Gesture Sequence" | 247 VLOG(4) << "Gesture Sequence" |
262 << " State: " << state_ | 248 << " State: " << state_ |
263 << " touch id: " << event.touch_id(); | 249 << " touch id: " << event.touch_id(); |
264 | 250 |
265 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) | 251 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) |
266 long_press_timer_->Stop(); | 252 long_press_timer_->Stop(); |
267 | 253 |
268 if (event.type() == ui::ET_TOUCH_RELEASED) | 254 // The set of point_ids must be contiguous and include 0. |
| 255 // When a touch point is released, all points with ids greater than the |
| 256 // released point must have their ids decremented, or the set of point_ids |
| 257 // could end up with gaps. |
| 258 if (event.type() == ui::ET_TOUCH_RELEASED) { |
| 259 GesturePoint& old_point = points_[event.touch_id()]; |
| 260 for (int i = 0; i < kMaxGesturePoints; ++i) { |
| 261 GesturePoint& point = points_[i]; |
| 262 if (point.point_id() > old_point.point_id()) |
| 263 point.set_point_id(point.point_id() - 1); |
| 264 } |
| 265 old_point.Reset(); |
269 --point_count_; | 266 --point_count_; |
| 267 } |
270 | 268 |
271 return gestures.release(); | 269 return gestures.release(); |
272 } | 270 } |
273 | 271 |
274 void GestureSequence::Reset() { | 272 void GestureSequence::Reset() { |
275 set_state(GS_NO_GESTURE); | 273 set_state(GS_NO_GESTURE); |
276 for (int i = 0; i < point_count_; ++i) | 274 for (int i = 0; i < kMaxGesturePoints; ++i) |
277 points_[i].Reset(); | 275 points_[i].Reset(); |
278 } | 276 } |
279 | 277 |
280 //////////////////////////////////////////////////////////////////////////////// | 278 //////////////////////////////////////////////////////////////////////////////// |
281 // GestureSequence Protected: | 279 // GestureSequence Protected: |
282 | 280 |
283 base::OneShotTimer<GestureSequence>* GestureSequence::CreateTimer() { | 281 base::OneShotTimer<GestureSequence>* GestureSequence::CreateTimer() { |
284 return new base::OneShotTimer<GestureSequence>(); | 282 return new base::OneShotTimer<GestureSequence>(); |
285 } | 283 } |
286 | 284 |
287 //////////////////////////////////////////////////////////////////////////////// | 285 //////////////////////////////////////////////////////////////////////////////// |
288 // GestureSequence Private: | 286 // GestureSequence Private: |
289 | 287 |
290 GesturePoint& GestureSequence::GesturePointForEvent( | 288 GesturePoint& GestureSequence::GesturePointForEvent( |
291 const TouchEvent& event) { | 289 const TouchEvent& event) { |
292 return points_[event.touch_id()]; | 290 return points_[event.touch_id()]; |
293 } | 291 } |
294 | 292 |
| 293 GesturePoint* GestureSequence::GetPointByPointId(int point_id) { |
| 294 DCHECK(0 <= point_id && point_id < kMaxGesturePoints); |
| 295 for (int i = 0; i < kMaxGesturePoints; ++i) { |
| 296 GesturePoint& point = points_[i]; |
| 297 if (point.in_use() && point.point_id() == point_id) |
| 298 return &point; |
| 299 } |
| 300 NOTREACHED(); |
| 301 return NULL; |
| 302 } |
| 303 |
295 void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, | 304 void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, |
296 Gestures* gestures) { | 305 Gestures* gestures) { |
297 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( | 306 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
298 ui::ET_GESTURE_TAP_DOWN, | 307 ui::ET_GESTURE_TAP_DOWN, |
299 point.first_touch_position().x(), | 308 point.first_touch_position().x(), |
300 point.first_touch_position().y(), | 309 point.first_touch_position().y(), |
301 flags_, | 310 flags_, |
302 base::Time::FromDoubleT(point.last_touch_time()), | 311 base::Time::FromDoubleT(point.last_touch_time()), |
303 0.f, 0.f))); | 312 0.f, 0.f))); |
304 } | 313 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 AppendTapDownGestureEvent(point, gestures); | 484 AppendTapDownGestureEvent(point, gestures); |
476 long_press_timer_->Start( | 485 long_press_timer_->Start( |
477 FROM_HERE, | 486 FROM_HERE, |
478 base::TimeDelta::FromMilliseconds(kLongPressTimeInMilliseconds), | 487 base::TimeDelta::FromMilliseconds(kLongPressTimeInMilliseconds), |
479 this, | 488 this, |
480 &GestureSequence::AppendLongPressGestureEvent); | 489 &GestureSequence::AppendLongPressGestureEvent); |
481 return true; | 490 return true; |
482 } | 491 } |
483 | 492 |
484 void GestureSequence::AppendLongPressGestureEvent() { | 493 void GestureSequence::AppendLongPressGestureEvent() { |
485 // TODO(tdresser) - this may not always be the first point | 494 const GesturePoint* point = GetPointByPointId(0); |
486 const GesturePoint& point = points_[0]; | |
487 GestureEvent* gesture = new GestureEvent( | 495 GestureEvent* gesture = new GestureEvent( |
488 ui::ET_GESTURE_LONG_PRESS, | 496 ui::ET_GESTURE_LONG_PRESS, |
489 point.first_touch_position().x(), | 497 point->first_touch_position().x(), |
490 point.first_touch_position().y(), | 498 point->first_touch_position().y(), |
491 flags_, | 499 flags_, |
492 base::Time::FromDoubleT(point.last_touch_time()), | 500 base::Time::FromDoubleT(point->last_touch_time()), |
493 point.touch_id(), 0.f); | 501 point->point_id(), 0.f); |
494 | |
495 root_window_->DispatchGestureEvent(gesture); | 502 root_window_->DispatchGestureEvent(gesture); |
496 } | 503 } |
497 | 504 |
498 bool GestureSequence::ScrollEnd(const TouchEvent& event, | 505 bool GestureSequence::ScrollEnd(const TouchEvent& event, |
499 GesturePoint& point, Gestures* gestures) { | 506 GesturePoint& point, Gestures* gestures) { |
500 DCHECK(state_ == GS_SCROLL); | 507 DCHECK(state_ == GS_SCROLL); |
501 if (point.IsInFlickWindow(event)) { | 508 if (point.IsInFlickWindow(event)) { |
502 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, | 509 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, |
503 point.XVelocity(), point.YVelocity()); | 510 point.XVelocity(), point.YVelocity()); |
504 } else { | 511 } else { |
505 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, | 512 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, |
506 0.f, 0.f); | 513 0.f, 0.f); |
507 } | 514 } |
508 return true; | 515 return true; |
509 } | 516 } |
510 | 517 |
511 bool GestureSequence::PinchStart(const TouchEvent& event, | 518 bool GestureSequence::PinchStart(const TouchEvent& event, |
512 const GesturePoint& point, Gestures* gestures) { | 519 const GesturePoint& point, Gestures* gestures) { |
513 DCHECK(state_ == GS_SCROLL || | 520 DCHECK(state_ == GS_SCROLL || |
514 state_ == GS_PENDING_SYNTHETIC_CLICK); | 521 state_ == GS_PENDING_SYNTHETIC_CLICK); |
515 AppendTapDownGestureEvent(point, gestures); | 522 AppendTapDownGestureEvent(point, gestures); |
516 | 523 |
517 pinch_distance_current_ = points_[0].Distance(points_[1]); | 524 const GesturePoint* point1 = GetPointByPointId(0); |
| 525 const GesturePoint* point2 = GetPointByPointId(1); |
| 526 |
| 527 pinch_distance_current_ = point1->Distance(*point2); |
518 pinch_distance_start_ = pinch_distance_current_; | 528 pinch_distance_start_ = pinch_distance_current_; |
519 AppendPinchGestureBegin(points_[0], points_[1], gestures); | 529 AppendPinchGestureBegin(*point1, *point2, gestures); |
520 | 530 |
521 if (state_ == GS_PENDING_SYNTHETIC_CLICK) { | 531 if (state_ == GS_PENDING_SYNTHETIC_CLICK) { |
522 gfx::Point center = points_[0].last_touch_position().Middle( | 532 gfx::Point center = point1->last_touch_position().Middle( |
523 points_[1].last_touch_position()); | 533 point2->last_touch_position()); |
524 AppendScrollGestureBegin(point, center, gestures); | 534 AppendScrollGestureBegin(point, center, gestures); |
525 } | 535 } |
526 | 536 |
527 return true; | 537 return true; |
528 } | 538 } |
529 | 539 |
530 bool GestureSequence::PinchUpdate(const TouchEvent& event, | 540 bool GestureSequence::PinchUpdate(const TouchEvent& event, |
531 const GesturePoint& point, Gestures* gestures) { | 541 const GesturePoint& point, Gestures* gestures) { |
532 DCHECK(state_ == GS_PINCH); | 542 DCHECK(state_ == GS_PINCH); |
533 float distance = points_[0].Distance(points_[1]); | 543 |
| 544 const GesturePoint* point1 = GetPointByPointId(0); |
| 545 const GesturePoint* point2 = GetPointByPointId(1); |
| 546 |
| 547 float distance = point1->Distance(*point2); |
534 if (abs(distance - pinch_distance_current_) < | 548 if (abs(distance - pinch_distance_current_) < |
535 GestureConfiguration::minimum_pinch_update_distance_in_pixels()) { | 549 GestureConfiguration::minimum_pinch_update_distance_in_pixels()) { |
536 // The fingers didn't move towards each other, or away from each other, | 550 // The fingers didn't move towards each other, or away from each other, |
537 // enough to constitute a pinch. But perhaps they moved enough in the same | 551 // enough to constitute a pinch. But perhaps they moved enough in the same |
538 // direction to do a two-finger scroll. | 552 // direction to do a two-finger scroll. |
539 if (!points_[0].DidScroll(event, | 553 if (!point1->DidScroll(event, |
540 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) || | 554 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) || |
541 !points_[1].DidScroll(event, | 555 !point2->DidScroll(event, |
542 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels())) | 556 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels())) |
543 return false; | 557 return false; |
544 | 558 |
545 gfx::Point center = points_[0].last_touch_position().Middle( | 559 gfx::Point center = point1->last_touch_position().Middle( |
546 points_[1].last_touch_position()); | 560 point2->last_touch_position()); |
547 AppendScrollGestureUpdate(point, center, gestures); | 561 AppendScrollGestureUpdate(point, center, gestures); |
548 } else { | 562 } else { |
549 AppendPinchGestureUpdate(points_[0], points_[1], | 563 AppendPinchGestureUpdate(*point1, *point2, |
550 distance / pinch_distance_current_, gestures); | 564 distance / pinch_distance_current_, gestures); |
551 pinch_distance_current_ = distance; | 565 pinch_distance_current_ = distance; |
552 } | 566 } |
553 return true; | 567 return true; |
554 } | 568 } |
555 | 569 |
556 bool GestureSequence::PinchEnd(const TouchEvent& event, | 570 bool GestureSequence::PinchEnd(const TouchEvent& event, |
557 const GesturePoint& point, Gestures* gestures) { | 571 const GesturePoint& point, Gestures* gestures) { |
558 DCHECK(state_ == GS_PINCH); | 572 DCHECK(state_ == GS_PINCH); |
559 float distance = points_[0].Distance(points_[1]); | 573 |
560 AppendPinchGestureEnd(points_[0], points_[1], | 574 const GesturePoint* point1 = GetPointByPointId(0); |
| 575 const GesturePoint* point2 = GetPointByPointId(1); |
| 576 |
| 577 float distance = point1->Distance(*point2); |
| 578 AppendPinchGestureEnd(*point1, *point2, |
561 distance / pinch_distance_start_, gestures); | 579 distance / pinch_distance_start_, gestures); |
562 | 580 |
563 pinch_distance_start_ = 0; | 581 pinch_distance_start_ = 0; |
564 pinch_distance_current_ = 0; | 582 pinch_distance_current_ = 0; |
565 return true; | 583 return true; |
566 } | 584 } |
567 | 585 |
568 } // namespace aura | 586 } // namespace aura |
OLD | NEW |