OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "ui/aura/client/cursor_client.h" | 9 #include "ui/aura/client/cursor_client.h" |
10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
32 // until all fingers are released. | 32 // until all fingers are released. |
33 const int kTouchIdNone = -1; | 33 const int kTouchIdNone = -1; |
34 } // namespace | 34 } // namespace |
35 | 35 |
36 TouchExplorationController::TouchExplorationController( | 36 TouchExplorationController::TouchExplorationController( |
37 aura::Window* root_window) | 37 aura::Window* root_window) |
38 : root_window_(root_window), | 38 : root_window_(root_window), |
39 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned), | 39 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned), |
40 state_(NO_FINGERS_DOWN), | 40 state_(NO_FINGERS_DOWN), |
41 event_handler_for_testing_(NULL), | 41 event_handler_for_testing_(NULL), |
42 gesture_provider_(this), | |
42 prev_state_(NO_FINGERS_DOWN) { | 43 prev_state_(NO_FINGERS_DOWN) { |
43 CHECK(root_window); | 44 CHECK(root_window); |
44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
45 } | 46 } |
46 | 47 |
47 TouchExplorationController::~TouchExplorationController() { | 48 TouchExplorationController::~TouchExplorationController() { |
48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | 49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); |
49 } | 50 } |
50 | 51 |
51 void TouchExplorationController::CallTapTimerNowForTesting() { | 52 void TouchExplorationController::CallTapTimerNowForTesting() { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 case NO_FINGERS_DOWN: | 121 case NO_FINGERS_DOWN: |
121 return InNoFingersDown(touch_event, rewritten_event); | 122 return InNoFingersDown(touch_event, rewritten_event); |
122 case SINGLE_TAP_PRESSED: | 123 case SINGLE_TAP_PRESSED: |
123 return InSingleTapPressed(touch_event, rewritten_event); | 124 return InSingleTapPressed(touch_event, rewritten_event); |
124 case SINGLE_TAP_RELEASED: | 125 case SINGLE_TAP_RELEASED: |
125 return InSingleTapReleased(touch_event, rewritten_event); | 126 return InSingleTapReleased(touch_event, rewritten_event); |
126 case DOUBLE_TAP_PRESSED: | 127 case DOUBLE_TAP_PRESSED: |
127 return InDoubleTapPressed(touch_event, rewritten_event); | 128 return InDoubleTapPressed(touch_event, rewritten_event); |
128 case TOUCH_EXPLORATION: | 129 case TOUCH_EXPLORATION: |
129 return InTouchExploration(touch_event, rewritten_event); | 130 return InTouchExploration(touch_event, rewritten_event); |
131 case GESTURE_IN_PROGRESS: | |
132 return InGestureInProgress(touch_event, rewritten_event); | |
130 case PASSTHROUGH_MINUS_ONE: | 133 case PASSTHROUGH_MINUS_ONE: |
131 return InPassthroughMinusOne(touch_event, rewritten_event); | 134 return InPassthroughMinusOne(touch_event, rewritten_event); |
132 case TOUCH_EXPLORE_SECOND_PRESS: | 135 case TOUCH_EXPLORE_SECOND_PRESS: |
133 return InTouchExploreSecondPress(touch_event, rewritten_event); | 136 return InTouchExploreSecondPress(touch_event, rewritten_event); |
134 } | 137 } |
135 | 138 |
136 NOTREACHED(); | 139 NOTREACHED(); |
137 return ui::EVENT_REWRITE_CONTINUE; | 140 return ui::EVENT_REWRITE_CONTINUE; |
138 } | 141 } |
139 | 142 |
140 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 143 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
141 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 144 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
142 NOTREACHED(); | 145 NOTREACHED(); |
143 return ui::EVENT_REWRITE_CONTINUE; | 146 return ui::EVENT_REWRITE_CONTINUE; |
144 } | 147 } |
145 | 148 |
146 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 149 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
147 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 150 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
148 const ui::EventType type = event.type(); | 151 const ui::EventType type = event.type(); |
149 if (type == ui::ET_TOUCH_PRESSED) { | 152 if (type == ui::ET_TOUCH_PRESSED) { |
150 initial_press_.reset(new TouchEvent(event)); | 153 initial_press_.reset(new TouchEvent(event)); |
151 tap_timer_.Start(FROM_HERE, | 154 tap_timer_.Start(FROM_HERE, |
152 gesture_detector_config_.double_tap_timeout, | 155 gesture_detector_config_.double_tap_timeout, |
153 this, | 156 this, |
154 &TouchExplorationController::OnTapTimerFired); | 157 &TouchExplorationController::OnTapTimerFired); |
158 gesture_provider_.OnTouchEvent(event); | |
159 gesture_provider_.OnTouchEventAck(false); | |
155 state_ = SINGLE_TAP_PRESSED; | 160 state_ = SINGLE_TAP_PRESSED; |
156 VLOG_STATE(); | 161 VLOG_STATE(); |
157 return ui::EVENT_REWRITE_DISCARD; | 162 return ui::EVENT_REWRITE_DISCARD; |
158 } | 163 } |
159 | 164 |
160 NOTREACHED(); | 165 NOTREACHED(); |
161 return ui::EVENT_REWRITE_CONTINUE; | 166 return ui::EVENT_REWRITE_CONTINUE; |
162 } | 167 } |
163 | 168 |
164 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 169 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
165 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
166 const ui::EventType type = event.type(); | 171 const ui::EventType type = event.type(); |
167 | 172 |
168 if (type == ui::ET_TOUCH_PRESSED) { | 173 if (type == ui::ET_TOUCH_PRESSED) { |
169 // Adding a second finger within the timeout period switches to | 174 // Adding a second finger within the timeout period switches to |
170 // passthrough. | 175 // passthrough. |
171 state_ = PASSTHROUGH_MINUS_ONE; | 176 state_ = PASSTHROUGH_MINUS_ONE; |
172 return InPassthroughMinusOne(event, rewritten_event); | 177 return InPassthroughMinusOne(event, rewritten_event); |
173 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 178 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
174 DCHECK_EQ(0U, current_touch_ids_.size()); | 179 DCHECK_EQ(0U, current_touch_ids_.size()); |
175 state_ = SINGLE_TAP_RELEASED; | 180 state_ = SINGLE_TAP_RELEASED; |
176 VLOG_STATE(); | 181 VLOG_STATE(); |
177 return EVENT_REWRITE_DISCARD; | 182 return EVENT_REWRITE_DISCARD; |
178 } else if (type == ui::ET_TOUCH_MOVED) { | 183 } else if (type == ui::ET_TOUCH_MOVED) { |
179 // If the user moves far enough from the initial touch location (outside | 184 // If the user moves fast enough from the initial touch location, |
180 // the "slop" region, jump to the touch exploration mode early. | 185 // start gesture detection |
181 // TODO(evy, lisayin): Add gesture recognition here instead - | 186 float delta_time = |
182 // we should probably jump to gesture mode here if the velocity is | 187 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); |
183 // high enough, and touch exploration if the velocity is lower. | 188 float delta_distance = |
184 float delta = (event.location() - initial_press_->location()).Length(); | 189 (event.location() - initial_press_->location()).Length(); |
185 if (delta > gesture_detector_config_.touch_slop) { | 190 float velocity = delta_distance / delta_time; |
191 VLOG(0) << "\n Delta time: " << delta_time | |
192 << "\n Delta distance: " << delta_distance | |
193 << "\n Velocity of click: " << velocity | |
194 << "\n Minimum swipe velocity: " | |
195 << gesture_detector_config_.minimum_swipe_velocity; | |
196 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | |
197 gesture_provider_.OnTouchEvent(event); | |
dmazzoni
2014/06/20 16:26:54
I think you're forwarding the same event to the ge
lisayin
2014/06/20 21:34:39
Fixed.
| |
198 gesture_provider_.OnTouchEventAck(false); | |
199 state_ = GESTURE_IN_PROGRESS; | |
200 VLOG_STATE(); | |
201 return InGestureInProgress(event, rewritten_event); | |
202 } | |
203 // Otherwise, if the user moves far enough from the initial touch location | |
204 // outside the "slop" region, jump to the touch exploration mode early. | |
205 else if (delta_distance > gesture_detector_config_.touch_slop) { | |
186 EnterTouchToMouseMode(); | 206 EnterTouchToMouseMode(); |
187 state_ = TOUCH_EXPLORATION; | 207 state_ = TOUCH_EXPLORATION; |
188 VLOG_STATE(); | 208 VLOG_STATE(); |
189 return InTouchExploration(event, rewritten_event); | 209 return InTouchExploration(event, rewritten_event); |
190 } | 210 } |
191 | 211 |
192 return EVENT_REWRITE_DISCARD; | 212 return EVENT_REWRITE_DISCARD; |
193 } | 213 } |
194 NOTREACHED() << "Unexpected event type received."; | 214 NOTREACHED() << "Unexpected event type received."; |
195 return ui::EVENT_REWRITE_CONTINUE; | 215 return ui::EVENT_REWRITE_CONTINUE; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 NOTREACHED() << "Unexpected event type received."; | 296 NOTREACHED() << "Unexpected event type received."; |
277 return ui::EVENT_REWRITE_CONTINUE; | 297 return ui::EVENT_REWRITE_CONTINUE; |
278 } | 298 } |
279 | 299 |
280 // Rewrite as a mouse-move event. | 300 // Rewrite as a mouse-move event. |
281 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 301 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
282 last_touch_exploration_.reset(new TouchEvent(event)); | 302 last_touch_exploration_.reset(new TouchEvent(event)); |
283 return ui::EVENT_REWRITE_REWRITTEN; | 303 return ui::EVENT_REWRITE_REWRITTEN; |
284 } | 304 } |
285 | 305 |
306 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | |
307 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | |
308 ui::EventType type = event.type(); | |
309 gfx::PointF location = event.location_f(); | |
310 if (type == ui::ET_TOUCH_PRESSED) { | |
311 return EVENT_REWRITE_DISCARD; | |
312 } | |
313 if (type == ui::ET_TOUCH_MOVED) { | |
314 gesture_provider_.OnTouchEvent(event); | |
315 gesture_provider_.OnTouchEventAck(false); | |
316 } | |
317 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
318 gesture_provider_.OnTouchEvent(event); | |
319 gesture_provider_.OnTouchEventAck(true); | |
dmazzoni
2014/06/20 16:26:54
Why true here and false otherwise?
lisayin
2014/06/20 21:34:39
To be honest, it was something that I was just try
| |
320 if (current_touch_ids_.size() == 0) | |
321 ResetToNoFingersDown(); | |
322 } | |
323 return ui::EVENT_REWRITE_DISCARD; | |
324 } | |
325 | |
286 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( | 326 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( |
287 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 327 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
288 ui::EventType type = event.type(); | 328 ui::EventType type = event.type(); |
289 gfx::PointF location = event.location_f(); | 329 gfx::PointF location = event.location_f(); |
290 | 330 |
291 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 331 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
292 if (current_touch_ids_.size() == 0) | 332 if (current_touch_ids_.size() == 0) |
293 ResetToNoFingersDown(); | 333 ResetToNoFingersDown(); |
294 | 334 |
295 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { | 335 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 435 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
396 if (event_handler_for_testing_) { | 436 if (event_handler_for_testing_) { |
397 event_handler_for_testing_->OnEvent(event); | 437 event_handler_for_testing_->OnEvent(event); |
398 return; | 438 return; |
399 } | 439 } |
400 | 440 |
401 ui::EventDispatchDetails result ALLOW_UNUSED = | 441 ui::EventDispatchDetails result ALLOW_UNUSED = |
402 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 442 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
403 } | 443 } |
404 | 444 |
445 void TouchExplorationController::OnGestureEvent( | |
446 ui::GestureEvent* gesture) { | |
447 std::string message = "\n Gesture Triggered: "; | |
448 switch (gesture->type()) { | |
449 case ET_GESTURE_SHOW_PRESS: | |
450 message += "ET_GESTURE_SHOW_PRESS"; | |
451 break; | |
452 case ET_GESTURE_SWIPE: | |
453 message += "ET_GESTURE_SWIPE"; | |
454 break; | |
455 case ET_GESTURE_LONG_TAP: | |
456 message += "ET_GESTURE_LONG_TAP"; | |
457 break; | |
458 case ET_GESTURE_LONG_PRESS: | |
459 message += "ET_GESTURE_LONG_PRESS"; | |
460 break; | |
461 case ET_GESTURE_PINCH_UPDATE: | |
462 message += "ET_GESTURE_PINCH_UPDATE"; | |
463 break; | |
464 case ET_GESTURE_PINCH_END: | |
465 message += "ET_GESTURE_PINCH_END"; | |
466 break; | |
467 default: | |
468 return; | |
469 } | |
470 VLOG(0) << message; | |
471 } | |
472 | |
405 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( | 473 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
406 const gfx::PointF& location, | 474 const gfx::PointF& location, |
407 int flags) { | 475 int flags) { |
408 return scoped_ptr<ui::Event>( | 476 return scoped_ptr<ui::Event>( |
409 new ui::MouseEvent( | 477 new ui::MouseEvent( |
410 ui::ET_MOUSE_MOVED, | 478 ui::ET_MOUSE_MOVED, |
411 location, | 479 location, |
412 location, | 480 location, |
413 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, | 481 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, |
414 0)); | 482 0)); |
415 } | 483 } |
416 | 484 |
417 void TouchExplorationController::EnterTouchToMouseMode() { | 485 void TouchExplorationController::EnterTouchToMouseMode() { |
418 aura::client::CursorClient* cursor_client = | 486 aura::client::CursorClient* cursor_client = |
419 aura::client::GetCursorClient(root_window_); | 487 aura::client::GetCursorClient(root_window_); |
420 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 488 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
421 cursor_client->EnableMouseEvents(); | 489 cursor_client->EnableMouseEvents(); |
422 if (cursor_client && cursor_client->IsCursorVisible()) | 490 if (cursor_client && cursor_client->IsCursorVisible()) |
423 cursor_client->HideCursor(); | 491 cursor_client->HideCursor(); |
424 } | 492 } |
425 | 493 |
426 void TouchExplorationController::ResetToNoFingersDown() { | 494 void TouchExplorationController::ResetToNoFingersDown() { |
495 gesture_provider_.GetAndResetPendingGestures(); | |
427 state_ = NO_FINGERS_DOWN; | 496 state_ = NO_FINGERS_DOWN; |
428 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned; | 497 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned; |
429 VLOG_STATE(); | 498 VLOG_STATE(); |
430 if (tap_timer_.IsRunning()) | 499 if (tap_timer_.IsRunning()) |
431 tap_timer_.Stop(); | 500 tap_timer_.Stop(); |
432 } | 501 } |
433 | 502 |
434 void TouchExplorationController::VlogState(const char* function_name) { | 503 void TouchExplorationController::VlogState(const char* function_name) { |
435 if (prev_state_ == state_) | 504 if (prev_state_ == state_) |
436 return; | 505 return; |
(...skipping 26 matching lines...) Expand all Loading... | |
463 case NO_FINGERS_DOWN: | 532 case NO_FINGERS_DOWN: |
464 return "NO_FINGERS_DOWN"; | 533 return "NO_FINGERS_DOWN"; |
465 case SINGLE_TAP_PRESSED: | 534 case SINGLE_TAP_PRESSED: |
466 return "SINGLE_TAP_PRESSED"; | 535 return "SINGLE_TAP_PRESSED"; |
467 case SINGLE_TAP_RELEASED: | 536 case SINGLE_TAP_RELEASED: |
468 return "SINGLE_TAP_RELEASED"; | 537 return "SINGLE_TAP_RELEASED"; |
469 case DOUBLE_TAP_PRESSED: | 538 case DOUBLE_TAP_PRESSED: |
470 return "DOUBLE_TAP_PRESSED"; | 539 return "DOUBLE_TAP_PRESSED"; |
471 case TOUCH_EXPLORATION: | 540 case TOUCH_EXPLORATION: |
472 return "TOUCH_EXPLORATION"; | 541 return "TOUCH_EXPLORATION"; |
542 case GESTURE_IN_PROGRESS: | |
543 return "GESTURE_IN_PROGRESS"; | |
473 case PASSTHROUGH_MINUS_ONE: | 544 case PASSTHROUGH_MINUS_ONE: |
474 return "PASSTHROUGH_MINUS_ONE"; | 545 return "PASSTHROUGH_MINUS_ONE"; |
475 case TOUCH_EXPLORE_SECOND_PRESS: | 546 case TOUCH_EXPLORE_SECOND_PRESS: |
476 return "TOUCH_EXPLORE_SECOND_PRESS"; | 547 return "TOUCH_EXPLORE_SECOND_PRESS"; |
477 } | 548 } |
478 return "Not a state"; | 549 return "Not a state"; |
479 } | 550 } |
480 | 551 |
481 std::string TouchExplorationController::EnumEventTypeToString( | 552 std::string TouchExplorationController::EnumEventTypeToString( |
482 ui::EventType type) { | 553 ui::EventType type) { |
483 // Add more cases later. For now, these are the most frequently seen | 554 // Add more cases later. For now, these are the most frequently seen |
484 // event types. | 555 // event types. |
485 switch (type) { | 556 switch (type) { |
486 case ET_TOUCH_RELEASED: | 557 case ET_TOUCH_RELEASED: |
487 return "ET_TOUCH_RELEASED"; | 558 return "ET_TOUCH_RELEASED"; |
488 case ET_TOUCH_PRESSED: | 559 case ET_TOUCH_PRESSED: |
489 return "ET_TOUCH_PRESSED"; | 560 return "ET_TOUCH_PRESSED"; |
490 case ET_TOUCH_MOVED: | 561 case ET_TOUCH_MOVED: |
491 return "ET_TOUCH_MOVED"; | 562 return "ET_TOUCH_MOVED"; |
492 case ET_TOUCH_CANCELLED: | 563 case ET_TOUCH_CANCELLED: |
493 return "ET_TOUCH_CANCELLED"; | 564 return "ET_TOUCH_CANCELLED"; |
494 default: | 565 default: |
495 return base::IntToString(type); | 566 return base::IntToString(type); |
496 } | 567 } |
497 } | 568 } |
498 | 569 |
499 } // namespace ui | 570 } // namespace ui |
OLD | NEW |