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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 case GESTURE_IN_PROGRESS: | 127 case GESTURE_IN_PROGRESS: |
128 return InGestureInProgress(touch_event, rewritten_event); | 128 return InGestureInProgress(touch_event, rewritten_event); |
129 case TOUCH_EXPLORE_SECOND_PRESS: | 129 case TOUCH_EXPLORE_SECOND_PRESS: |
130 return InTouchExploreSecondPress(touch_event, rewritten_event); | 130 return InTouchExploreSecondPress(touch_event, rewritten_event); |
131 case SLIDE_GESTURE: | 131 case SLIDE_GESTURE: |
132 return InSlideGesture(touch_event, rewritten_event); | 132 return InSlideGesture(touch_event, rewritten_event); |
133 case ONE_FINGER_PASSTHROUGH: | 133 case ONE_FINGER_PASSTHROUGH: |
134 return InOneFingerPassthrough(touch_event, rewritten_event); | 134 return InOneFingerPassthrough(touch_event, rewritten_event); |
135 case WAIT_FOR_ONE_FINGER: | 135 case WAIT_FOR_ONE_FINGER: |
136 return InWaitForOneFinger(touch_event, rewritten_event); | 136 return InWaitForOneFinger(touch_event, rewritten_event); |
| 137 case TWO_FINGER_TAP: |
| 138 return InTwoFingerTap(touch_event, rewritten_event); |
137 } | 139 } |
138 NOTREACHED(); | 140 NOTREACHED(); |
139 return ui::EVENT_REWRITE_CONTINUE; | 141 return ui::EVENT_REWRITE_CONTINUE; |
140 } | 142 } |
141 | 143 |
142 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 144 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
143 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 145 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
144 NOTREACHED(); | 146 NOTREACHED(); |
145 return ui::EVENT_REWRITE_CONTINUE; | 147 return ui::EVENT_REWRITE_CONTINUE; |
146 } | 148 } |
147 | 149 |
148 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 150 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
149 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 151 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
150 const ui::EventType type = event.type(); | 152 const ui::EventType type = event.type(); |
151 if (type == ui::ET_TOUCH_PRESSED) { | 153 if (type != ui::ET_TOUCH_PRESSED) { |
152 initial_press_.reset(new TouchEvent(event)); | 154 NOTREACHED() << "Unexpected event type received: " << event.name(); |
153 last_unused_finger_event_.reset(new TouchEvent(event)); | 155 return ui::EVENT_REWRITE_CONTINUE; |
154 StartTapTimer(); | |
155 gesture_provider_.OnTouchEvent(event); | |
156 gesture_provider_.OnTouchEventAck(false); | |
157 ProcessGestureEvents(); | |
158 state_ = SINGLE_TAP_PRESSED; | |
159 VLOG_STATE(); | |
160 return ui::EVENT_REWRITE_DISCARD; | |
161 } | 156 } |
162 NOTREACHED() << "Unexpected event type received: " << event.name(); | 157 initial_press_.reset(new TouchEvent(event)); |
163 return ui::EVENT_REWRITE_CONTINUE; | 158 initial_presses_[event.touch_id()] = event.location(); |
| 159 last_unused_finger_event_.reset(new TouchEvent(event)); |
| 160 StartTapTimer(); |
| 161 gesture_provider_.OnTouchEvent(event); |
| 162 gesture_provider_.OnTouchEventAck(false); |
| 163 ProcessGestureEvents(); |
| 164 state_ = SINGLE_TAP_PRESSED; |
| 165 VLOG_STATE(); |
| 166 return ui::EVENT_REWRITE_DISCARD; |
164 } | 167 } |
165 | 168 |
166 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 169 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
168 const ui::EventType type = event.type(); | 171 const ui::EventType type = event.type(); |
169 | 172 |
170 if (type == ui::ET_TOUCH_PRESSED) { | 173 if (type == ui::ET_TOUCH_PRESSED) { |
171 // TODO (evy, lisayin) : add support for multifinger swipes. | 174 initial_presses_[event.touch_id()] = event.location(); |
172 // For now, we wait for there to be only one finger down again. | 175 state_ = TWO_FINGER_TAP; |
173 state_ = WAIT_FOR_ONE_FINGER; | 176 VLOG_STATE(); |
174 return EVENT_REWRITE_DISCARD; | 177 return EVENT_REWRITE_DISCARD; |
175 } 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) { |
176 if (current_touch_ids_.size() == 0 && | 179 if (current_touch_ids_.size() == 0 && |
177 event.touch_id() == initial_press_->touch_id()) { | 180 event.touch_id() == initial_press_->touch_id()) { |
178 state_ = SINGLE_TAP_RELEASED; | 181 state_ = SINGLE_TAP_RELEASED; |
179 VLOG_STATE(); | 182 VLOG_STATE(); |
180 } else if (current_touch_ids_.size() == 0) { | 183 } else if (current_touch_ids_.size() == 0) { |
181 ResetToNoFingersDown(); | 184 ResetToNoFingersDown(); |
182 } | 185 } |
183 return EVENT_REWRITE_DISCARD; | 186 return EVENT_REWRITE_DISCARD; |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 if (current_touch_ids_.size() == 0) { | 545 if (current_touch_ids_.size() == 0) { |
543 ResetToNoFingersDown(); | 546 ResetToNoFingersDown(); |
544 } | 547 } |
545 return ui::EVENT_REWRITE_DISCARD; | 548 return ui::EVENT_REWRITE_DISCARD; |
546 } | 549 } |
547 | 550 |
548 ProcessGestureEvents(); | 551 ProcessGestureEvents(); |
549 return ui::EVENT_REWRITE_DISCARD; | 552 return ui::EVENT_REWRITE_DISCARD; |
550 } | 553 } |
551 | 554 |
| 555 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( |
| 556 const ui::TouchEvent& event, |
| 557 scoped_ptr<ui::Event>* rewritten_event) { |
| 558 ui::EventType type = event.type(); |
| 559 if (type == ui::ET_TOUCH_PRESSED) { |
| 560 // TODO(evy): Process three finger gestures here. |
| 561 state_ = WAIT_FOR_ONE_FINGER; |
| 562 VLOG_STATE(); |
| 563 return ui::EVENT_REWRITE_DISCARD; |
| 564 } |
| 565 |
| 566 if (type == ui::ET_TOUCH_MOVED) { |
| 567 // Determine if it was a swipe. |
| 568 gfx::Point original_location = initial_presses_[event.touch_id()]; |
| 569 float distance = (event.location() - original_location).Length(); |
| 570 // If the user moves too far from the original position, consider the |
| 571 // movement a swipe. |
| 572 // TODO(evy, lisayin): Add multifinger swipe processing. |
| 573 if (distance > gesture_detector_config_.touch_slop) { |
| 574 state_ = WAIT_FOR_ONE_FINGER; |
| 575 } |
| 576 return ui::EVENT_REWRITE_DISCARD; |
| 577 } |
| 578 |
| 579 if (current_touch_ids_.size() != 0) |
| 580 return ui::EVENT_REWRITE_DISCARD; |
| 581 |
| 582 if (type == ui::ET_TOUCH_RELEASED) { |
| 583 // In ChromeVox, pressing control will stop ChromeVox from speaking. |
| 584 ui::KeyEvent control_down( |
| 585 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN); |
| 586 ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE); |
| 587 |
| 588 DispatchEvent(&control_down); |
| 589 DispatchEvent(&control_up); |
| 590 |
| 591 ResetToNoFingersDown(); |
| 592 return ui::EVENT_REWRITE_DISCARD; |
| 593 } |
| 594 return ui::EVENT_REWRITE_DISCARD; |
| 595 } |
| 596 |
552 base::TimeDelta TouchExplorationController::Now() { | 597 base::TimeDelta TouchExplorationController::Now() { |
553 if (tick_clock_) { | 598 if (tick_clock_) { |
554 // This is the same as what EventTimeForNow() does, but here we do it | 599 // This is the same as what EventTimeForNow() does, but here we do it |
555 // with a clock that can be replaced with a simulated clock for tests. | 600 // with a clock that can be replaced with a simulated clock for tests. |
556 return base::TimeDelta::FromInternalValue( | 601 return base::TimeDelta::FromInternalValue( |
557 tick_clock_->NowTicks().ToInternalValue()); | 602 tick_clock_->NowTicks().ToInternalValue()); |
558 } | 603 } |
559 return ui::EventTimeForNow(); | 604 return ui::EventTimeForNow(); |
560 } | 605 } |
561 | 606 |
(...skipping 26 matching lines...) Expand all Loading... |
588 DispatchEvent(passthrough_press.get()); | 633 DispatchEvent(passthrough_press.get()); |
589 return; | 634 return; |
590 } | 635 } |
591 case SINGLE_TAP_PRESSED: | 636 case SINGLE_TAP_PRESSED: |
592 case GESTURE_IN_PROGRESS: | 637 case GESTURE_IN_PROGRESS: |
593 // Discard any pending gestures. | 638 // Discard any pending gestures. |
594 delete gesture_provider_.GetAndResetPendingGestures(); | 639 delete gesture_provider_.GetAndResetPendingGestures(); |
595 state_ = TOUCH_EXPLORATION; | 640 state_ = TOUCH_EXPLORATION; |
596 VLOG_STATE(); | 641 VLOG_STATE(); |
597 break; | 642 break; |
| 643 case TWO_FINGER_TAP: |
| 644 state_ = WAIT_FOR_ONE_FINGER; |
| 645 VLOG_STATE(); |
| 646 break; |
598 default: | 647 default: |
599 return; | 648 return; |
600 } | 649 } |
601 EnterTouchToMouseMode(); | 650 EnterTouchToMouseMode(); |
602 scoped_ptr<ui::Event> mouse_move = | 651 scoped_ptr<ui::Event> mouse_move = |
603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 652 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
604 DispatchEvent(mouse_move.get()); | 653 DispatchEvent(mouse_move.get()); |
605 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 654 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
606 } | 655 } |
607 | 656 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 aura::client::CursorClient* cursor_client = | 842 aura::client::CursorClient* cursor_client = |
794 aura::client::GetCursorClient(root_window_); | 843 aura::client::GetCursorClient(root_window_); |
795 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 844 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
796 cursor_client->EnableMouseEvents(); | 845 cursor_client->EnableMouseEvents(); |
797 if (cursor_client && cursor_client->IsCursorVisible()) | 846 if (cursor_client && cursor_client->IsCursorVisible()) |
798 cursor_client->HideCursor(); | 847 cursor_client->HideCursor(); |
799 } | 848 } |
800 | 849 |
801 void TouchExplorationController::ResetToNoFingersDown() { | 850 void TouchExplorationController::ResetToNoFingersDown() { |
802 ProcessGestureEvents(); | 851 ProcessGestureEvents(); |
| 852 initial_presses_.clear(); |
803 if (sound_timer_.IsRunning()) | 853 if (sound_timer_.IsRunning()) |
804 sound_timer_.Stop(); | 854 sound_timer_.Stop(); |
805 state_ = NO_FINGERS_DOWN; | 855 state_ = NO_FINGERS_DOWN; |
806 VLOG_STATE(); | 856 VLOG_STATE(); |
807 if (tap_timer_.IsRunning()) | 857 if (tap_timer_.IsRunning()) |
808 tap_timer_.Stop(); | 858 tap_timer_.Stop(); |
809 } | 859 } |
810 | 860 |
811 void TouchExplorationController::VlogState(const char* function_name) { | 861 void TouchExplorationController::VlogState(const char* function_name) { |
812 if (!VLOG_on_) | 862 if (!VLOG_on_) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 case GESTURE_IN_PROGRESS: | 918 case GESTURE_IN_PROGRESS: |
869 return "GESTURE_IN_PROGRESS"; | 919 return "GESTURE_IN_PROGRESS"; |
870 case TOUCH_EXPLORE_SECOND_PRESS: | 920 case TOUCH_EXPLORE_SECOND_PRESS: |
871 return "TOUCH_EXPLORE_SECOND_PRESS"; | 921 return "TOUCH_EXPLORE_SECOND_PRESS"; |
872 case SLIDE_GESTURE: | 922 case SLIDE_GESTURE: |
873 return "SLIDE_GESTURE"; | 923 return "SLIDE_GESTURE"; |
874 case ONE_FINGER_PASSTHROUGH: | 924 case ONE_FINGER_PASSTHROUGH: |
875 return "ONE_FINGER_PASSTHROUGH"; | 925 return "ONE_FINGER_PASSTHROUGH"; |
876 case WAIT_FOR_ONE_FINGER: | 926 case WAIT_FOR_ONE_FINGER: |
877 return "WAIT_FOR_ONE_FINGER"; | 927 return "WAIT_FOR_ONE_FINGER"; |
| 928 case TWO_FINGER_TAP: |
| 929 return "TWO_FINGER_TAP"; |
878 } | 930 } |
879 return "Not a state"; | 931 return "Not a state"; |
880 } | 932 } |
881 | 933 |
882 } // namespace ui | 934 } // namespace ui |
OLD | NEW |