| 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 |