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/events/gestures/gesture_sequence.h" | 5 #include "ui/events/gestures/gesture_sequence.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); | 472 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); |
473 } | 473 } |
474 } | 474 } |
475 } | 475 } |
476 | 476 |
477 } // namespace | 477 } // namespace |
478 | 478 |
479 //////////////////////////////////////////////////////////////////////////////// | 479 //////////////////////////////////////////////////////////////////////////////// |
480 // GestureSequence Public: | 480 // GestureSequence Public: |
481 | 481 |
482 GestureSequence::GestureSequence(GestureSequenceDelegate* delegate) | 482 GestureSequence::GestureSequence(GestureEventQueueTimerInterface* geq_timers) |
483 : state_(GS_NO_GESTURE), | 483 : state_(GS_NO_GESTURE), |
484 flags_(0), | 484 flags_(0), |
485 pinch_distance_start_(0.f), | 485 pinch_distance_start_(0.f), |
486 pinch_distance_current_(0.f), | 486 pinch_distance_current_(0.f), |
487 scroll_type_(ST_FREE), | 487 scroll_type_(ST_FREE), |
488 point_count_(0), | 488 point_count_(0), |
489 delegate_(delegate) { | 489 geq_timers_(geq_timers) { |
490 CHECK(delegate_); | |
491 } | 490 } |
492 | 491 |
493 GestureSequence::~GestureSequence() { | 492 GestureSequence::~GestureSequence() { |
494 } | 493 } |
495 | 494 |
496 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( | 495 GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
497 const TouchEvent& event, | 496 const TouchEvent& event) { |
498 EventResult result) { | 497 // TODO(tdresser): Remove depency on EventResult from GestureSequence. |
| 498 EventResult result = ER_UNHANDLED; |
499 StopTimersIfRequired(event); | 499 StopTimersIfRequired(event); |
500 last_touch_location_ = event.location(); | 500 last_touch_location_ = event.location(); |
501 if (result & ER_CONSUMED) | 501 if (result & ER_CONSUMED) |
502 return NULL; | 502 return NULL; |
503 | 503 |
504 // Set a limit on the number of simultaneous touches in a gesture. | 504 // Set a limit on the number of simultaneous touches in a gesture. |
505 if (event.touch_id() >= kMaxGesturePoints) | 505 if (event.touch_id() >= kMaxGesturePoints) |
506 return NULL; | 506 return NULL; |
507 | 507 |
508 if (event.type() == ui::ET_TOUCH_PRESSED) { | 508 if (event.type() == ui::ET_TOUCH_PRESSED) { |
(...skipping 15 matching lines...) Expand all Loading... |
524 | 524 |
525 GestureState last_state = state_; | 525 GestureState last_state = state_; |
526 | 526 |
527 // NOTE: when modifying these state transitions, also update gestures.dot | 527 // NOTE: when modifying these state transitions, also update gestures.dot |
528 scoped_ptr<Gestures> gestures(new Gestures()); | 528 scoped_ptr<Gestures> gestures(new Gestures()); |
529 GesturePoint& point = GesturePointForEvent(event); | 529 GesturePoint& point = GesturePointForEvent(event); |
530 point.UpdateValues(event); | 530 point.UpdateValues(event); |
531 RecreateBoundingBox(); | 531 RecreateBoundingBox(); |
532 flags_ = event.flags(); | 532 flags_ = event.flags(); |
533 const int point_id = point.point_id(); | 533 const int point_id = point.point_id(); |
534 if (point_id < 0) | 534 if (point_id < 0) { |
| 535 LOG(ERROR) << "GS sees event for touch which isn't down " << event.type(); |
| 536 LOG(ERROR) << "Touch id is " << event.touch_id(); |
535 return NULL; | 537 return NULL; |
| 538 } |
536 | 539 |
537 // Send GESTURE_BEGIN for any touch pressed. | 540 // Send GESTURE_BEGIN for any touch pressed. |
538 if (event.type() == ui::ET_TOUCH_PRESSED) | 541 if (event.type() == ui::ET_TOUCH_PRESSED) |
539 AppendBeginGestureEvent(point, gestures.get()); | 542 AppendBeginGestureEvent(point, gestures.get()); |
540 | 543 |
541 TouchStatusInternal status_internal = (result == ER_UNHANDLED) ? | 544 TouchStatusInternal status_internal = (result == ER_UNHANDLED) ? |
542 TSI_NOT_PROCESSED : TSI_PROCESSED; | 545 TSI_NOT_PROCESSED : TSI_PROCESSED; |
543 | 546 |
544 EdgeStateSignatureType signature = Signature(state_, point_id, | 547 EdgeStateSignatureType signature = Signature(state_, point_id, |
545 event.type(), status_internal); | 548 event.type(), status_internal); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 if (event.type() == ui::ET_TOUCH_RELEASED || | 747 if (event.type() == ui::ET_TOUCH_RELEASED || |
745 event.type() == ui::ET_TOUCH_CANCELLED) | 748 event.type() == ui::ET_TOUCH_CANCELLED) |
746 AppendEndGestureEvent(point, gestures.get()); | 749 AppendEndGestureEvent(point, gestures.get()); |
747 | 750 |
748 if (state_ != last_state) | 751 if (state_ != last_state) |
749 DVLOG(4) << "Gesture Sequence" | 752 DVLOG(4) << "Gesture Sequence" |
750 << " State: " << state_ | 753 << " State: " << state_ |
751 << " touch id: " << event.touch_id(); | 754 << " touch id: " << event.touch_id(); |
752 | 755 |
753 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) { | 756 if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) { |
754 GetLongPressTimer()->Stop(); | 757 if (GetLongPressTimer()->IsRunning()) { |
755 GetShowPressTimer()->Stop(); | 758 GetLongPressTimer()->Stop(); |
| 759 geq_timers_->TimerCancelled(); |
| 760 } |
| 761 if (GetShowPressTimer()->IsRunning()) { |
| 762 GetShowPressTimer()->Stop(); |
| 763 geq_timers_->TimerCancelled(); |
| 764 } |
756 } | 765 } |
757 | 766 |
758 // The set of point_ids must be contiguous and include 0. | 767 // The set of point_ids must be contiguous and include 0. |
759 // When a touch point is released, all points with ids greater than the | 768 // When a touch point is released, all points with ids greater than the |
760 // released point must have their ids decremented, or the set of point_ids | 769 // released point must have their ids decremented, or the set of point_ids |
761 // could end up with gaps. | 770 // could end up with gaps. |
762 if (event.type() == ui::ET_TOUCH_RELEASED || | 771 if (event.type() == ui::ET_TOUCH_RELEASED || |
763 event.type() == ui::ET_TOUCH_CANCELLED) { | 772 event.type() == ui::ET_TOUCH_CANCELLED) { |
764 for (int i = 0; i < kMaxGesturePoints; ++i) { | 773 for (int i = 0; i < kMaxGesturePoints; ++i) { |
765 GesturePoint& iter_point = points_[i]; | 774 GesturePoint& iter_point = points_[i]; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 void GestureSequence::ResetVelocities() { | 820 void GestureSequence::ResetVelocities() { |
812 for (int i = 0; i < kMaxGesturePoints; ++i) { | 821 for (int i = 0; i < kMaxGesturePoints; ++i) { |
813 if (points_[i].in_use()) | 822 if (points_[i].in_use()) |
814 points_[i].ResetVelocity(); | 823 points_[i].ResetVelocity(); |
815 } | 824 } |
816 } | 825 } |
817 | 826 |
818 //////////////////////////////////////////////////////////////////////////////// | 827 //////////////////////////////////////////////////////////////////////////////// |
819 // GestureSequence Protected: | 828 // GestureSequence Protected: |
820 | 829 |
821 base::OneShotTimer<GestureSequence>* GestureSequence::CreateTimer() { | 830 base::OneShotTimer<GestureEventQueueTimerInterface>* |
822 return new base::OneShotTimer<GestureSequence>(); | 831 GestureSequence::CreateTimer() { |
| 832 return new base::OneShotTimer<GestureEventQueueTimerInterface>(); |
823 } | 833 } |
824 | 834 |
825 base::OneShotTimer<GestureSequence>* GestureSequence::GetLongPressTimer() { | 835 base::OneShotTimer<GestureEventQueueTimerInterface>* |
| 836 GestureSequence::GetLongPressTimer() { |
826 if (!long_press_timer_.get()) | 837 if (!long_press_timer_.get()) |
827 long_press_timer_.reset(CreateTimer()); | 838 long_press_timer_.reset(CreateTimer()); |
828 return long_press_timer_.get(); | 839 return long_press_timer_.get(); |
829 } | 840 } |
830 | 841 |
831 base::OneShotTimer<GestureSequence>* GestureSequence::GetShowPressTimer() { | 842 base::OneShotTimer<GestureEventQueueTimerInterface>* |
| 843 GestureSequence::GetShowPressTimer() { |
832 if (!show_press_timer_.get()) | 844 if (!show_press_timer_.get()) |
833 show_press_timer_.reset(CreateTimer()); | 845 show_press_timer_.reset(CreateTimer()); |
834 return show_press_timer_.get(); | 846 return show_press_timer_.get(); |
835 } | 847 } |
836 | 848 |
837 //////////////////////////////////////////////////////////////////////////////// | 849 //////////////////////////////////////////////////////////////////////////////// |
838 // GestureSequence Private: | 850 // GestureSequence Private: |
839 | 851 |
840 GesturePoint& GestureSequence::GesturePointForEvent( | 852 GesturePoint& GestureSequence::GesturePointForEvent( |
841 const TouchEvent& event) { | 853 const TouchEvent& event) { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 Gestures* gestures) { | 1115 Gestures* gestures) { |
1104 DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK); | 1116 DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK); |
1105 if (point.IsInClickWindow(event)) { | 1117 if (point.IsInClickWindow(event)) { |
1106 int tap_count = 1; | 1118 int tap_count = 1; |
1107 if (point.IsInTripleClickWindow(event)) | 1119 if (point.IsInTripleClickWindow(event)) |
1108 tap_count = 3; | 1120 tap_count = 3; |
1109 else if (point.IsInDoubleClickWindow(event)) | 1121 else if (point.IsInDoubleClickWindow(event)) |
1110 tap_count = 2; | 1122 tap_count = 2; |
1111 if (tap_count == 1 && GetShowPressTimer()->IsRunning()) { | 1123 if (tap_count == 1 && GetShowPressTimer()->IsRunning()) { |
1112 GetShowPressTimer()->Stop(); | 1124 GetShowPressTimer()->Stop(); |
1113 AppendShowPressGestureEvent(); | 1125 geq_timers_->TimerCancelled(); |
1114 } | 1126 } |
1115 AppendClickGestureEvent(point, tap_count, gestures); | 1127 AppendClickGestureEvent(point, tap_count, gestures); |
1116 return true; | 1128 return true; |
1117 } else if (point.IsInsideManhattanSquare(event) && | 1129 } else if (point.IsInsideManhattanSquare(event) && |
1118 !GetLongPressTimer()->IsRunning()) { | 1130 !GetLongPressTimer()->IsRunning()) { |
1119 AppendLongTapGestureEvent(point, gestures); | 1131 AppendLongTapGestureEvent(point, gestures); |
1120 } | 1132 } |
1121 return false; | 1133 return false; |
1122 } | 1134 } |
1123 | 1135 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 return false; | 1169 return false; |
1158 AppendScrollGestureUpdate(point, gestures); | 1170 AppendScrollGestureUpdate(point, gestures); |
1159 return true; | 1171 return true; |
1160 } | 1172 } |
1161 | 1173 |
1162 bool GestureSequence::TouchDown(const TouchEvent& event, | 1174 bool GestureSequence::TouchDown(const TouchEvent& event, |
1163 const GesturePoint& point, | 1175 const GesturePoint& point, |
1164 Gestures* gestures) { | 1176 Gestures* gestures) { |
1165 DCHECK(state_ == GS_NO_GESTURE); | 1177 DCHECK(state_ == GS_NO_GESTURE); |
1166 AppendTapDownGestureEvent(point, gestures); | 1178 AppendTapDownGestureEvent(point, gestures); |
| 1179 AppendLongPressGestureEvent(point, gestures); |
| 1180 AppendShowPressGestureEvent(point, gestures); |
| 1181 |
1167 GetLongPressTimer()->Start( | 1182 GetLongPressTimer()->Start( |
1168 FROM_HERE, | 1183 FROM_HERE, |
1169 base::TimeDelta::FromMilliseconds( | 1184 base::TimeDelta::FromMilliseconds( |
1170 GestureConfiguration::long_press_time_in_seconds() * 1000), | 1185 GestureConfiguration::long_press_time_in_seconds() * 1000), |
1171 this, | 1186 geq_timers_, |
1172 &GestureSequence::AppendLongPressGestureEvent); | 1187 &GestureEventQueueTimerInterface::TimerFired); |
1173 | 1188 |
1174 GetShowPressTimer()->Start( | 1189 GetShowPressTimer()->Start( |
1175 FROM_HERE, | 1190 FROM_HERE, |
1176 base::TimeDelta::FromMilliseconds( | 1191 base::TimeDelta::FromMilliseconds( |
1177 GestureConfiguration::show_press_delay_in_ms()), | 1192 GestureConfiguration::show_press_delay_in_ms()), |
1178 this, | 1193 geq_timers_, |
1179 &GestureSequence::AppendShowPressGestureEvent); | 1194 &GestureEventQueueTimerInterface::TimerFired); |
1180 | 1195 |
1181 return true; | 1196 return true; |
1182 } | 1197 } |
1183 | 1198 |
1184 bool GestureSequence::TwoFingerTouchDown(const TouchEvent& event, | 1199 bool GestureSequence::TwoFingerTouchDown(const TouchEvent& event, |
1185 const GesturePoint& point, | 1200 const GesturePoint& point, |
1186 Gestures* gestures) { | 1201 Gestures* gestures) { |
1187 DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK || | 1202 DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK || |
1188 state_ == GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL || | 1203 state_ == GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL || |
1189 state_ == GS_SCROLL); | 1204 state_ == GS_SCROLL); |
(...skipping 28 matching lines...) Expand all Loading... |
1218 DCHECK(state_ == GS_PENDING_TWO_FINGER_TAP || | 1233 DCHECK(state_ == GS_PENDING_TWO_FINGER_TAP || |
1219 state_ == GS_PENDING_TWO_FINGER_TAP_NO_PINCH); | 1234 state_ == GS_PENDING_TWO_FINGER_TAP_NO_PINCH); |
1220 base::TimeDelta time_delta = event.time_stamp() - second_touch_time_; | 1235 base::TimeDelta time_delta = event.time_stamp() - second_touch_time_; |
1221 base::TimeDelta max_delta = base::TimeDelta::FromMilliseconds(1000 * | 1236 base::TimeDelta max_delta = base::TimeDelta::FromMilliseconds(1000 * |
1222 ui::GestureConfiguration::max_touch_down_duration_in_seconds_for_click()); | 1237 ui::GestureConfiguration::max_touch_down_duration_in_seconds_for_click()); |
1223 if (time_delta < max_delta && point.IsInsideManhattanSquare(event)) | 1238 if (time_delta < max_delta && point.IsInsideManhattanSquare(event)) |
1224 AppendTwoFingerTapGestureEvent(gestures); | 1239 AppendTwoFingerTapGestureEvent(gestures); |
1225 return true; | 1240 return true; |
1226 } | 1241 } |
1227 | 1242 |
1228 void GestureSequence::AppendLongPressGestureEvent() { | 1243 void GestureSequence::AppendLongPressGestureEvent(const GesturePoint& point, |
1229 const GesturePoint* point = GetPointByPointId(0); | 1244 Gestures* gestures) { |
1230 scoped_ptr<GestureEvent> gesture(CreateGestureEvent( | 1245 gestures->push_back(CreateGestureEvent( |
1231 GestureEventDetails(ui::ET_GESTURE_LONG_PRESS, 0, 0), | 1246 GestureEventDetails(ui::ET_GESTURE_LONG_PRESS, 0, 0), |
1232 point->first_touch_position(), | 1247 point.first_touch_position(), |
1233 flags_, | 1248 flags_, |
1234 base::Time::FromDoubleT(point->last_touch_time()), | 1249 base::Time::FromDoubleT(point.last_touch_time()), |
1235 1 << point->touch_id())); | 1250 1 << point.touch_id())); |
1236 delegate_->DispatchPostponedGestureEvent(gesture.get()); | |
1237 } | 1251 } |
1238 | 1252 |
1239 void GestureSequence::AppendShowPressGestureEvent() { | 1253 |
1240 const GesturePoint* point = GetPointByPointId(0); | 1254 void GestureSequence::AppendShowPressGestureEvent(const GesturePoint& point, |
1241 scoped_ptr<GestureEvent> gesture(CreateGestureEvent( | 1255 Gestures* gestures) { |
| 1256 gestures->push_back(CreateGestureEvent( |
1242 GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS, 0, 0), | 1257 GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS, 0, 0), |
1243 point->first_touch_position(), | 1258 point.first_touch_position(), |
1244 flags_, | 1259 flags_, |
1245 base::Time::FromDoubleT(point->last_touch_time()), | 1260 base::Time::FromDoubleT(point.last_touch_time()), |
1246 1 << point->touch_id())); | 1261 1 << point.touch_id())); |
1247 delegate_->DispatchPostponedGestureEvent(gesture.get()); | |
1248 } | 1262 } |
1249 | 1263 |
1250 void GestureSequence::AppendLongTapGestureEvent(const GesturePoint& point, | 1264 void GestureSequence::AppendLongTapGestureEvent(const GesturePoint& point, |
1251 Gestures* gestures) { | 1265 Gestures* gestures) { |
1252 gfx::Rect er = point.enclosing_rectangle(); | 1266 gfx::Rect er = point.enclosing_rectangle(); |
1253 gfx::Point center = er.CenterPoint(); | 1267 gfx::Point center = er.CenterPoint(); |
1254 gestures->push_back(CreateGestureEvent( | 1268 gestures->push_back(CreateGestureEvent( |
1255 GestureEventDetails(ui::ET_GESTURE_LONG_TAP, 0, 0), | 1269 GestureEventDetails(ui::ET_GESTURE_LONG_TAP, 0, 0), |
1256 center, | 1270 center, |
1257 flags_, | 1271 flags_, |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 void GestureSequence::StopTimersIfRequired(const TouchEvent& event) { | 1447 void GestureSequence::StopTimersIfRequired(const TouchEvent& event) { |
1434 if ((!GetLongPressTimer()->IsRunning() && | 1448 if ((!GetLongPressTimer()->IsRunning() && |
1435 !GetShowPressTimer()->IsRunning()) || | 1449 !GetShowPressTimer()->IsRunning()) || |
1436 event.type() != ui::ET_TOUCH_MOVED) | 1450 event.type() != ui::ET_TOUCH_MOVED) |
1437 return; | 1451 return; |
1438 | 1452 |
1439 // Since a timer is running, there should be a non-NULL point. | 1453 // Since a timer is running, there should be a non-NULL point. |
1440 const GesturePoint* point = GetPointByPointId(0); | 1454 const GesturePoint* point = GetPointByPointId(0); |
1441 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(), | 1455 if (!ui::gestures::IsInsideManhattanSquare(point->first_touch_position(), |
1442 event.location())) { | 1456 event.location())) { |
1443 GetLongPressTimer()->Stop(); | 1457 if (GetLongPressTimer()->IsRunning()) { |
1444 GetShowPressTimer()->Stop(); | 1458 GetLongPressTimer()->Stop(); |
| 1459 geq_timers_->TimerCancelled(); |
| 1460 } |
| 1461 if (GetShowPressTimer()->IsRunning()) { |
| 1462 GetShowPressTimer()->Stop(); |
| 1463 geq_timers_->TimerCancelled(); |
| 1464 } |
1445 } | 1465 } |
1446 } | 1466 } |
1447 | 1467 |
1448 } // namespace ui | 1468 } // namespace ui |
OLD | NEW |