Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: ui/aura/gestures/gesture_sequence.cc

Issue 9452024: Gestures are now possible using touch events with any ids (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Allow consecutive touch presses with the same touch-id. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698