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" | |
8 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
9 #include "ui/aura/client/cursor_client.h" | 8 #include "ui/aura/client/cursor_client.h" |
10 #include "ui/aura/window.h" | 9 #include "ui/aura/window.h" |
11 #include "ui/aura/window_event_dispatcher.h" | 10 #include "ui/aura/window_event_dispatcher.h" |
12 #include "ui/aura/window_tree_host.h" | 11 #include "ui/aura/window_tree_host.h" |
13 #include "ui/events/event.h" | 12 #include "ui/events/event.h" |
14 #include "ui/events/event_processor.h" | 13 #include "ui/events/event_processor.h" |
| 14 #include "ui/gfx/geometry/rect.h" |
15 | 15 |
16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) | 16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) |
17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) | 17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) |
18 | 18 |
19 namespace ui { | 19 namespace ui { |
20 | 20 |
21 namespace { | 21 namespace { |
| 22 |
| 23 // Delay between adjustment sounds. |
| 24 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); |
| 25 |
22 // In ChromeOS, VKEY_LWIN is synonymous for the search key. | 26 // In ChromeOS, VKEY_LWIN is synonymous for the search key. |
23 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; | 27 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; |
24 } // namespace | 28 } // namespace |
25 | 29 |
26 TouchExplorationController::TouchExplorationController( | 30 TouchExplorationController::TouchExplorationController( |
27 aura::Window* root_window) | 31 aura::Window* root_window, |
| 32 TouchExplorationControllerDelegate* delegate) |
28 : root_window_(root_window), | 33 : root_window_(root_window), |
| 34 delegate_(delegate), |
29 state_(NO_FINGERS_DOWN), | 35 state_(NO_FINGERS_DOWN), |
30 event_handler_for_testing_(NULL), | 36 event_handler_for_testing_(NULL), |
31 gesture_provider_(this), | 37 gesture_provider_(this), |
32 prev_state_(NO_FINGERS_DOWN), | 38 prev_state_(NO_FINGERS_DOWN), |
33 VLOG_on_(true) { | 39 VLOG_on_(true) { |
34 CHECK(root_window); | 40 CHECK(root_window); |
35 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 41 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
36 } | 42 } |
37 | 43 |
38 TouchExplorationController::~TouchExplorationController() { | 44 TouchExplorationController::~TouchExplorationController() { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 const ui::EventType type = touch_event.type(); | 76 const ui::EventType type = touch_event.type(); |
71 const gfx::PointF& location = touch_event.location_f(); | 77 const gfx::PointF& location = touch_event.location_f(); |
72 const int touch_id = touch_event.touch_id(); | 78 const int touch_id = touch_event.touch_id(); |
73 | 79 |
74 // Always update touch ids and touch locations, so we can use those | 80 // Always update touch ids and touch locations, so we can use those |
75 // no matter what state we're in. | 81 // no matter what state we're in. |
76 if (type == ui::ET_TOUCH_PRESSED) { | 82 if (type == ui::ET_TOUCH_PRESSED) { |
77 current_touch_ids_.push_back(touch_id); | 83 current_touch_ids_.push_back(touch_id); |
78 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); | 84 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); |
79 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 85 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 86 // In order to avoid accidentally double tapping when moving off the edge of |
| 87 // the screen, the state will be rewritten to NoFingersDown. |
| 88 TouchEvent touch_event = static_cast<const TouchEvent&>(event); |
| 89 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != |
| 90 NO_EDGE) { |
| 91 if (current_touch_ids_.size() == 0) |
| 92 ResetToNoFingersDown(); |
| 93 } |
| 94 |
80 std::vector<int>::iterator it = std::find( | 95 std::vector<int>::iterator it = std::find( |
81 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); | 96 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); |
82 | 97 |
83 // Can happen if touch exploration is enabled while fingers were down. | 98 // Can happen if touch exploration is enabled while fingers were down. |
84 if (it == current_touch_ids_.end()) | 99 if (it == current_touch_ids_.end()) |
85 return ui::EVENT_REWRITE_CONTINUE; | 100 return ui::EVENT_REWRITE_CONTINUE; |
86 | 101 |
87 current_touch_ids_.erase(it); | 102 current_touch_ids_.erase(it); |
88 touch_locations_.erase(touch_id); | 103 touch_locations_.erase(touch_id); |
89 } else if (type == ui::ET_TOUCH_MOVED) { | 104 } else if (type == ui::ET_TOUCH_MOVED) { |
(...skipping 24 matching lines...) Expand all Loading... |
114 case GESTURE_IN_PROGRESS: | 129 case GESTURE_IN_PROGRESS: |
115 return InGestureInProgress(touch_event, rewritten_event); | 130 return InGestureInProgress(touch_event, rewritten_event); |
116 case TOUCH_EXPLORE_SECOND_PRESS: | 131 case TOUCH_EXPLORE_SECOND_PRESS: |
117 return InTouchExploreSecondPress(touch_event, rewritten_event); | 132 return InTouchExploreSecondPress(touch_event, rewritten_event); |
118 case TWO_TO_ONE_FINGER: | 133 case TWO_TO_ONE_FINGER: |
119 return InTwoToOneFinger(touch_event, rewritten_event); | 134 return InTwoToOneFinger(touch_event, rewritten_event); |
120 case PASSTHROUGH: | 135 case PASSTHROUGH: |
121 return InPassthrough(touch_event, rewritten_event); | 136 return InPassthrough(touch_event, rewritten_event); |
122 case WAIT_FOR_RELEASE: | 137 case WAIT_FOR_RELEASE: |
123 return InWaitForRelease(touch_event, rewritten_event); | 138 return InWaitForRelease(touch_event, rewritten_event); |
| 139 case SLIDE_GESTURE: |
| 140 return InSlideGesture(touch_event, rewritten_event); |
124 } | 141 } |
125 NOTREACHED(); | 142 NOTREACHED(); |
126 return ui::EVENT_REWRITE_CONTINUE; | 143 return ui::EVENT_REWRITE_CONTINUE; |
127 } | 144 } |
128 | 145 |
129 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 146 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
130 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 147 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
131 NOTREACHED(); | 148 NOTREACHED(); |
132 return ui::EVENT_REWRITE_CONTINUE; | 149 return ui::EVENT_REWRITE_CONTINUE; |
133 } | 150 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 | 201 |
185 float delta_time = | 202 float delta_time = |
186 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); | 203 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); |
187 float velocity = distance / delta_time; | 204 float velocity = distance / delta_time; |
188 VLOG(0) << "\n Delta time: " << delta_time | 205 VLOG(0) << "\n Delta time: " << delta_time |
189 << "\n Distance: " << distance | 206 << "\n Distance: " << distance |
190 << "\n Velocity of click: " << velocity | 207 << "\n Velocity of click: " << velocity |
191 << "\n Minimum swipe velocity: " | 208 << "\n Minimum swipe velocity: " |
192 << gesture_detector_config_.minimum_swipe_velocity; | 209 << gesture_detector_config_.minimum_swipe_velocity; |
193 | 210 |
| 211 // Change to slide gesture if the slide occurred at the right edge. |
| 212 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); |
| 213 if (edge & RIGHT_EDGE) { |
| 214 state_ = SLIDE_GESTURE; |
| 215 VLOG_STATE(); |
| 216 return InSlideGesture(event, rewritten_event); |
| 217 } |
| 218 |
194 // If the user moves fast enough from the initial touch location, start | 219 // If the user moves fast enough from the initial touch location, start |
195 // gesture detection. Otherwise, jump to the touch exploration mode early. | 220 // gesture detection. Otherwise, jump to the touch exploration mode early. |
196 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | 221 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { |
197 state_ = GESTURE_IN_PROGRESS; | 222 state_ = GESTURE_IN_PROGRESS; |
198 VLOG_STATE(); | 223 VLOG_STATE(); |
199 return InGestureInProgress(event, rewritten_event); | 224 return InGestureInProgress(event, rewritten_event); |
200 } | 225 } |
201 EnterTouchToMouseMode(); | 226 EnterTouchToMouseMode(); |
202 state_ = TOUCH_EXPLORATION; | 227 state_ = TOUCH_EXPLORATION; |
203 VLOG_STATE(); | 228 VLOG_STATE(); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 const ui::TouchEvent& event, | 344 const ui::TouchEvent& event, |
320 scoped_ptr<ui::Event>* rewritten_event) { | 345 scoped_ptr<ui::Event>* rewritten_event) { |
321 ui::EventType type = event.type(); | 346 ui::EventType type = event.type(); |
322 // If additional fingers are added before a swipe gesture has been registered, | 347 // If additional fingers are added before a swipe gesture has been registered, |
323 // then the state will no longer be GESTURE_IN_PROGRESS. | 348 // then the state will no longer be GESTURE_IN_PROGRESS. |
324 if (type == ui::ET_TOUCH_PRESSED || | 349 if (type == ui::ET_TOUCH_PRESSED || |
325 event.touch_id() != initial_press_->touch_id()) { | 350 event.touch_id() != initial_press_->touch_id()) { |
326 if (tap_timer_.IsRunning()) | 351 if (tap_timer_.IsRunning()) |
327 tap_timer_.Stop(); | 352 tap_timer_.Stop(); |
328 // Discard any pending gestures. | 353 // Discard any pending gestures. |
329 ignore_result(gesture_provider_.GetAndResetPendingGestures()); | 354 delete gesture_provider_.GetAndResetPendingGestures(); |
330 state_ = TWO_TO_ONE_FINGER; | 355 state_ = TWO_TO_ONE_FINGER; |
331 last_two_to_one_.reset(new TouchEvent(event)); | 356 last_two_to_one_.reset(new TouchEvent(event)); |
332 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 357 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
333 event.location(), | 358 event.location(), |
334 event.touch_id(), | 359 event.touch_id(), |
335 event.time_stamp())); | 360 event.time_stamp())); |
336 (*rewritten_event)->set_flags(event.flags()); | 361 (*rewritten_event)->set_flags(event.flags()); |
337 return EVENT_REWRITE_REWRITTEN; | 362 return EVENT_REWRITE_REWRITTEN; |
338 } | 363 } |
339 | 364 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 return ui::EVENT_REWRITE_CONTINUE; | 515 return ui::EVENT_REWRITE_CONTINUE; |
491 } | 516 } |
492 if (current_touch_ids_.size() == 0) { | 517 if (current_touch_ids_.size() == 0) { |
493 state_ = NO_FINGERS_DOWN; | 518 state_ = NO_FINGERS_DOWN; |
494 VLOG_STATE(); | 519 VLOG_STATE(); |
495 ResetToNoFingersDown(); | 520 ResetToNoFingersDown(); |
496 } | 521 } |
497 return EVENT_REWRITE_DISCARD; | 522 return EVENT_REWRITE_DISCARD; |
498 } | 523 } |
499 | 524 |
| 525 void TouchExplorationController::PlaySoundForTimer() { |
| 526 delegate_->PlayVolumeAdjustSound(); |
| 527 } |
| 528 |
| 529 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( |
| 530 const ui::TouchEvent& event, |
| 531 scoped_ptr<ui::Event>* rewritten_event) { |
| 532 // The timer should not fire when sliding. |
| 533 if (tap_timer_.IsRunning()) |
| 534 tap_timer_.Stop(); |
| 535 |
| 536 ui::EventType type = event.type(); |
| 537 // If additional fingers are added before a swipe gesture has been registered, |
| 538 // then wait until all fingers have been lifted. |
| 539 if (type == ui::ET_TOUCH_PRESSED || |
| 540 event.touch_id() != initial_press_->touch_id()) { |
| 541 if (sound_timer_.IsRunning()) |
| 542 sound_timer_.Stop(); |
| 543 // Discard any pending gestures. |
| 544 delete gesture_provider_.GetAndResetPendingGestures(); |
| 545 state_ = WAIT_FOR_RELEASE; |
| 546 return EVENT_REWRITE_DISCARD; |
| 547 } |
| 548 |
| 549 // Allows user to return to the edge to adjust the sound if they have left the |
| 550 // boundaries. |
| 551 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); |
| 552 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { |
| 553 if (sound_timer_.IsRunning()) { |
| 554 sound_timer_.Stop(); |
| 555 } |
| 556 return EVENT_REWRITE_DISCARD; |
| 557 } |
| 558 |
| 559 // This can occur if the user leaves the screen edge and then returns to it to |
| 560 // continue adjusting the sound. |
| 561 if (!sound_timer_.IsRunning()) { |
| 562 sound_timer_.Start(FROM_HERE, |
| 563 kSoundDelay, |
| 564 this, |
| 565 &ui::TouchExplorationController::PlaySoundForTimer); |
| 566 delegate_->PlayVolumeAdjustSound(); |
| 567 } |
| 568 |
| 569 // There should not be more than one finger down. |
| 570 DCHECK(current_touch_ids_.size() <= 1); |
| 571 if (type == ui::ET_TOUCH_MOVED) { |
| 572 gesture_provider_.OnTouchEvent(event); |
| 573 gesture_provider_.OnTouchEventAck(false); |
| 574 } |
| 575 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 576 gesture_provider_.OnTouchEvent(event); |
| 577 gesture_provider_.OnTouchEventAck(false); |
| 578 delete gesture_provider_.GetAndResetPendingGestures(); |
| 579 if (current_touch_ids_.size() == 0) |
| 580 ResetToNoFingersDown(); |
| 581 return ui::EVENT_REWRITE_DISCARD; |
| 582 } |
| 583 |
| 584 ProcessGestureEvents(); |
| 585 return ui::EVENT_REWRITE_DISCARD; |
| 586 } |
| 587 |
500 void TouchExplorationController::OnTapTimerFired() { | 588 void TouchExplorationController::OnTapTimerFired() { |
501 switch (state_) { | 589 switch (state_) { |
502 case SINGLE_TAP_RELEASED: | 590 case SINGLE_TAP_RELEASED: |
503 ResetToNoFingersDown(); | 591 ResetToNoFingersDown(); |
504 break; | 592 break; |
505 case TOUCH_EXPLORE_RELEASED: | 593 case TOUCH_EXPLORE_RELEASED: |
506 ResetToNoFingersDown(); | 594 ResetToNoFingersDown(); |
507 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 595 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
508 return; | 596 return; |
509 case SINGLE_TAP_PRESSED: | 597 case SINGLE_TAP_PRESSED: |
510 case GESTURE_IN_PROGRESS: | 598 case GESTURE_IN_PROGRESS: |
511 // Discard any pending gestures. | 599 // Discard any pending gestures. |
512 ignore_result(gesture_provider_.GetAndResetPendingGestures()); | 600 delete gesture_provider_.GetAndResetPendingGestures(); |
513 EnterTouchToMouseMode(); | 601 EnterTouchToMouseMode(); |
514 state_ = TOUCH_EXPLORATION; | 602 state_ = TOUCH_EXPLORATION; |
515 VLOG_STATE(); | 603 VLOG_STATE(); |
516 break; | 604 break; |
517 default: | 605 default: |
518 return; | 606 return; |
519 } | 607 } |
520 scoped_ptr<ui::Event> mouse_move = | 608 scoped_ptr<ui::Event> mouse_move = |
521 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 609 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
522 DispatchEvent(mouse_move.get()); | 610 DispatchEvent(mouse_move.get()); |
523 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 611 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
524 } | 612 } |
525 | 613 |
526 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 614 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
527 if (event_handler_for_testing_) { | 615 if (event_handler_for_testing_) { |
528 event_handler_for_testing_->OnEvent(event); | 616 event_handler_for_testing_->OnEvent(event); |
529 return; | 617 return; |
530 } | 618 } |
531 ui::EventDispatchDetails result ALLOW_UNUSED = | 619 ui::EventDispatchDetails result ALLOW_UNUSED = |
532 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 620 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
533 } | 621 } |
534 | 622 |
535 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { | 623 void TouchExplorationController::OnGestureEvent( |
| 624 ui::GestureEvent* gesture) { |
536 CHECK(gesture->IsGestureEvent()); | 625 CHECK(gesture->IsGestureEvent()); |
| 626 ui::EventType type = gesture->type(); |
537 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | 627 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); |
538 if (gesture->type() == ui::ET_GESTURE_SWIPE) { | 628 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) { |
539 if (tap_timer_.IsRunning()) | 629 VLOG(0) << "Swipe!"; |
540 tap_timer_.Stop(); | 630 delete gesture_provider_.GetAndResetPendingGestures(); |
541 OnSwipeEvent(gesture); | 631 OnSwipeEvent(gesture); |
542 return; | 632 return; |
543 } | 633 } |
544 } | 634 } |
545 | 635 |
546 void TouchExplorationController::ProcessGestureEvents() { | 636 void TouchExplorationController::ProcessGestureEvents() { |
547 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | 637 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( |
548 gesture_provider_.GetAndResetPendingGestures()); | 638 gesture_provider_.GetAndResetPendingGestures()); |
549 if (gestures) { | 639 if (gestures) { |
550 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | 640 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); |
551 i != gestures->end(); | 641 i != gestures->end(); |
552 ++i) { | 642 ++i) { |
553 OnGestureEvent(*i); | 643 if (state_ == SLIDE_GESTURE) |
| 644 SideSlideControl(*i); |
| 645 else |
| 646 OnGestureEvent(*i); |
554 } | 647 } |
555 } | 648 } |
556 } | 649 } |
557 | 650 |
| 651 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { |
| 652 ui::EventType type = gesture->type(); |
| 653 if (!gesture->IsScrollGestureEvent()) |
| 654 return; |
| 655 |
| 656 if (type == ET_GESTURE_SCROLL_BEGIN) { |
| 657 delegate_->PlayVolumeAdjustSound(); |
| 658 } |
| 659 |
| 660 if (type == ET_GESTURE_SCROLL_END) { |
| 661 if (sound_timer_.IsRunning()) |
| 662 sound_timer_.Stop(); |
| 663 delegate_->PlayVolumeAdjustSound(); |
| 664 } |
| 665 |
| 666 // If the user is in the corner of the right side of the screen, the volume |
| 667 // will be automatically set to 100% or muted depending on which corner they |
| 668 // are in. Otherwise, the user will be able to adjust the volume by sliding |
| 669 // their finger along the right side of the screen. Volume is relative to |
| 670 // where they are on the right side of the screen. |
| 671 gfx::Point location = gesture->location(); |
| 672 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); |
| 673 if (!(edge & RIGHT_EDGE)) |
| 674 return; |
| 675 |
| 676 if (edge & TOP_EDGE) { |
| 677 delegate_->SetOutputLevel(100); |
| 678 return; |
| 679 } |
| 680 if (edge & BOTTOM_EDGE) { |
| 681 delegate_->SetOutputLevel(0); |
| 682 return; |
| 683 } |
| 684 |
| 685 location = gesture->location(); |
| 686 root_window_->GetHost()->ConvertPointFromNativeScreen(&location); |
| 687 float volume_adjust_height = |
| 688 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge; |
| 689 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; |
| 690 float volume = 100 - 100 * ratio; |
| 691 VLOG(0) << "\n Volume = " << volume << "\n Location = " << location.ToString() |
| 692 << "\n Bounds = " << root_window_->bounds().right(); |
| 693 |
| 694 delegate_->SetOutputLevel(int(volume)); |
| 695 } |
| 696 |
| 697 |
558 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | 698 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
559 // A swipe gesture contains details for the direction in which the swipe | 699 // A swipe gesture contains details for the direction in which the swipe |
560 // occurred. | 700 // occurred. |
561 GestureEventDetails event_details = swipe_gesture->details(); | 701 GestureEventDetails event_details = swipe_gesture->details(); |
562 if (event_details.swipe_left()) { | 702 if (event_details.swipe_left()) { |
563 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); | 703 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); |
564 return; | 704 return; |
565 } else if (event_details.swipe_right()) { | 705 } else if (event_details.swipe_right()) { |
566 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); | 706 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); |
567 return; | 707 return; |
568 } else if (event_details.swipe_up()) { | 708 } else if (event_details.swipe_up()) { |
569 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | 709 DispatchShiftSearchKeyEvent(ui::VKEY_UP); |
570 return; | 710 return; |
571 } else if (event_details.swipe_down()) { | 711 } else if (event_details.swipe_down()) { |
572 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | 712 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); |
573 return; | 713 return; |
574 } | 714 } |
575 } | 715 } |
576 | 716 |
| 717 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, |
| 718 float bounds) { |
| 719 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be |
| 720 // converted. |
| 721 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); |
| 722 gfx::Rect window = root_window_->GetBoundsInScreen(); |
| 723 |
| 724 float left_edge_limit = window.x() + bounds; |
| 725 float right_edge_limit = window.right() - bounds; |
| 726 float top_edge_limit = window.y() + bounds; |
| 727 float bottom_edge_limit = window.bottom() - bounds; |
| 728 |
| 729 // Bitwise manipulation in order to determine where on the screen the point |
| 730 // lies. If more than one bit is turned on, then it is a corner where the two |
| 731 // bit/edges intersect. Otherwise, if no bits are turned on, the point must be |
| 732 // in the center of the screen. |
| 733 int result = NO_EDGE; |
| 734 if (point.x() < left_edge_limit) |
| 735 result |= LEFT_EDGE; |
| 736 if (point.x() > right_edge_limit) |
| 737 result |= RIGHT_EDGE; |
| 738 if (point.y() < top_edge_limit) |
| 739 result |= TOP_EDGE; |
| 740 if (point.y() > bottom_edge_limit) |
| 741 result |= BOTTOM_EDGE; |
| 742 return result; |
| 743 } |
| 744 |
577 void TouchExplorationController::DispatchShiftSearchKeyEvent( | 745 void TouchExplorationController::DispatchShiftSearchKeyEvent( |
578 const ui::KeyboardCode direction) { | 746 const ui::KeyboardCode direction) { |
579 // In order to activate the shortcut shift+search+<arrow key> | 747 // In order to activate the shortcut shift+search+<arrow key> |
580 // three KeyPressed events must be dispatched in succession along | 748 // three KeyPressed events must be dispatched in succession along |
581 // with three KeyReleased events. | 749 // with three KeyReleased events. |
582 ui::KeyEvent shift_down = ui::KeyEvent( | 750 ui::KeyEvent shift_down = ui::KeyEvent( |
583 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false); | 751 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false); |
584 ui::KeyEvent search_down = ui::KeyEvent( | 752 ui::KeyEvent search_down = ui::KeyEvent( |
585 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false); | 753 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false); |
586 ui::KeyEvent direction_down = | 754 ui::KeyEvent direction_down = |
(...skipping 29 matching lines...) Expand all Loading... |
616 void TouchExplorationController::EnterTouchToMouseMode() { | 784 void TouchExplorationController::EnterTouchToMouseMode() { |
617 aura::client::CursorClient* cursor_client = | 785 aura::client::CursorClient* cursor_client = |
618 aura::client::GetCursorClient(root_window_); | 786 aura::client::GetCursorClient(root_window_); |
619 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 787 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
620 cursor_client->EnableMouseEvents(); | 788 cursor_client->EnableMouseEvents(); |
621 if (cursor_client && cursor_client->IsCursorVisible()) | 789 if (cursor_client && cursor_client->IsCursorVisible()) |
622 cursor_client->HideCursor(); | 790 cursor_client->HideCursor(); |
623 } | 791 } |
624 | 792 |
625 void TouchExplorationController::ResetToNoFingersDown() { | 793 void TouchExplorationController::ResetToNoFingersDown() { |
| 794 ProcessGestureEvents(); |
| 795 if (sound_timer_.IsRunning()) |
| 796 sound_timer_.Stop(); |
626 state_ = NO_FINGERS_DOWN; | 797 state_ = NO_FINGERS_DOWN; |
627 VLOG_STATE(); | 798 VLOG_STATE(); |
628 if (tap_timer_.IsRunning()) | 799 if (tap_timer_.IsRunning()) |
629 tap_timer_.Stop(); | 800 tap_timer_.Stop(); |
630 } | 801 } |
631 | 802 |
632 void TouchExplorationController::VlogState(const char* function_name) { | 803 void TouchExplorationController::VlogState(const char* function_name) { |
633 if (!VLOG_on_) | 804 if (!VLOG_on_) |
634 return; | 805 return; |
635 if (prev_state_ == state_) | 806 if (prev_state_ == state_) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 case GESTURE_IN_PROGRESS: | 858 case GESTURE_IN_PROGRESS: |
688 return "GESTURE_IN_PROGRESS"; | 859 return "GESTURE_IN_PROGRESS"; |
689 case TOUCH_EXPLORE_SECOND_PRESS: | 860 case TOUCH_EXPLORE_SECOND_PRESS: |
690 return "TOUCH_EXPLORE_SECOND_PRESS"; | 861 return "TOUCH_EXPLORE_SECOND_PRESS"; |
691 case TWO_TO_ONE_FINGER: | 862 case TWO_TO_ONE_FINGER: |
692 return "TWO_TO_ONE_FINGER"; | 863 return "TWO_TO_ONE_FINGER"; |
693 case PASSTHROUGH: | 864 case PASSTHROUGH: |
694 return "PASSTHROUGH"; | 865 return "PASSTHROUGH"; |
695 case WAIT_FOR_RELEASE: | 866 case WAIT_FOR_RELEASE: |
696 return "WAIT_FOR_RELEASE"; | 867 return "WAIT_FOR_RELEASE"; |
| 868 case SLIDE_GESTURE: |
| 869 return "SLIDE_GESTURE"; |
697 } | 870 } |
698 return "Not a state"; | 871 return "Not a state"; |
699 } | 872 } |
700 | 873 |
701 } // namespace ui | 874 } // namespace ui |
OLD | NEW |