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

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: Created 8 years, 10 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"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 //////////////////////////////////////////////////////////////////////////////// 156 ////////////////////////////////////////////////////////////////////////////////
157 // GestureSequence Public: 157 // GestureSequence Public:
158 158
159 GestureSequence::GestureSequence() 159 GestureSequence::GestureSequence()
160 : state_(GS_NO_GESTURE), 160 : state_(GS_NO_GESTURE),
161 flags_(0), 161 flags_(0),
162 pinch_distance_start_(0.f), 162 pinch_distance_start_(0.f),
163 pinch_distance_current_(0.f), 163 pinch_distance_current_(0.f),
164 long_press_timer_(CreateTimer()), 164 long_press_timer_(CreateTimer()),
165 point_count_(0) { 165 point_count_(0) {
166 for (int i = 0; i < kMaxGesturePoints; ++i) {
167 points_[i].set_touch_id(i);
168 }
169 } 166 }
170 167
171 GestureSequence::~GestureSequence() { 168 GestureSequence::~GestureSequence() {
172 } 169 }
173 170
174 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( 171 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
175 const TouchEvent& event, 172 const TouchEvent& event,
176 ui::TouchStatus status) { 173 ui::TouchStatus status) {
177 if (status != ui::TOUCH_STATUS_UNKNOWN) 174 if (status != ui::TOUCH_STATUS_UNKNOWN)
178 return NULL; // The event was consumed by a touch sequence. 175 return NULL; // The event was consumed by a touch sequence.
179 176
180 // Set a limit on the number of simultaneous touches in a gesture. 177 // Set a limit on the number of simultaneous touches in a gesture.
181 if (event.touch_id() >= kMaxGesturePoints) 178 if (event.touch_id() >= kMaxGesturePoints)
182 return NULL; 179 return NULL;
183 180
184 if (event.type() == ui::ET_TOUCH_PRESSED) { 181 if (event.type() == ui::ET_TOUCH_PRESSED) {
185 if (point_count_ == kMaxGesturePoints) 182 if (point_count_ == kMaxGesturePoints)
186 return NULL; 183 return NULL;
187 ++point_count_; 184 GesturePoint* new_point = &points_[event.touch_id()];
185 // We shouldn't be able to get two PRESSED events, without a RELEASE
186 DCHECK(!points_[event.touch_id()].in_use());
187 new_point->use();
188 new_point->set_point_id(point_count_++);
189 } else {
190 // Make sure the point we're modifying was PRESSED at some point in the past
191 DCHECK(points_[event.touch_id()].in_use());
188 } 192 }
189 193
190 GestureState last_state = state_; 194 GestureState last_state = state_;
191 195
192 // NOTE: when modifying these state transitions, also update gestures.dot 196 // NOTE: when modifying these state transitions, also update gestures.dot
193 scoped_ptr<Gestures> gestures(new Gestures()); 197 scoped_ptr<Gestures> gestures(new Gestures());
194 GesturePoint& point = GesturePointForEvent(event); 198 GesturePoint& point = GesturePointForEvent(event);
195 point.UpdateValues(event); 199 point.UpdateValues(event);
196 flags_ = event.flags(); 200 flags_ = event.flags();
197 switch (Signature(state_, event.touch_id(), event.type(), false)) { 201 const int point_id = points_[event.touch_id()].point_id();
202 switch (Signature(state_, point_id, event.type(), false)) {
198 case GST_NO_GESTURE_FIRST_PRESSED: 203 case GST_NO_GESTURE_FIRST_PRESSED:
199 TouchDown(event, point, gestures.get()); 204 TouchDown(event, point, gestures.get());
200 set_state(GS_PENDING_SYNTHETIC_CLICK); 205 set_state(GS_PENDING_SYNTHETIC_CLICK);
201 break; 206 break;
202 case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED: 207 case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED:
203 if (Click(event, point, gestures.get())) 208 if (Click(event, point, gestures.get()))
204 point.UpdateForTap(); 209 point.UpdateForTap();
205 set_state(GS_NO_GESTURE); 210 set_state(GS_NO_GESTURE);
206 break; 211 break;
207 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED: 212 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 262 }
258 263
259 if (state_ != last_state) 264 if (state_ != last_state)
260 VLOG(4) << "Gesture Sequence" 265 VLOG(4) << "Gesture Sequence"
261 << " State: " << state_ 266 << " State: " << state_
262 << " touch id: " << event.touch_id(); 267 << " touch id: " << event.touch_id();
263 268
264 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) 269 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state)
265 long_press_timer_->Stop(); 270 long_press_timer_->Stop();
266 271
267 if (event.type() == ui::ET_TOUCH_RELEASED) 272 if (event.type() == ui::ET_TOUCH_RELEASED) {
rjkroege 2012/02/23 19:39:45 I am unclear why you are doing this. Can you expla
tdresser 2012/02/23 20:13:07 See comments.
273 GesturePoint& old_point = points_[event.touch_id()];
274 for (int i = 0; i < kMaxGesturePoints; ++i) {
275 GesturePoint& point = points_[i];
276 if (point.point_id() > old_point.point_id())
277 point.set_point_id(point.point_id() - 1);
278 }
279 old_point.Reset();
268 --point_count_; 280 --point_count_;
281 }
269 282
270 return gestures.release(); 283 return gestures.release();
271 } 284 }
272 285
273 void GestureSequence::Reset() { 286 void GestureSequence::Reset() {
274 set_state(GS_NO_GESTURE); 287 set_state(GS_NO_GESTURE);
275 for (int i = 0; i < point_count_; ++i) 288 for (int i = 0; i < kMaxGesturePoints; ++i)
276 points_[i].Reset(); 289 points_[i].Reset();
277 } 290 }
278 291
279 //////////////////////////////////////////////////////////////////////////////// 292 ////////////////////////////////////////////////////////////////////////////////
280 // GestureSequence Protected: 293 // GestureSequence Protected:
281 294
282 base::OneShotTimer<GestureSequence>* GestureSequence::CreateTimer() { 295 base::OneShotTimer<GestureSequence>* GestureSequence::CreateTimer() {
283 return new base::OneShotTimer<GestureSequence>(); 296 return new base::OneShotTimer<GestureSequence>();
284 } 297 }
285 298
286 //////////////////////////////////////////////////////////////////////////////// 299 ////////////////////////////////////////////////////////////////////////////////
287 // GestureSequence Private: 300 // GestureSequence Private:
288 301
289 GesturePoint& GestureSequence::GesturePointForEvent( 302 GesturePoint& GestureSequence::GesturePointForEvent(
290 const TouchEvent& event) { 303 const TouchEvent& event) {
291 return points_[event.touch_id()]; 304 return points_[event.touch_id()];
292 } 305 }
293 306
307 GesturePoint* GestureSequence::GetPointByPointId(int point_id) {
rjkroege 2012/02/23 19:39:45 can't we preserve the radix lookup. you are mainta
tdresser 2012/02/23 20:13:07 I believe that maintaining a second table would en
308 DCHECK(0 <= point_id && point_id < kMaxGesturePoints);
309 for (int i = 0; i < kMaxGesturePoints; ++i) {
310 GesturePoint& point = points_[i];
311 if (point.in_use() && point.point_id() == point_id)
312 return &point;
313 }
314 DCHECK(false);
315 return NULL;
316 }
317
294 void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, 318 void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point,
295 Gestures* gestures) { 319 Gestures* gestures) {
296 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( 320 gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent(
297 ui::ET_GESTURE_TAP_DOWN, 321 ui::ET_GESTURE_TAP_DOWN,
298 point.first_touch_position().x(), 322 point.first_touch_position().x(),
299 point.first_touch_position().y(), 323 point.first_touch_position().y(),
300 flags_, 324 flags_,
301 base::Time::FromDoubleT(point.last_touch_time()), 325 base::Time::FromDoubleT(point.last_touch_time()),
302 0.f, 0.f))); 326 0.f, 0.f)));
303 } 327 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 AppendTapDownGestureEvent(point, gestures); 498 AppendTapDownGestureEvent(point, gestures);
475 long_press_timer_->Start( 499 long_press_timer_->Start(
476 FROM_HERE, 500 FROM_HERE,
477 base::TimeDelta::FromMilliseconds(kLongPressTimeInMilliseconds), 501 base::TimeDelta::FromMilliseconds(kLongPressTimeInMilliseconds),
478 this, 502 this,
479 &GestureSequence::AppendLongPressGestureEvent); 503 &GestureSequence::AppendLongPressGestureEvent);
480 return true; 504 return true;
481 } 505 }
482 506
483 void GestureSequence::AppendLongPressGestureEvent() { 507 void GestureSequence::AppendLongPressGestureEvent() {
484 // TODO(tdresser) - this may not always be the first point 508 const GesturePoint* point = GetPointByPointId(0);
485 const GesturePoint& point = points_[0]; 509 DCHECK(point);
486 GestureEvent* gesture = new GestureEvent( 510 GestureEvent* gesture = new GestureEvent(
487 ui::ET_GESTURE_LONG_PRESS, 511 ui::ET_GESTURE_LONG_PRESS,
488 point.first_touch_position().x(), 512 point->first_touch_position().x(),
489 point.first_touch_position().y(), 513 point->first_touch_position().y(),
490 flags_, 514 flags_,
491 base::Time::FromDoubleT(point.last_touch_time()), 515 base::Time::FromDoubleT(point->last_touch_time()),
492 point.touch_id(), 0.f); 516 point->point_id(), 0.f);
493
494 RootWindow::GetInstance()->DispatchGestureEvent(gesture); 517 RootWindow::GetInstance()->DispatchGestureEvent(gesture);
495 } 518 }
496 519
497 bool GestureSequence::ScrollEnd(const TouchEvent& event, 520 bool GestureSequence::ScrollEnd(const TouchEvent& event,
498 GesturePoint& point, Gestures* gestures) { 521 GesturePoint& point, Gestures* gestures) {
499 DCHECK(state_ == GS_SCROLL); 522 DCHECK(state_ == GS_SCROLL);
500 if (point.IsInFlickWindow(event)) { 523 if (point.IsInFlickWindow(event)) {
501 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, 524 AppendScrollGestureEnd(point, point.last_touch_position(), gestures,
502 point.XVelocity(), point.YVelocity()); 525 point.XVelocity(), point.YVelocity());
503 } else { 526 } else {
504 AppendScrollGestureEnd(point, point.last_touch_position(), gestures, 527 AppendScrollGestureEnd(point, point.last_touch_position(), gestures,
505 0.f, 0.f); 528 0.f, 0.f);
506 } 529 }
507 return true; 530 return true;
508 } 531 }
509 532
510 bool GestureSequence::PinchStart(const TouchEvent& event, 533 bool GestureSequence::PinchStart(const TouchEvent& event,
511 const GesturePoint& point, Gestures* gestures) { 534 const GesturePoint& point, Gestures* gestures) {
512 DCHECK(state_ == GS_SCROLL || 535 DCHECK(state_ == GS_SCROLL ||
513 state_ == GS_PENDING_SYNTHETIC_CLICK); 536 state_ == GS_PENDING_SYNTHETIC_CLICK);
514 AppendTapDownGestureEvent(point, gestures); 537 AppendTapDownGestureEvent(point, gestures);
515 538
516 pinch_distance_current_ = points_[0].Distance(points_[1]); 539 const GesturePoint* point1 = GetPointByPointId(0);
540 const GesturePoint* point2 = GetPointByPointId(1);
541
542 pinch_distance_current_ = point1->Distance(*point2);
517 pinch_distance_start_ = pinch_distance_current_; 543 pinch_distance_start_ = pinch_distance_current_;
518 AppendPinchGestureBegin(points_[0], points_[1], gestures); 544 AppendPinchGestureBegin(*point1, *point2, gestures);
519 545
520 if (state_ == GS_PENDING_SYNTHETIC_CLICK) { 546 if (state_ == GS_PENDING_SYNTHETIC_CLICK) {
521 gfx::Point center = points_[0].last_touch_position().Middle( 547 gfx::Point center = point1->last_touch_position().Middle(
522 points_[1].last_touch_position()); 548 point2->last_touch_position());
523 AppendScrollGestureBegin(point, center, gestures); 549 AppendScrollGestureBegin(point, center, gestures);
524 } 550 }
525 551
526 return true; 552 return true;
527 } 553 }
528 554
529 bool GestureSequence::PinchUpdate(const TouchEvent& event, 555 bool GestureSequence::PinchUpdate(const TouchEvent& event,
530 const GesturePoint& point, Gestures* gestures) { 556 const GesturePoint& point, Gestures* gestures) {
531 DCHECK(state_ == GS_PINCH); 557 DCHECK(state_ == GS_PINCH);
532 float distance = points_[0].Distance(points_[1]); 558
559 const GesturePoint* point1 = GetPointByPointId(0);
560 const GesturePoint* point2 = GetPointByPointId(1);
561
562 float distance = point1->Distance(*point2);
533 if (abs(distance - pinch_distance_current_) < 563 if (abs(distance - pinch_distance_current_) <
534 GestureConfiguration::minimum_pinch_update_distance_in_pixels()) { 564 GestureConfiguration::minimum_pinch_update_distance_in_pixels()) {
535 // The fingers didn't move towards each other, or away from each other, 565 // 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 566 // enough to constitute a pinch. But perhaps they moved enough in the same
537 // direction to do a two-finger scroll. 567 // direction to do a two-finger scroll.
538 if (!points_[0].DidScroll(event, 568 if (!point1->DidScroll(event,
539 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) || 569 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) ||
540 !points_[1].DidScroll(event, 570 !point2->DidScroll(event,
541 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels())) 571 GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()))
542 return false; 572 return false;
543 573
544 gfx::Point center = points_[0].last_touch_position().Middle( 574 gfx::Point center = point1->last_touch_position().Middle(
545 points_[1].last_touch_position()); 575 point2->last_touch_position());
546 AppendScrollGestureUpdate(point, center, gestures); 576 AppendScrollGestureUpdate(point, center, gestures);
547 } else { 577 } else {
548 AppendPinchGestureUpdate(points_[0], points_[1], 578 AppendPinchGestureUpdate(*point1, *point2,
549 distance / pinch_distance_current_, gestures); 579 distance / pinch_distance_current_, gestures);
550 pinch_distance_current_ = distance; 580 pinch_distance_current_ = distance;
551 } 581 }
552 return true; 582 return true;
553 } 583 }
554 584
555 bool GestureSequence::PinchEnd(const TouchEvent& event, 585 bool GestureSequence::PinchEnd(const TouchEvent& event,
556 const GesturePoint& point, Gestures* gestures) { 586 const GesturePoint& point, Gestures* gestures) {
557 DCHECK(state_ == GS_PINCH); 587 DCHECK(state_ == GS_PINCH);
558 float distance = points_[0].Distance(points_[1]); 588
559 AppendPinchGestureEnd(points_[0], points_[1], 589 const GesturePoint* point1 = GetPointByPointId(0);
590 const GesturePoint* point2 = GetPointByPointId(1);
591
592 float distance = point1->Distance(*point2);
593 AppendPinchGestureEnd(*point1, *point2,
560 distance / pinch_distance_start_, gestures); 594 distance / pinch_distance_start_, gestures);
561 595
562 pinch_distance_start_ = 0; 596 pinch_distance_start_ = 0;
563 pinch_distance_current_ = 0; 597 pinch_distance_current_ = 0;
564 return true; 598 return true;
565 } 599 }
566 600
567 } // namespace aura 601 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698