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