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

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

Issue 385073009: Side Slide Gestures for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added Tests for Slide Gestures Created 6 years, 5 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 "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 int SignOf(float number) {
23 if (number == 0)
24 return 0;
25 return number > 0 ? 1 : -1;
26 }
27
28 // Delay between adjustment sounds.
29 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
30
31 // Minimum Volume adjustment.
32 const float kMinPercentVolumeChange = 1;
33
34 // Swipe/scroll gestures within these bounds (in dips) will change preset
35 // settings.
36 const float kMaxDistanceFromEdge = 75;
37
38 // After a slide gesture has been triggered, if the finger is still within these
39 // bounds, the preset settings will still change.
40 const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40;
41
22 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 42 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
23 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 43 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
24 } // namespace 44 } // namespace
25 45
26 TouchExplorationController::TouchExplorationController( 46 TouchExplorationController::TouchExplorationController(
27 aura::Window* root_window) 47 aura::Window* root_window,
48 TouchExplorationControllerDelegate* delegate)
28 : root_window_(root_window), 49 : root_window_(root_window),
29 state_(NO_FINGERS_DOWN), 50 state_(NO_FINGERS_DOWN),
30 event_handler_for_testing_(NULL), 51 event_handler_for_testing_(NULL),
31 gesture_provider_(this), 52 gesture_provider_(this),
32 prev_state_(NO_FINGERS_DOWN), 53 prev_state_(NO_FINGERS_DOWN),
33 VLOG_on_(true) { 54 VLOG_on_(true) {
34 CHECK(root_window); 55 CHECK(root_window);
35 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 56 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
57 delegate_.reset(delegate);
dmazzoni 2014/07/14 18:00:34 Do this as an initializer before the initial {, as
lisayin 2014/07/14 22:38:38 Done.
36 } 58 }
37 59
38 60
39 TouchExplorationController::~TouchExplorationController() { 61 TouchExplorationController::~TouchExplorationController() {
40 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 62 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
41 } 63 }
42 64
43 void TouchExplorationController::CallTapTimerNowForTesting() { 65 void TouchExplorationController::CallTapTimerNowForTesting() {
44 DCHECK(tap_timer_.IsRunning()); 66 DCHECK(tap_timer_.IsRunning());
45 tap_timer_.Stop(); 67 tap_timer_.Stop();
(...skipping 14 matching lines...) Expand all
60 82
61 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const { 83 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const {
62 return state_ == NO_FINGERS_DOWN; 84 return state_ == NO_FINGERS_DOWN;
63 } 85 }
64 86
65 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const { 87 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const {
66 return state_ == GESTURE_IN_PROGRESS; 88 return state_ == GESTURE_IN_PROGRESS;
67 } 89 }
68 90
69 void TouchExplorationController::SuppressVLOGsForTesting(bool suppress) { 91 void TouchExplorationController::SuppressVLOGsForTesting(bool suppress) {
70 VLOG_on_ = !suppress; 92 VLOG_on_ = !suppress;
93 }
94
95 gfx::Rect TouchExplorationController::BoundsOfWindowInDIPForTesting() {
dmazzoni 2014/07/14 18:00:33 This should be BoundsOfRootWindow...?
lisayin 2014/07/14 22:38:38 Done.
96 return root_window_->GetBoundsInScreen();
97 }
98
99 bool TouchExplorationController::IsInSlideGestureStateForTesting() const {
100 return state_ == SLIDE_GESTURE;
71 } 101 }
72 102
73 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 103 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
74 const ui::Event& event, 104 const ui::Event& event,
75 scoped_ptr<ui::Event>* rewritten_event) { 105 scoped_ptr<ui::Event>* rewritten_event) {
76 if (!event.IsTouchEvent()) { 106 if (!event.IsTouchEvent()) {
77 if (event.IsKeyEvent()) { 107 if (event.IsKeyEvent()) {
78 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); 108 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
79 VLOG(0) << "\nKeyboard event: " << key_event.name() 109 VLOG(0) << "\nKeyboard event: " << key_event.name()
80 << "\n Key code: " << key_event.key_code() 110 << "\n Key code: " << key_event.key_code()
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 case GESTURE_IN_PROGRESS: 175 case GESTURE_IN_PROGRESS:
146 return InGestureInProgress(touch_event, rewritten_event); 176 return InGestureInProgress(touch_event, rewritten_event);
147 case TOUCH_EXPLORE_SECOND_PRESS: 177 case TOUCH_EXPLORE_SECOND_PRESS:
148 return InTouchExploreSecondPress(touch_event, rewritten_event); 178 return InTouchExploreSecondPress(touch_event, rewritten_event);
149 case TWO_TO_ONE_FINGER: 179 case TWO_TO_ONE_FINGER:
150 return InTwoToOneFinger(touch_event, rewritten_event); 180 return InTwoToOneFinger(touch_event, rewritten_event);
151 case PASSTHROUGH: 181 case PASSTHROUGH:
152 return InPassthrough(touch_event, rewritten_event); 182 return InPassthrough(touch_event, rewritten_event);
153 case WAIT_FOR_RELEASE: 183 case WAIT_FOR_RELEASE:
154 return InWaitForRelease(touch_event, rewritten_event); 184 return InWaitForRelease(touch_event, rewritten_event);
185 case SLIDE_GESTURE:
186 return InSlideGesture(touch_event, rewritten_event);
155 } 187 }
156 NOTREACHED(); 188 NOTREACHED();
157 return ui::EVENT_REWRITE_CONTINUE; 189 return ui::EVENT_REWRITE_CONTINUE;
158 } 190 }
159 191
160 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 192 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
161 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 193 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
162 NOTREACHED(); 194 NOTREACHED();
163 return ui::EVENT_REWRITE_CONTINUE; 195 return ui::EVENT_REWRITE_CONTINUE;
164 } 196 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 247
216 float delta_time = 248 float delta_time =
217 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 249 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
218 float velocity = distance / delta_time; 250 float velocity = distance / delta_time;
219 VLOG(0) << "\n Delta time: " << delta_time 251 VLOG(0) << "\n Delta time: " << delta_time
220 << "\n Distance: " << distance 252 << "\n Distance: " << distance
221 << "\n Velocity of click: " << velocity 253 << "\n Velocity of click: " << velocity
222 << "\n Minimum swipe velocity: " 254 << "\n Minimum swipe velocity: "
223 << gesture_detector_config_.minimum_swipe_velocity; 255 << gesture_detector_config_.minimum_swipe_velocity;
224 256
257 // Change to slide gesture if the slide occurred at the right edge.
258 int where = WithinBoundsOfEdge(event.location(), kMaxDistanceFromEdge);
259 if ((where | RIGHT_EDGE) == where) {
260 state_ = SLIDE_GESTURE;
261 VLOG_STATE();
262 return InSlideGesture(event, rewritten_event);
263 }
264
225 // If the user moves fast enough from the initial touch location, start 265 // If the user moves fast enough from the initial touch location, start
226 // gesture detection. Otherwise, jump to the touch exploration mode early. 266 // gesture detection. Otherwise, jump to the touch exploration mode early.
227 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 267 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
228 state_ = GESTURE_IN_PROGRESS; 268 state_ = GESTURE_IN_PROGRESS;
229 VLOG_STATE(); 269 VLOG_STATE();
230 return InGestureInProgress(event, rewritten_event); 270 return InGestureInProgress(event, rewritten_event);
231 } 271 }
232 EnterTouchToMouseMode(); 272 EnterTouchToMouseMode();
233 state_ = TOUCH_EXPLORATION; 273 state_ = TOUCH_EXPLORATION;
234 VLOG_STATE(); 274 VLOG_STATE();
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 if (current_touch_ids_.size() != 1) 535 if (current_touch_ids_.size() != 1)
496 return EVENT_REWRITE_DISCARD; 536 return EVENT_REWRITE_DISCARD;
497 537
498 // Rewrite at location of last touch exploration. 538 // Rewrite at location of last touch exploration.
499 rewritten_event->reset( 539 rewritten_event->reset(
500 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 540 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
501 last_touch_exploration_->location(), 541 last_touch_exploration_->location(),
502 initial_press_->touch_id(), 542 initial_press_->touch_id(),
503 event.time_stamp())); 543 event.time_stamp()));
504 (*rewritten_event)->set_flags(event.flags()); 544 (*rewritten_event)->set_flags(event.flags());
545 EnterTouchToMouseMode();
505 state_ = TOUCH_EXPLORATION; 546 state_ = TOUCH_EXPLORATION;
506 EnterTouchToMouseMode(); 547 EnterTouchToMouseMode();
507 VLOG_STATE(); 548 VLOG_STATE();
508 return ui::EVENT_REWRITE_REWRITTEN; 549 return ui::EVENT_REWRITE_REWRITTEN;
509 } 550 }
510 NOTREACHED() << "Unexpected event type received: " << event.name(); 551 NOTREACHED() << "Unexpected event type received: " << event.name();
511 return ui::EVENT_REWRITE_CONTINUE; 552 return ui::EVENT_REWRITE_CONTINUE;
512 } 553 }
513 554
514 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( 555 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease(
515 const ui::TouchEvent& event, 556 const ui::TouchEvent& event,
516 scoped_ptr<ui::Event>* rewritten_event) { 557 scoped_ptr<ui::Event>* rewritten_event) {
517 ui::EventType type = event.type(); 558 ui::EventType type = event.type();
518 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 559 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
519 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 560 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
520 NOTREACHED() << "Unexpected event type received: " << event.name(); 561 NOTREACHED() << "Unexpected event type received: " << event.name();
521 return ui::EVENT_REWRITE_CONTINUE; 562 return ui::EVENT_REWRITE_CONTINUE;
522 } 563 }
523 if (current_touch_ids_.size() == 0) { 564 if (current_touch_ids_.size() == 0) {
524 state_ = NO_FINGERS_DOWN; 565 state_ = NO_FINGERS_DOWN;
525 VLOG_STATE(); 566 VLOG_STATE();
526 ResetToNoFingersDown(); 567 ResetToNoFingersDown();
527 } 568 }
528 return EVENT_REWRITE_DISCARD; 569 return EVENT_REWRITE_DISCARD;
529 } 570 }
530 571
572 void TouchExplorationController::PlaySoundForTimer() {
573 delegate_->PlayVolumeAdjustSound();
574 }
575
576 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
577 const ui::TouchEvent& event,
578 scoped_ptr<ui::Event>* rewritten_event) {
579 ui::EventType type = event.type();
580 // If additional fingers are added before a swipe gesture has been registered,
581 // then wait until all fingers have been released.
dmazzoni 2014/07/14 18:00:34 This comment doesn't seem to describe what the cod
lisayin 2014/07/14 22:38:38 Done.
582 if (type == ui::ET_TOUCH_PRESSED ||
583 event.touch_id() != initial_press_->touch_id()) {
584 if (tap_timer_.IsRunning())
585 tap_timer_.Stop();
586 // Discard any pending gestures.
587 ignore_result(gesture_provider_.GetAndResetPendingGestures());
588 state_ = TWO_TO_ONE_FINGER;
589 last_two_to_one_.reset(new TouchEvent(event));
590 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
591 event.location(),
592 event.touch_id(),
593 event.time_stamp()));
594 (*rewritten_event)->set_flags(event.flags());
595 return EVENT_REWRITE_REWRITTEN;
596 }
597
598 VLOG(0) << "Location " << event.location().ToString();
599 // Allows user to return to the edge to adjust the sound if they have left the
600 // boundaries.
601 int where = WithinBoundsOfEdge(event.location(), kSlopDistanceFromEdge);
602 if (((where | RIGHT_EDGE) != where) && (type != ui::ET_TOUCH_RELEASED)) {
603 if (sound_timer_.IsRunning()) {
604 sound_timer_.Stop();
605 }
606 return EVENT_REWRITE_DISCARD;
607 }
608
609 // This can occur if the user leaves the screen edge and then returns to it to
610 // continue adjusting the sound.
611 if (!sound_timer_.IsRunning()) {
612 sound_timer_.Start(FROM_HERE,
613 kSoundDelay,
614 this,
615 &ui::TouchExplorationController::PlaySoundForTimer);
616 delegate_->PlayVolumeAdjustSound();
617 }
618 // The timer should not fire when sliding.
619 if (tap_timer_.IsRunning())
620 tap_timer_.Stop();
621
622 // There should not be more than one finger down.
623 DCHECK(current_touch_ids_.size() <= 1);
624 if (type == ui::ET_TOUCH_MOVED) {
625 gesture_provider_.OnTouchEvent(event);
626 gesture_provider_.OnTouchEventAck(false);
627 }
628 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
629 gesture_provider_.OnTouchEvent(event);
630 gesture_provider_.OnTouchEventAck(false);
631 ignore_result(gesture_provider_.GetAndResetPendingGestures());
632 if (current_touch_ids_.size() == 0)
633 ResetToNoFingersDown();
634 return ui::EVENT_REWRITE_DISCARD;
635 }
636
637 ProcessGestureEvents();
638 return ui::EVENT_REWRITE_DISCARD;
639 }
640
531 void TouchExplorationController::OnTapTimerFired() { 641 void TouchExplorationController::OnTapTimerFired() {
532 switch (state_) { 642 switch (state_) {
533 case SINGLE_TAP_RELEASED: 643 case SINGLE_TAP_RELEASED:
534 ResetToNoFingersDown(); 644 ResetToNoFingersDown();
535 break; 645 break;
536 case TOUCH_EXPLORE_RELEASED: 646 case TOUCH_EXPLORE_RELEASED:
537 ResetToNoFingersDown(); 647 ResetToNoFingersDown();
538 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 648 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
539 return; 649 return;
540 case SINGLE_TAP_PRESSED: 650 case SINGLE_TAP_PRESSED:
541 case GESTURE_IN_PROGRESS: 651 case GESTURE_IN_PROGRESS:
542 // Discard any pending gestures. 652 // Discard any pending gestures.
543 ignore_result(gesture_provider_.GetAndResetPendingGestures()); 653 ignore_result(gesture_provider_.GetAndResetPendingGestures());
544 EnterTouchToMouseMode(); 654 EnterTouchToMouseMode();
545 state_ = TOUCH_EXPLORATION; 655 state_ = TOUCH_EXPLORATION;
546 VLOG_STATE(); 656 VLOG_STATE();
547 break; 657 break;
548 default: 658 default:
549 return; 659 return;
550 } 660 }
551 scoped_ptr<ui::Event> mouse_move = 661 scoped_ptr<ui::Event> mouse_move =
552 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 662 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
553 DispatchEvent(mouse_move.get()); 663 DispatchEvent(mouse_move.get());
554 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 664 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
555 } 665 }
556 666
557 void TouchExplorationController::DispatchEvent(ui::Event* event) { 667 void TouchExplorationController::DispatchEvent(ui::Event* event) {
558 if (event_handler_for_testing_) { 668 if (event_handler_for_testing_) {
559 event_handler_for_testing_->OnEvent(event); 669 event_handler_for_testing_->OnEvent(event);
560 return; 670 return;
561 } 671 }
562 ui::EventDispatchDetails result ALLOW_UNUSED = 672 ui::EventDispatchDetails result ALLOW_UNUSED =
563 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 673 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
564 } 674 }
565 675
566 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { 676 void TouchExplorationController::OnGestureEvent(
677 ui::GestureEvent* gesture) {
567 CHECK(gesture->IsGestureEvent()); 678 CHECK(gesture->IsGestureEvent());
679 ui::EventType type = gesture->type();
568 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); 680 VLOG(0) << " \n Gesture Triggered: " << gesture->name();
569 if (gesture->type() == ui::ET_GESTURE_SWIPE) { 681 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) {
570 if (tap_timer_.IsRunning()) 682 VLOG(0) << "Swipe!";
571 tap_timer_.Stop(); 683 ignore_result(gesture_provider_.GetAndResetPendingGestures());
572 OnSwipeEvent(gesture); 684 OnSwipeEvent(gesture);
573 return; 685 return;
574 } 686 }
687 if (gesture->IsScrollGestureEvent() && state_ == SLIDE_GESTURE) {
688 SideSlideControl(gesture);
dmazzoni 2014/07/14 18:00:33 Why are you using the gesture detector for slides?
lisayin 2014/07/14 22:38:38 Done.
689 VLOG(0) << "Sliding";
690 return;
691 }
575 } 692 }
576 693
577 void TouchExplorationController::ProcessGestureEvents() { 694 void TouchExplorationController::ProcessGestureEvents() {
578 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( 695 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
579 gesture_provider_.GetAndResetPendingGestures()); 696 gesture_provider_.GetAndResetPendingGestures());
580 if (gestures) { 697 if (gestures) {
581 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); 698 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
582 i != gestures->end(); 699 i != gestures->end();
583 ++i) { 700 ++i) {
584 OnGestureEvent(*i); 701 OnGestureEvent(*i);
585 } 702 }
586 } 703 }
587 } 704 }
588 705
706 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
707 ui::EventType type = gesture->type();
708 gfx::Point location = gesture->location();
709 VLOG(0) << "Location " << location.ToString();
710 root_window_->GetHost()->ConvertPointToNativeScreen(&location);
711 if (WithinBoundsOfEdge(location, kSlopDistanceFromEdge) == SCREEN_CENTER) {
712 VLOG(0) << "No more Slide gesture ";
713 // Discard any pending gestures.
714 ignore_result(gesture_provider_.GetAndResetPendingGestures());
715 if (current_touch_ids_.size() > 1) {
716 state_ = WAIT_FOR_RELEASE;
717 } else if (current_touch_ids_.size() == 0) {
718 ResetToNoFingersDown();
719 } else {
720 EnterTouchToMouseMode();
721 state_ = TOUCH_EXPLORATION;
722 }
723 VLOG_STATE();
724 return;
725 }
726
727 if (type == ET_GESTURE_SCROLL_BEGIN) {
728 delegate_->PlayVolumeAdjustSound();
729 }
730
731 if (type == ET_GESTURE_SCROLL_END) {
732 if (sound_timer_.IsRunning())
733 sound_timer_.Stop();
734 delegate_->PlayVolumeAdjustSound();
735 }
736
737 location = gesture->location();
738 int where = WithinBoundsOfEdge(location, kSlopDistanceFromEdge);
739
740 // If the user is in the corner of the right side of the screen, the volume
741 // will be automatically set to 100% or muted depending on which corner they
742 // are in. Otherwise, the user will be able to adjust the volume by sliding
743 // their finger along the right side of the screen. Volume is relative to
744 // where they are on the right side of the screen.
745 if ((where | RIGHT_EDGE) != where)
746 return;
747
748 if (where == RIGHT_EDGE) {
749 location = gesture->location();
750 root_window_->GetHost()->ConvertPointFromNativeScreen(&location);
751 float volume =
752 100 -
753 ((float)location.y() - kMaxDistanceFromEdge) /
754 (root_window_->bounds().bottom() - 2 * kMaxDistanceFromEdge) * 100;
755 VLOG(0) << "\n Volume = " << volume
756 << "\n Location = " << location.ToString()
757 << "\n Bounds = " << root_window_->bounds().right();
758
759 delegate_->AdjustSound(volume);
760 return;
761 }
762 else if ((where | TOP_EDGE) == where) {
763 delegate_->AdjustSound(100);
764 return;
765 } else if ((where | BOTTOM_EDGE) == where) {
766 delegate_->AdjustSound(0);
767 return;
768 }
769 NOTREACHED() << "Invalid location " << where;
770 }
771
772
589 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 773 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
590 // A swipe gesture contains details for the direction in which the swipe 774 // A swipe gesture contains details for the direction in which the swipe
591 // occurred. 775 // occurred.
592 GestureEventDetails event_details = swipe_gesture->details(); 776 GestureEventDetails event_details = swipe_gesture->details();
593 if (event_details.swipe_left()) { 777 if (event_details.swipe_left()) {
594 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 778 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT);
595 return; 779 return;
596 } else if (event_details.swipe_right()) { 780 } else if (event_details.swipe_right()) {
597 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); 781 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT);
598 return; 782 return;
599 } else if (event_details.swipe_up()) { 783 } else if (event_details.swipe_up()) {
600 DispatchShiftSearchKeyEvent(ui::VKEY_UP); 784 DispatchShiftSearchKeyEvent(ui::VKEY_UP);
601 return; 785 return;
602 } else if (event_details.swipe_down()) { 786 } else if (event_details.swipe_down()) {
603 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); 787 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN);
604 return; 788 return;
605 } 789 }
606 } 790 }
607 791
792 int TouchExplorationController::WithinBoundsOfEdge(gfx::Point point,
793 float bounds) {
794 // Since GetBoundsInScreen is in DIPs but p is not, then p needs to be
795 // converted.
796 root_window_->GetHost()->ConvertPointFromNativeScreen(&point);
797 gfx::Rect window= root_window_->GetBoundsInScreen();
798
799 float left_edge_limit = window.x() + bounds;
800 float right_edge_limit = window.right() - bounds;
801 float top_edge_limit = window.y() + bounds;
802 float bottom_edge_limit = window.bottom() - bounds;
803
804 // Bitwise manipulation in order to determine where on the screen the point
805 // lies. If more than one bit is turned on, then it is a corner where the two
806 // bit/edges intersect. Otherwise, if no bits are turned on, the point must be
807 // in the center of the screen.
808 int result = SCREEN_CENTER;
809 if (point.x() < left_edge_limit)
810 result = result | LEFT_EDGE;
811 if (point.x() > right_edge_limit)
812 result = result | RIGHT_EDGE;
813 if (point.y() < top_edge_limit)
814 result = result | TOP_EDGE;
815 if (point.y() > bottom_edge_limit)
816 result = result | BOTTOM_EDGE;
817 return result;
818 }
819
608 void TouchExplorationController::DispatchShiftSearchKeyEvent( 820 void TouchExplorationController::DispatchShiftSearchKeyEvent(
609 const ui::KeyboardCode direction) { 821 const ui::KeyboardCode direction) {
610 // In order to activate the shortcut shift+search+<arrow key> 822 // In order to activate the shortcut shift+search+<arrow key>
611 // three KeyPressed events must be dispatched in succession along 823 // three KeyPressed events must be dispatched in succession along
612 // with three KeyReleased events. 824 // with three KeyReleased events.
613 ui::KeyEvent shift_down = ui::KeyEvent( 825 ui::KeyEvent shift_down = ui::KeyEvent(
614 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false); 826 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false);
615 ui::KeyEvent search_down = ui::KeyEvent( 827 ui::KeyEvent search_down = ui::KeyEvent(
616 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false); 828 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false);
617 ui::KeyEvent direction_down = 829 ui::KeyEvent direction_down =
(...skipping 29 matching lines...) Expand all
647 void TouchExplorationController::EnterTouchToMouseMode() { 859 void TouchExplorationController::EnterTouchToMouseMode() {
648 aura::client::CursorClient* cursor_client = 860 aura::client::CursorClient* cursor_client =
649 aura::client::GetCursorClient(root_window_); 861 aura::client::GetCursorClient(root_window_);
650 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 862 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
651 cursor_client->EnableMouseEvents(); 863 cursor_client->EnableMouseEvents();
652 if (cursor_client && cursor_client->IsCursorVisible()) 864 if (cursor_client && cursor_client->IsCursorVisible())
653 cursor_client->HideCursor(); 865 cursor_client->HideCursor();
654 } 866 }
655 867
656 void TouchExplorationController::ResetToNoFingersDown() { 868 void TouchExplorationController::ResetToNoFingersDown() {
869 ProcessGestureEvents();
870 if (sound_timer_.IsRunning())
871 sound_timer_.Stop();
657 state_ = NO_FINGERS_DOWN; 872 state_ = NO_FINGERS_DOWN;
658 VLOG_STATE(); 873 VLOG_STATE();
659 if (tap_timer_.IsRunning()) 874 if (tap_timer_.IsRunning())
660 tap_timer_.Stop(); 875 tap_timer_.Stop();
661 } 876 }
662 877
663 void TouchExplorationController::VlogState(const char* function_name) { 878 void TouchExplorationController::VlogState(const char* function_name) {
664 if (!VLOG_on_) 879 if (!VLOG_on_)
665 return; 880 return;
666 if (prev_state_ == state_) 881 if (prev_state_ == state_)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 case GESTURE_IN_PROGRESS: 933 case GESTURE_IN_PROGRESS:
719 return "GESTURE_IN_PROGRESS"; 934 return "GESTURE_IN_PROGRESS";
720 case TOUCH_EXPLORE_SECOND_PRESS: 935 case TOUCH_EXPLORE_SECOND_PRESS:
721 return "TOUCH_EXPLORE_SECOND_PRESS"; 936 return "TOUCH_EXPLORE_SECOND_PRESS";
722 case TWO_TO_ONE_FINGER: 937 case TWO_TO_ONE_FINGER:
723 return "TWO_TO_ONE_FINGER"; 938 return "TWO_TO_ONE_FINGER";
724 case PASSTHROUGH: 939 case PASSTHROUGH:
725 return "PASSTHROUGH"; 940 return "PASSTHROUGH";
726 case WAIT_FOR_RELEASE: 941 case WAIT_FOR_RELEASE:
727 return "WAIT_FOR_RELEASE"; 942 return "WAIT_FOR_RELEASE";
943 case SLIDE_GESTURE:
944 return "SLIDE_GESTURE";
728 } 945 }
729 return "Not a state"; 946 return "Not a state";
730 } 947 }
731 948
732 } // namespace ui 949 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698