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

Side by Side Diff: ui/chromeos/touch_exploration_controller.cc

Issue 2880043002: Implement touch exploration touch typing (Closed)
Patch Set: Remove observer. Created 3 years, 6 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
OLDNEW
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 <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 root_window_->GetHost()->ConvertDIPToScreenInPixels(&native_point); 65 root_window_->GetHost()->ConvertDIPToScreenInPixels(&native_point);
66 66
67 anchor_point_ = gfx::PointF(native_point.x(), native_point.y()); 67 anchor_point_ = gfx::PointF(native_point.x(), native_point.y());
68 anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET; 68 anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET;
69 } 69 }
70 70
71 void TouchExplorationController::SetExcludeBounds(const gfx::Rect& bounds) { 71 void TouchExplorationController::SetExcludeBounds(const gfx::Rect& bounds) {
72 exclude_bounds_ = bounds; 72 exclude_bounds_ = bounds;
73 } 73 }
74 74
75 void TouchExplorationController::SetLiftActivationBounds(
76 const gfx::Rect& bounds) {
77 lift_activation_bounds_ = bounds;
78 }
79
75 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 80 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
76 const ui::Event& event, 81 const ui::Event& event,
77 std::unique_ptr<ui::Event>* rewritten_event) { 82 std::unique_ptr<ui::Event>* rewritten_event) {
78 if (!event.IsTouchEvent()) { 83 if (!event.IsTouchEvent()) {
79 if (event.IsKeyEvent()) { 84 if (event.IsKeyEvent()) {
80 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); 85 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
81 VLOG(1) << "\nKeyboard event: " << key_event.GetName() 86 VLOG(1) << "\nKeyboard event: " << key_event.GetName()
82 << "\n Key code: " << key_event.key_code() 87 << "\n Key code: " << key_event.key_code()
83 << ", Flags: " << key_event.flags() 88 << ", Flags: " << key_event.flags()
84 << ", Is char: " << key_event.is_char(); 89 << ", Is char: " << key_event.is_char();
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 321
317 if (type == ui::ET_TOUCH_PRESSED) { 322 if (type == ui::ET_TOUCH_PRESSED) {
318 initial_presses_[event.pointer_details().id] = event.location(); 323 initial_presses_[event.pointer_details().id] = event.location();
319 SET_STATE(TWO_FINGER_TAP); 324 SET_STATE(TWO_FINGER_TAP);
320 return EVENT_REWRITE_DISCARD; 325 return EVENT_REWRITE_DISCARD;
321 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 326 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
322 if (passthrough_timer_.IsRunning()) 327 if (passthrough_timer_.IsRunning())
323 passthrough_timer_.Stop(); 328 passthrough_timer_.Stop();
324 if (current_touch_ids_.size() == 0 && 329 if (current_touch_ids_.size() == 0 &&
325 event.pointer_details().id == initial_press_->pointer_details().id) { 330 event.pointer_details().id == initial_press_->pointer_details().id) {
331 MaybeSendSimulatedTapInLiftActivationBounds(event);
326 SET_STATE(SINGLE_TAP_RELEASED); 332 SET_STATE(SINGLE_TAP_RELEASED);
327 } else if (current_touch_ids_.size() == 0) { 333 } else if (current_touch_ids_.size() == 0) {
328 SET_STATE(NO_FINGERS_DOWN); 334 SET_STATE(NO_FINGERS_DOWN);
329 } 335 }
330 return EVENT_REWRITE_DISCARD; 336 return EVENT_REWRITE_DISCARD;
331 } else if (type == ui::ET_TOUCH_MOVED) { 337 } else if (type == ui::ET_TOUCH_MOVED) {
332 float distance = (event.location() - initial_press_->location()).Length(); 338 float distance = (event.location() - initial_press_->location()).Length();
333 // If the user does not move far enough from the original position, then the 339 // If the user does not move far enough from the original position, then the
334 // resulting movement should not be considered to be a deliberate gesture or 340 // resulting movement should not be considered to be a deliberate gesture or
335 // touch exploration. 341 // touch exploration.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 float delta = (event.location() - initial_press_->location()).Length(); 432 float delta = (event.location() - initial_press_->location()).Length();
427 if (delta > gesture_detector_config_.touch_slop) { 433 if (delta > gesture_detector_config_.touch_slop) {
428 tap_timer_.Stop(); 434 tap_timer_.Stop();
429 OnTapTimerFired(); 435 OnTapTimerFired();
430 } 436 }
431 return EVENT_REWRITE_DISCARD; 437 return EVENT_REWRITE_DISCARD;
432 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 438 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
433 if (current_touch_ids_.size() != 0) 439 if (current_touch_ids_.size() != 0)
434 return EVENT_REWRITE_DISCARD; 440 return EVENT_REWRITE_DISCARD;
435 441
436 SendSimulatedClick(); 442 SendSimulatedClickOrTap();
437 443
438 SET_STATE(NO_FINGERS_DOWN); 444 SET_STATE(NO_FINGERS_DOWN);
439 return ui::EVENT_REWRITE_DISCARD; 445 return ui::EVENT_REWRITE_DISCARD;
440 } 446 }
441 NOTREACHED(); 447 NOTREACHED();
442 return ui::EVENT_REWRITE_CONTINUE; 448 return ui::EVENT_REWRITE_CONTINUE;
443 } 449 }
444 450
445 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( 451 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending(
446 const ui::TouchEvent& event, 452 const ui::TouchEvent& event,
447 std::unique_ptr<ui::Event>* rewritten_event) { 453 std::unique_ptr<ui::Event>* rewritten_event) {
448 const ui::EventType type = event.type(); 454 const ui::EventType type = event.type();
449 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { 455 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) {
450 return ui::EVENT_REWRITE_DISCARD; 456 return ui::EVENT_REWRITE_DISCARD;
451 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 457 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
452 if (current_touch_ids_.size() != 0) 458 if (current_touch_ids_.size() != 0)
453 return EVENT_REWRITE_DISCARD; 459 return EVENT_REWRITE_DISCARD;
454 460
455 SendSimulatedClick(); 461 SendSimulatedClickOrTap();
456 SET_STATE(NO_FINGERS_DOWN); 462 SET_STATE(NO_FINGERS_DOWN);
457 return ui::EVENT_REWRITE_DISCARD; 463 return ui::EVENT_REWRITE_DISCARD;
458 } 464 }
459 NOTREACHED(); 465 NOTREACHED();
460 return ui::EVENT_REWRITE_CONTINUE; 466 return ui::EVENT_REWRITE_CONTINUE;
461 } 467 }
462 468
463 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 469 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
464 const ui::TouchEvent& event, 470 const ui::TouchEvent& event,
465 std::unique_ptr<ui::Event>* rewritten_event) { 471 std::unique_ptr<ui::Event>* rewritten_event) {
466 const ui::EventType type = event.type(); 472 const ui::EventType type = event.type();
467 if (type == ui::ET_TOUCH_PRESSED) { 473 if (type == ui::ET_TOUCH_PRESSED) {
468 // Enter split-tap mode. 474 // Enter split-tap mode.
469 initial_press_.reset(new TouchEvent(event)); 475 initial_press_.reset(new TouchEvent(event));
470 tap_timer_.Stop(); 476 tap_timer_.Stop();
471 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); 477 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS);
472 return ui::EVENT_REWRITE_DISCARD; 478 return ui::EVENT_REWRITE_DISCARD;
473 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 479 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
474 initial_press_.reset(new TouchEvent(event)); 480 initial_press_.reset(new TouchEvent(event));
475 StartTapTimer(); 481 StartTapTimer();
482 MaybeSendSimulatedTapInLiftActivationBounds(event);
476 SET_STATE(TOUCH_EXPLORE_RELEASED); 483 SET_STATE(TOUCH_EXPLORE_RELEASED);
477 } else if (type != ui::ET_TOUCH_MOVED) { 484 } else if (type != ui::ET_TOUCH_MOVED) {
478 NOTREACHED(); 485 NOTREACHED();
479 return ui::EVENT_REWRITE_CONTINUE; 486 return ui::EVENT_REWRITE_CONTINUE;
480 } 487 }
481 488
482 // Rewrite as a mouse-move event. 489 // Rewrite as a mouse-move event.
483 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags()); 490 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags());
484 last_touch_exploration_.reset(new TouchEvent(event)); 491 last_touch_exploration_.reset(new TouchEvent(event));
485 if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET) 492 if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 last_touch_exploration_->pointer_details().id) { 614 last_touch_exploration_->pointer_details().id) {
608 SET_STATE(TOUCH_RELEASE_PENDING); 615 SET_STATE(TOUCH_RELEASE_PENDING);
609 return EVENT_REWRITE_DISCARD; 616 return EVENT_REWRITE_DISCARD;
610 } 617 }
611 618
612 // Continue to release the touch only if the touch explore finger is the 619 // Continue to release the touch only if the touch explore finger is the
613 // only finger remaining. 620 // only finger remaining.
614 if (current_touch_ids_.size() != 1) 621 if (current_touch_ids_.size() != 1)
615 return EVENT_REWRITE_DISCARD; 622 return EVENT_REWRITE_DISCARD;
616 623
617 SendSimulatedClick(); 624 SendSimulatedClickOrTap();
618 625
619 SET_STATE(TOUCH_EXPLORATION); 626 SET_STATE(TOUCH_EXPLORATION);
620 EnterTouchToMouseMode(); 627 EnterTouchToMouseMode();
621 return ui::EVENT_REWRITE_DISCARD; 628 return ui::EVENT_REWRITE_DISCARD;
622 } 629 }
623 NOTREACHED(); 630 NOTREACHED();
624 return ui::EVENT_REWRITE_CONTINUE; 631 return ui::EVENT_REWRITE_CONTINUE;
625 } 632 }
626 633
627 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( 634 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
628 const ui::TouchEvent& event, 635 const ui::TouchEvent& event,
629 std::unique_ptr<ui::Event>* rewritten_event) { 636 std::unique_ptr<ui::Event>* rewritten_event) {
630 if (current_touch_ids_.size() == 0) 637 if (current_touch_ids_.size() == 0)
631 SET_STATE(NO_FINGERS_DOWN); 638 SET_STATE(NO_FINGERS_DOWN);
632 return EVENT_REWRITE_DISCARD; 639 return EVENT_REWRITE_DISCARD;
633 } 640 }
634 641
635 void TouchExplorationController::PlaySoundForTimer() { 642 void TouchExplorationController::PlaySoundForTimer() {
636 delegate_->PlayVolumeAdjustEarcon(); 643 delegate_->PlayVolumeAdjustEarcon();
637 } 644 }
638 645
639 void TouchExplorationController::SendSimulatedClick() { 646 void TouchExplorationController::SendSimulatedClickOrTap() {
640 // If we got an anchor point from ChromeVox, send a double-tap gesture 647 // If we got an anchor point from ChromeVox, send a double-tap gesture
641 // and let ChromeVox handle the click. 648 // and let ChromeVox handle the click.
642 if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) { 649 if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) {
643 delegate_->HandleAccessibilityGesture(ui::AX_GESTURE_CLICK); 650 delegate_->HandleAccessibilityGesture(ui::AX_GESTURE_CLICK);
644 return; 651 return;
645 } 652 }
653 SendSimulatedTap();
654 }
646 655
647 // If we don't have an anchor point, we can't send a simulated click. 656 void TouchExplorationController::SendSimulatedTap() {
648 if (anchor_point_state_ == ANCHOR_POINT_NONE)
649 return;
650
651 // Otherwise send a simulated press/release at the anchor point.
652 std::unique_ptr<ui::TouchEvent> touch_press; 657 std::unique_ptr<ui::TouchEvent> touch_press;
653 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), 658 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
654 Now(), 659 Now(),
655 initial_press_->pointer_details())); 660 initial_press_->pointer_details()));
656 touch_press->set_location_f(anchor_point_); 661 touch_press->set_location_f(anchor_point_);
657 touch_press->set_root_location_f(anchor_point_); 662 touch_press->set_root_location_f(anchor_point_);
658 DispatchEvent(touch_press.get()); 663 DispatchEvent(touch_press.get());
659 664
660 std::unique_ptr<ui::TouchEvent> touch_release; 665 std::unique_ptr<ui::TouchEvent> touch_release;
661 touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), 666 touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
662 Now(), 667 Now(),
663 initial_press_->pointer_details())); 668 initial_press_->pointer_details()));
664 touch_release->set_location_f(anchor_point_); 669 touch_release->set_location_f(anchor_point_);
665 touch_release->set_root_location_f(anchor_point_); 670 touch_release->set_root_location_f(anchor_point_);
666 DispatchEvent(touch_release.get()); 671 DispatchEvent(touch_release.get());
667 } 672 }
668 673
674 void TouchExplorationController::MaybeSendSimulatedTapInLiftActivationBounds(
675 const ui::TouchEvent& event) {
676 gfx::Point location = event.location();
677 root_window_->GetHost()->ConvertScreenInPixelsToDIP(&location);
678 if (lift_activation_bounds_.Contains(anchor_point_.x(), anchor_point_.y()) &&
679 lift_activation_bounds_.Contains(location)) {
680 SendSimulatedTap();
681 }
682 }
683
669 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 684 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
670 const ui::TouchEvent& event, 685 const ui::TouchEvent& event,
671 std::unique_ptr<ui::Event>* rewritten_event) { 686 std::unique_ptr<ui::Event>* rewritten_event) {
672 // The timer should not fire when sliding. 687 // The timer should not fire when sliding.
673 tap_timer_.Stop(); 688 tap_timer_.Stop();
674 689
675 ui::EventType type = event.type(); 690 ui::EventType type = event.type();
676 // If additional fingers are added before a swipe gesture has been registered, 691 // If additional fingers are added before a swipe gesture has been registered,
677 // then wait until all fingers have been lifted. 692 // then wait until all fingers have been lifted.
678 if (type == ui::ET_TOUCH_PRESSED || 693 if (type == ui::ET_TOUCH_PRESSED ||
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 return "TWO_FINGER_TAP"; 1207 return "TWO_FINGER_TAP";
1193 } 1208 }
1194 return "Not a state"; 1209 return "Not a state";
1195 } 1210 }
1196 1211
1197 float TouchExplorationController::GetSplitTapTouchSlop() { 1212 float TouchExplorationController::GetSplitTapTouchSlop() {
1198 return gesture_detector_config_.touch_slop * 3; 1213 return gesture_detector_config_.touch_slop * 3;
1199 } 1214 }
1200 1215
1201 } // namespace ui 1216 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698