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

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

Issue 10937038: gesture recognizer: Recognizer rotation gestures. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 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') | ui/base/gestures/gesture_types.h » ('j') | 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 return signature; 257 return signature;
258 } 258 }
259 #undef G 259 #undef G
260 260
261 float BoundingBoxDiagonal(const gfx::Rect& rect) { 261 float BoundingBoxDiagonal(const gfx::Rect& rect) {
262 float width = rect.width() * rect.width(); 262 float width = rect.width() * rect.width();
263 float height = rect.height() * rect.height(); 263 float height = rect.height() * rect.height();
264 return sqrt(width + height); 264 return sqrt(width + height);
265 } 265 }
266 266
267 float BoundingBoxDiagonalAngle(const gfx::Rect& rect) {
268 float width = rect.width();
269 float height = rect.height();
270 return width == 0.f ? M_PI_2 : atan(height / width);
271 }
272
267 unsigned int ComputeTouchBitmask(const GesturePoint* points) { 273 unsigned int ComputeTouchBitmask(const GesturePoint* points) {
268 unsigned int touch_bitmask = 0; 274 unsigned int touch_bitmask = 0;
269 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) { 275 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) {
270 if (points[i].in_use()) 276 if (points[i].in_use())
271 touch_bitmask |= 1 << points[i].touch_id(); 277 touch_bitmask |= 1 << points[i].touch_id();
272 } 278 }
273 return touch_bitmask; 279 return touch_bitmask;
274 } 280 }
275 281
276 float CalibrateFlingVelocity(float velocity) { 282 float CalibrateFlingVelocity(float velocity) {
277 // TODO(sad|rjkroege): fling-curve is currently configured to work well with 283 // TODO(sad|rjkroege): fling-curve is currently configured to work well with
278 // touchpad scroll-events. This curve needs to be adjusted to work correctly 284 // touchpad scroll-events. This curve needs to be adjusted to work correctly
279 // with both touchpad and touchscreen. Until then, scale quadratically. 285 // with both touchpad and touchscreen. Until then, scale quadratically.
280 // http://crbug.com/120154 286 // http://crbug.com/120154
281 const float velocity_scaling = 287 const float velocity_scaling =
282 GestureConfiguration::touchscreen_fling_acceleration_adjustment(); 288 GestureConfiguration::touchscreen_fling_acceleration_adjustment();
283 return velocity_scaling * velocity; 289 return velocity_scaling * velocity;
284 } 290 }
285 291
286 } // namespace 292 } // namespace
287 293
288 //////////////////////////////////////////////////////////////////////////////// 294 ////////////////////////////////////////////////////////////////////////////////
289 // GestureSequence Public: 295 // GestureSequence Public:
290 296
291 GestureSequence::GestureSequence(GestureEventHelper* helper) 297 GestureSequence::GestureSequence(GestureEventHelper* helper)
292 : state_(GS_NO_GESTURE), 298 : state_(GS_NO_GESTURE),
293 flags_(0), 299 flags_(0),
300 bounding_box_diagonal_angle_(0.f),
294 pinch_distance_start_(0.f), 301 pinch_distance_start_(0.f),
295 pinch_distance_current_(0.f), 302 pinch_distance_current_(0.f),
296 scroll_type_(ST_FREE), 303 scroll_type_(ST_FREE),
297 long_press_timer_(CreateTimer()), 304 long_press_timer_(CreateTimer()),
298 point_count_(0), 305 point_count_(0),
299 helper_(helper) { 306 helper_(helper) {
300 } 307 }
301 308
302 GestureSequence::~GestureSequence() { 309 GestureSequence::~GestureSequence() {
303 } 310 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 // pinch_distance_current_ and pinch_distance_start_ will be updated 474 // pinch_distance_current_ and pinch_distance_start_ will be updated
468 // when the bounding-box is updated. 475 // when the bounding-box is updated.
469 } 476 }
470 ResetVelocities(); 477 ResetVelocities();
471 break; 478 break;
472 case GST_PINCH_THIRD_PRESSED: 479 case GST_PINCH_THIRD_PRESSED:
473 case GST_PINCH_FOURTH_PRESSED: 480 case GST_PINCH_FOURTH_PRESSED:
474 case GST_PINCH_FIFTH_PRESSED: 481 case GST_PINCH_FIFTH_PRESSED:
475 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_); 482 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_);
476 pinch_distance_start_ = pinch_distance_current_; 483 pinch_distance_start_ = pinch_distance_current_;
484 bounding_box_diagonal_angle_ = BoundingBoxDiagonalAngle(bounding_box_);
477 break; 485 break;
478 } 486 }
479 487
480 if (event.type() == ui::ET_TOUCH_RELEASED || 488 if (event.type() == ui::ET_TOUCH_RELEASED ||
481 event.type() == ui::ET_TOUCH_CANCELLED) 489 event.type() == ui::ET_TOUCH_CANCELLED)
482 AppendEndGestureEvent(point, gestures.get()); 490 AppendEndGestureEvent(point, gestures.get());
483 491
484 if (state_ != last_state) 492 if (state_ != last_state)
485 DVLOG(4) << "Gesture Sequence" 493 DVLOG(4) << "Gesture Sequence"
486 << " State: " << state_ 494 << " State: " << state_
(...skipping 14 matching lines...) Expand all
501 iter_point.set_point_id(iter_point.point_id() - 1); 509 iter_point.set_point_id(iter_point.point_id() - 1);
502 } 510 }
503 511
504 point.Reset(); 512 point.Reset();
505 --point_count_; 513 --point_count_;
506 CHECK_GE(point_count_, 0); 514 CHECK_GE(point_count_, 0);
507 RecreateBoundingBox(); 515 RecreateBoundingBox();
508 if (state_ == GS_PINCH) { 516 if (state_ == GS_PINCH) {
509 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_); 517 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_);
510 pinch_distance_start_ = pinch_distance_current_; 518 pinch_distance_start_ = pinch_distance_current_;
519 bounding_box_diagonal_angle_ = BoundingBoxDiagonalAngle(bounding_box_);
511 } 520 }
512 } 521 }
513 return gestures.release(); 522 return gestures.release();
514 } 523 }
515 524
516 void GestureSequence::RecreateBoundingBox() { 525 void GestureSequence::RecreateBoundingBox() {
517 // TODO(sad): Recreating the bounding box at every touch-event is not very 526 // TODO(sad): Recreating the bounding box at every touch-event is not very
518 // efficient. This should be made better. 527 // efficient. This should be made better.
519 int left = INT_MAX, top = INT_MAX, right = INT_MIN, bottom = INT_MIN; 528 int left = INT_MAX, top = INT_MAX, right = INT_MIN, bottom = INT_MIN;
520 for (int i = 0; i < kMaxGesturePoints; ++i) { 529 for (int i = 0; i < kMaxGesturePoints; ++i) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 gestures->push_back(CreateGestureEvent( 754 gestures->push_back(CreateGestureEvent(
746 GestureEventDetails(ui::ET_GESTURE_PINCH_END, 0, 0), 755 GestureEventDetails(ui::ET_GESTURE_PINCH_END, 0, 0),
747 center, 756 center,
748 flags_, 757 flags_,
749 base::Time::FromDoubleT(p1.last_touch_time()), 758 base::Time::FromDoubleT(p1.last_touch_time()),
750 1 << p1.touch_id() | 1 << p2.touch_id())); 759 1 << p1.touch_id() | 1 << p2.touch_id()));
751 } 760 }
752 761
753 void GestureSequence::AppendPinchGestureUpdate(const GesturePoint& point, 762 void GestureSequence::AppendPinchGestureUpdate(const GesturePoint& point,
754 float scale, 763 float scale,
764 float rotation,
755 Gestures* gestures) { 765 Gestures* gestures) {
756 // TODO(sad): Compute rotation and include it in delta_y. 766 // TODO(sad): Compute rotation and include it in delta_y.
757 // http://crbug.com/113145 767 // http://crbug.com/113145
758 gestures->push_back(CreateGestureEvent( 768 gestures->push_back(CreateGestureEvent(
759 GestureEventDetails(ui::ET_GESTURE_PINCH_UPDATE, scale, 0), 769 GestureEventDetails(ui::ET_GESTURE_PINCH_UPDATE, scale, rotation),
760 bounding_box_.CenterPoint(), 770 bounding_box_.CenterPoint(),
761 flags_, 771 flags_,
762 base::Time::FromDoubleT(point.last_touch_time()), 772 base::Time::FromDoubleT(point.last_touch_time()),
763 ComputeTouchBitmask(points_))); 773 ComputeTouchBitmask(points_)));
764 } 774 }
765 775
766 void GestureSequence::AppendSwipeGesture(const GesturePoint& point, 776 void GestureSequence::AppendSwipeGesture(const GesturePoint& point,
767 int swipe_x, 777 int swipe_x,
768 int swipe_y, 778 int swipe_y,
769 Gestures* gestures) { 779 Gestures* gestures) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 state_ == GS_PENDING_TWO_FINGER_TAP); 935 state_ == GS_PENDING_TWO_FINGER_TAP);
926 936
927 // Once pinch starts, we immediately break rail scroll. 937 // Once pinch starts, we immediately break rail scroll.
928 scroll_type_ = ST_FREE; 938 scroll_type_ = ST_FREE;
929 939
930 const GesturePoint* point1 = GetPointByPointId(0); 940 const GesturePoint* point1 = GetPointByPointId(0);
931 const GesturePoint* point2 = GetPointByPointId(1); 941 const GesturePoint* point2 = GetPointByPointId(1);
932 942
933 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_); 943 pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_);
934 pinch_distance_start_ = pinch_distance_current_; 944 pinch_distance_start_ = pinch_distance_current_;
945 bounding_box_diagonal_angle_ = BoundingBoxDiagonalAngle(bounding_box_);
946
935 AppendPinchGestureBegin(*point1, *point2, gestures); 947 AppendPinchGestureBegin(*point1, *point2, gestures);
936 948
937 if (state_ == GS_PENDING_SYNTHETIC_CLICK || 949 if (state_ == GS_PENDING_SYNTHETIC_CLICK ||
938 state_ == GS_PENDING_TWO_FINGER_TAP) { 950 state_ == GS_PENDING_TWO_FINGER_TAP) {
939 gfx::Point center = bounding_box_.CenterPoint(); 951 gfx::Point center = bounding_box_.CenterPoint();
940 AppendScrollGestureBegin(point, center, gestures); 952 AppendScrollGestureBegin(point, center, gestures);
941 } 953 }
942 954
943 return true; 955 return true;
944 } 956 }
(...skipping 16 matching lines...) Expand all
961 break; 973 break;
962 } 974 }
963 975
964 if (!did_scroll) 976 if (!did_scroll)
965 return false; 977 return false;
966 978
967 float distance = BoundingBoxDiagonal(bounding_box_); 979 float distance = BoundingBoxDiagonal(bounding_box_);
968 980
969 if (abs(distance - pinch_distance_current_) >= 981 if (abs(distance - pinch_distance_current_) >=
970 GestureConfiguration::min_pinch_update_distance_in_pixels()) { 982 GestureConfiguration::min_pinch_update_distance_in_pixels()) {
971 AppendPinchGestureUpdate(point, 983 float scale = distance / pinch_distance_current_;
972 distance / pinch_distance_current_, gestures); 984 float angle = bounding_box_diagonal_angle_;
985 // Compute rotation only if the the bounding box remained of roughly the
986 // same size.
987 if (fabs(1.f - scale) < 0.15f)
988 angle = BoundingBoxDiagonalAngle(bounding_box_);
989 else
990 LOG(ERROR) << "Scale: " << scale;
991 AppendPinchGestureUpdate(point, scale, angle - bounding_box_diagonal_angle_,
992 gestures);
973 pinch_distance_current_ = distance; 993 pinch_distance_current_ = distance;
994 bounding_box_diagonal_angle_ = angle;
974 } else { 995 } else {
975 gfx::Point center = bounding_box_.CenterPoint(); 996 gfx::Point center = bounding_box_.CenterPoint();
976 AppendScrollGestureUpdate(point, center, gestures); 997 AppendScrollGestureUpdate(point, center, gestures);
977 } 998 }
978 999
979 return true; 1000 return true;
980 } 1001 }
981 1002
982 bool GestureSequence::PinchEnd(const TouchEvent& event, 1003 bool GestureSequence::PinchEnd(const TouchEvent& event,
983 const GesturePoint& point, 1004 const GesturePoint& point,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 return; 1090 return;
1070 1091
1071 // Since long press timer has been started, there should be a non-NULL point. 1092 // Since long press timer has been started, there should be a non-NULL point.
1072 const GesturePoint* point = GetPointByPointId(0); 1093 const GesturePoint* point = GetPointByPointId(0);
1073 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(), 1094 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(),
1074 event.location())) 1095 event.location()))
1075 long_press_timer_->Stop(); 1096 long_press_timer_->Stop();
1076 } 1097 }
1077 1098
1078 } // namespace ui 1099 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/gestures/gesture_sequence.h ('k') | ui/base/gestures/gesture_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698