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

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

Issue 10834283: gesture recognizer: Some cleanup and workaround for a crash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « ui/base/gestures/gesture_sequence.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/base/gestures/gesture_sequence.h" 5 #include "ui/base/gestures/gesture_sequence.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 291
292 // Set a limit on the number of simultaneous touches in a gesture. 292 // Set a limit on the number of simultaneous touches in a gesture.
293 if (event.touch_id() >= kMaxGesturePoints) 293 if (event.touch_id() >= kMaxGesturePoints)
294 return NULL; 294 return NULL;
295 295
296 if (event.type() == ui::ET_TOUCH_PRESSED) { 296 if (event.type() == ui::ET_TOUCH_PRESSED) {
297 if (point_count_ == kMaxGesturePoints) 297 if (point_count_ == kMaxGesturePoints)
298 return NULL; 298 return NULL;
299 GesturePoint* new_point = &points_[event.touch_id()]; 299 GesturePoint* new_point = &points_[event.touch_id()];
300 // We shouldn't be able to get two PRESSED events from the same 300 // We shouldn't be able to get two PRESSED events from the same
301 // finger without either a RELEASE or CANCEL in between. 301 // finger without either a RELEASE or CANCEL in between. But let's not crash
302 DCHECK(!new_point->in_use()); 302 // in a release build.
303 if (new_point->in_use()) {
304 LOG(ERROR) << "Received a second press for a point: " << event.touch_id();
305 new_point->ResetVelocity();
306 new_point->UpdateValues(event);
307 return NULL;
308 }
303 new_point->set_point_id(point_count_++); 309 new_point->set_point_id(point_count_++);
304 new_point->set_touch_id(event.touch_id()); 310 new_point->set_touch_id(event.touch_id());
305 } 311 }
306 312
307 GestureState last_state = state_; 313 GestureState last_state = state_;
308 314
309 // NOTE: when modifying these state transitions, also update gestures.dot 315 // NOTE: when modifying these state transitions, also update gestures.dot
310 scoped_ptr<Gestures> gestures(new Gestures()); 316 scoped_ptr<Gestures> gestures(new Gestures());
311 GesturePoint& point = GesturePointForEvent(event); 317 GesturePoint& point = GesturePointForEvent(event);
312 point.UpdateValues(event); 318 point.UpdateValues(event);
313 RecreateBoundingBox(); 319 RecreateBoundingBox();
314 flags_ = event.flags(); 320 flags_ = event.flags();
315 const int point_id = points_[event.touch_id()].point_id(); 321 const int point_id = points_[event.touch_id()].point_id();
varunjain 2012/08/13 20:40:44 also change this to point.point_id()?
sadrul 2012/08/13 20:43:55 Good point. Done.
316 if (point_id < 0) 322 if (point_id < 0)
317 return NULL; 323 return NULL;
318 324
319 // Send GESTURE_BEGIN for any touch pressed. 325 // Send GESTURE_BEGIN for any touch pressed.
320 if (event.type() == ui::ET_TOUCH_PRESSED) 326 if (event.type() == ui::ET_TOUCH_PRESSED)
321 AppendBeginGestureEvent(point, gestures.get()); 327 AppendBeginGestureEvent(point, gestures.get());
322 328
323 TouchStatusInternal status_internal = (status == ui::TOUCH_STATUS_UNKNOWN) ? 329 TouchStatusInternal status_internal = (status == ui::TOUCH_STATUS_UNKNOWN) ?
324 TSI_NOT_PROCESSED : TSI_PROCESSED; 330 TSI_NOT_PROCESSED : TSI_PROCESSED;
325 331
(...skipping 18 matching lines...) Expand all
344 break; 350 break;
345 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED: 351 case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED:
346 case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY: 352 case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY:
347 if (ScrollStart(event, point, gestures.get())) { 353 if (ScrollStart(event, point, gestures.get())) {
348 set_state(GS_SCROLL); 354 set_state(GS_SCROLL);
349 if (ScrollUpdate(event, point, gestures.get())) 355 if (ScrollUpdate(event, point, gestures.get()))
350 point.UpdateForScroll(); 356 point.UpdateForScroll();
351 } 357 }
352 break; 358 break;
353 case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED: 359 case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED:
354 NoGesture(event, point, gestures.get()); 360 set_state(GS_NO_GESTURE);
355 break; 361 break;
356 case GST_SCROLL_FIRST_MOVED: 362 case GST_SCROLL_FIRST_MOVED:
357 if (scroll_type_ == ST_VERTICAL || 363 if (scroll_type_ == ST_VERTICAL ||
358 scroll_type_ == ST_HORIZONTAL) 364 scroll_type_ == ST_HORIZONTAL)
359 BreakRailScroll(event, point, gestures.get()); 365 BreakRailScroll(event, point, gestures.get());
360 if (ScrollUpdate(event, point, gestures.get())) 366 if (ScrollUpdate(event, point, gestures.get()))
361 point.UpdateForScroll(); 367 point.UpdateForScroll();
362 break; 368 break;
363 case GST_SCROLL_FIRST_RELEASED: 369 case GST_SCROLL_FIRST_RELEASED:
364 case GST_SCROLL_FIRST_CANCELLED: 370 case GST_SCROLL_FIRST_CANCELLED:
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 457
452 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) 458 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state)
453 long_press_timer_->Stop(); 459 long_press_timer_->Stop();
454 460
455 // The set of point_ids must be contiguous and include 0. 461 // The set of point_ids must be contiguous and include 0.
456 // When a touch point is released, all points with ids greater than the 462 // When a touch point is released, all points with ids greater than the
457 // released point must have their ids decremented, or the set of point_ids 463 // released point must have their ids decremented, or the set of point_ids
458 // could end up with gaps. 464 // could end up with gaps.
459 if (event.type() == ui::ET_TOUCH_RELEASED || 465 if (event.type() == ui::ET_TOUCH_RELEASED ||
460 event.type() == ui::ET_TOUCH_CANCELLED) { 466 event.type() == ui::ET_TOUCH_CANCELLED) {
461 GesturePoint& old_point = points_[event.touch_id()];
462 for (int i = 0; i < kMaxGesturePoints; ++i) { 467 for (int i = 0; i < kMaxGesturePoints; ++i) {
463 GesturePoint& point = points_[i]; 468 GesturePoint& iter_point = points_[i];
464 if (point.point_id() > old_point.point_id()) 469 if (iter_point.point_id() > point.point_id())
465 point.set_point_id(point.point_id() - 1); 470 iter_point.set_point_id(iter_point.point_id() - 1);
466 } 471 }
467 472
468 if (old_point.in_use()) { 473 point.Reset();
469 old_point.Reset(); 474 --point_count_;
470 --point_count_; 475 CHECK_GE(point_count_, 0);
471 DCHECK_GE(point_count_, 0); 476 RecreateBoundingBox();
472 RecreateBoundingBox(); 477 if (state_ == GS_PINCH) {
473 if (state_ == GS_PINCH) { 478 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_);
474 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_); 479 pinch_distance_start_ = pinch_distance_current_;
475 pinch_distance_start_ = pinch_distance_current_;
476 }
477 } 480 }
478 } 481 }
479
480 return gestures.release(); 482 return gestures.release();
481 } 483 }
482 484
483 void GestureSequence::Reset() {
484 set_state(GS_NO_GESTURE);
485 for (int i = 0; i < kMaxGesturePoints; ++i)
486 points_[i].Reset();
487 point_count_ = 0;
488 }
489
490 void GestureSequence::RecreateBoundingBox() { 485 void GestureSequence::RecreateBoundingBox() {
491 // TODO(sad): Recreating the bounding box at every touch-event is not very 486 // TODO(sad): Recreating the bounding box at every touch-event is not very
492 // efficient. This should be made better. 487 // efficient. This should be made better.
493 int left = INT_MAX, top = INT_MAX, right = INT_MIN, bottom = INT_MIN; 488 int left = INT_MAX, top = INT_MAX, right = INT_MIN, bottom = INT_MIN;
494 for (int i = 0; i < kMaxGesturePoints; ++i) { 489 for (int i = 0; i < kMaxGesturePoints; ++i) {
495 if (!points_[i].in_use()) 490 if (!points_[i].in_use())
496 continue; 491 continue;
497 gfx::Rect rect = points_[i].enclosing_rectangle(); 492 gfx::Rect rect = points_[i].enclosing_rectangle();
498 if (left > rect.x()) 493 if (left > rect.x())
499 left = rect.x(); 494 left = rect.x();
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 788
794 bool GestureSequence::ScrollUpdate(const TouchEvent& event, 789 bool GestureSequence::ScrollUpdate(const TouchEvent& event,
795 const GesturePoint& point, Gestures* gestures) { 790 const GesturePoint& point, Gestures* gestures) {
796 DCHECK(state_ == GS_SCROLL); 791 DCHECK(state_ == GS_SCROLL);
797 if (!point.DidScroll(event, 0)) 792 if (!point.DidScroll(event, 0))
798 return false; 793 return false;
799 AppendScrollGestureUpdate(point, point.last_touch_position(), gestures); 794 AppendScrollGestureUpdate(point, point.last_touch_position(), gestures);
800 return true; 795 return true;
801 } 796 }
802 797
803 bool GestureSequence::NoGesture(const TouchEvent&,
804 const GesturePoint& point, Gestures*) {
805 Reset();
806 return false;
807 }
808
809 bool GestureSequence::TouchDown(const TouchEvent& event, 798 bool GestureSequence::TouchDown(const TouchEvent& event,
810 const GesturePoint& point, Gestures* gestures) { 799 const GesturePoint& point, Gestures* gestures) {
811 DCHECK(state_ == GS_NO_GESTURE); 800 DCHECK(state_ == GS_NO_GESTURE);
812 AppendTapDownGestureEvent(point, gestures); 801 AppendTapDownGestureEvent(point, gestures);
813 long_press_timer_->Start( 802 long_press_timer_->Start(
814 FROM_HERE, 803 FROM_HERE,
815 base::TimeDelta::FromMilliseconds( 804 base::TimeDelta::FromMilliseconds(
816 GestureConfiguration::long_press_time_in_seconds() * 1000), 805 GestureConfiguration::long_press_time_in_seconds() * 1000),
817 this, 806 this,
818 &GestureSequence::AppendLongPressGestureEvent); 807 &GestureSequence::AppendLongPressGestureEvent);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 return; 1017 return;
1029 1018
1030 // Since long press timer has been started, there should be a non-NULL point. 1019 // Since long press timer has been started, there should be a non-NULL point.
1031 const GesturePoint* point = GetPointByPointId(0); 1020 const GesturePoint* point = GetPointByPointId(0);
1032 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(), 1021 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(),
1033 event.location())) 1022 event.location()))
1034 long_press_timer_->Stop(); 1023 long_press_timer_->Stop();
1035 } 1024 }
1036 1025
1037 } // namespace ui 1026 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/gestures/gesture_sequence.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698