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