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

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: Fixed TouchExploration Not Turning On 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
23 // Delay between adjustment sounds.
24 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
25
26 // Within these bounds, the release event generated will reset the state to
27 // NoFingersDown.
28 const float kLeavingScreenEdge = 6;
29
30 // Swipe/scroll gestures within these bounds (in dips) will change preset
31 // settings.
32 const float kMaxDistanceFromEdge = 75;
33
34 // After a slide gesture has been triggered, if the finger is still within these
35 // bounds (in DIPs), the preset settings will still change.
36 const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40;
37
22 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 38 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
23 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 39 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
24 } // namespace 40 } // namespace
25 41
26 TouchExplorationController::TouchExplorationController( 42 TouchExplorationController::TouchExplorationController(
27 aura::Window* root_window) 43 aura::Window* root_window,
44 TouchExplorationControllerDelegate* delegate)
28 : root_window_(root_window), 45 : root_window_(root_window),
46 delegate_(delegate),
29 state_(NO_FINGERS_DOWN), 47 state_(NO_FINGERS_DOWN),
30 event_handler_for_testing_(NULL), 48 event_handler_for_testing_(NULL),
31 gesture_provider_(this), 49 gesture_provider_(this),
32 prev_state_(NO_FINGERS_DOWN), 50 prev_state_(NO_FINGERS_DOWN),
33 VLOG_on_(true) { 51 VLOG_on_(true) {
34 CHECK(root_window); 52 CHECK(root_window);
35 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 53 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
36 } 54 }
37 55
38 56
(...skipping 21 matching lines...) Expand all
60 78
61 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const { 79 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const {
62 return state_ == NO_FINGERS_DOWN; 80 return state_ == NO_FINGERS_DOWN;
63 } 81 }
64 82
65 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const { 83 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const {
66 return state_ == GESTURE_IN_PROGRESS; 84 return state_ == GESTURE_IN_PROGRESS;
67 } 85 }
68 86
69 void TouchExplorationController::SuppressVLOGsForTesting(bool suppress) { 87 void TouchExplorationController::SuppressVLOGsForTesting(bool suppress) {
70 VLOG_on_ = !suppress; 88 VLOG_on_ = !suppress;
89 }
90
91 gfx::Rect TouchExplorationController::BoundsOfRootWindowInDIPForTesting() {
92 return root_window_->GetBoundsInScreen();
93 }
94
95 bool TouchExplorationController::IsInSlideGestureStateForTesting() const {
96 return state_ == SLIDE_GESTURE;
71 } 97 }
72 98
73 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 99 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
74 const ui::Event& event, 100 const ui::Event& event,
75 scoped_ptr<ui::Event>* rewritten_event) { 101 scoped_ptr<ui::Event>* rewritten_event) {
76 if (!event.IsTouchEvent()) { 102 if (!event.IsTouchEvent()) {
77 if (event.IsKeyEvent()) { 103 if (event.IsKeyEvent()) {
78 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); 104 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
79 VLOG(0) << "\nKeyboard event: " << key_event.name() 105 VLOG(0) << "\nKeyboard event: " << key_event.name()
80 << "\n Key code: " << key_event.key_code() 106 << "\n Key code: " << key_event.key_code()
(...skipping 20 matching lines...) Expand all
101 const ui::EventType type = touch_event.type(); 127 const ui::EventType type = touch_event.type();
102 const gfx::PointF& location = touch_event.location_f(); 128 const gfx::PointF& location = touch_event.location_f();
103 const int touch_id = touch_event.touch_id(); 129 const int touch_id = touch_event.touch_id();
104 130
105 // Always update touch ids and touch locations, so we can use those 131 // Always update touch ids and touch locations, so we can use those
106 // no matter what state we're in. 132 // no matter what state we're in.
107 if (type == ui::ET_TOUCH_PRESSED) { 133 if (type == ui::ET_TOUCH_PRESSED) {
108 current_touch_ids_.push_back(touch_id); 134 current_touch_ids_.push_back(touch_id);
109 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 135 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
110 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 136 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
137 // In order to avoid accidentally double tapping when moving off the edge of
138 // the screen, the state will be rewritten to NoFingersDown.
139 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
140 if (WithinBoundsOfEdge(touch_event.location(), kLeavingScreenEdge) !=
141 SCREEN_CENTER) {
142 if (current_touch_ids_.size() == 0)
143 ResetToNoFingersDown();
144 else
145 state_ = WAIT_FOR_RELEASE;
146 }
147
111 std::vector<int>::iterator it = std::find( 148 std::vector<int>::iterator it = std::find(
112 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 149 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
113 150
114 // Can happen if touch exploration is enabled while fingers were down. 151 // Can happen if touch exploration is enabled while fingers were down.
115 if (it == current_touch_ids_.end()) 152 if (it == current_touch_ids_.end())
116 return ui::EVENT_REWRITE_CONTINUE; 153 return ui::EVENT_REWRITE_CONTINUE;
117 154
118 current_touch_ids_.erase(it); 155 current_touch_ids_.erase(it);
119 touch_locations_.erase(touch_id); 156 touch_locations_.erase(touch_id);
120 } else if (type == ui::ET_TOUCH_MOVED) { 157 } else if (type == ui::ET_TOUCH_MOVED) {
(...skipping 24 matching lines...) Expand all
145 case GESTURE_IN_PROGRESS: 182 case GESTURE_IN_PROGRESS:
146 return InGestureInProgress(touch_event, rewritten_event); 183 return InGestureInProgress(touch_event, rewritten_event);
147 case TOUCH_EXPLORE_SECOND_PRESS: 184 case TOUCH_EXPLORE_SECOND_PRESS:
148 return InTouchExploreSecondPress(touch_event, rewritten_event); 185 return InTouchExploreSecondPress(touch_event, rewritten_event);
149 case TWO_TO_ONE_FINGER: 186 case TWO_TO_ONE_FINGER:
150 return InTwoToOneFinger(touch_event, rewritten_event); 187 return InTwoToOneFinger(touch_event, rewritten_event);
151 case PASSTHROUGH: 188 case PASSTHROUGH:
152 return InPassthrough(touch_event, rewritten_event); 189 return InPassthrough(touch_event, rewritten_event);
153 case WAIT_FOR_RELEASE: 190 case WAIT_FOR_RELEASE:
154 return InWaitForRelease(touch_event, rewritten_event); 191 return InWaitForRelease(touch_event, rewritten_event);
192 case SLIDE_GESTURE:
193 return InSlideGesture(touch_event, rewritten_event);
155 } 194 }
156 NOTREACHED(); 195 NOTREACHED();
157 return ui::EVENT_REWRITE_CONTINUE; 196 return ui::EVENT_REWRITE_CONTINUE;
158 } 197 }
159 198
160 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 199 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
161 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 200 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
162 NOTREACHED(); 201 NOTREACHED();
163 return ui::EVENT_REWRITE_CONTINUE; 202 return ui::EVENT_REWRITE_CONTINUE;
164 } 203 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 254
216 float delta_time = 255 float delta_time =
217 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 256 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
218 float velocity = distance / delta_time; 257 float velocity = distance / delta_time;
219 VLOG(0) << "\n Delta time: " << delta_time 258 VLOG(0) << "\n Delta time: " << delta_time
220 << "\n Distance: " << distance 259 << "\n Distance: " << distance
221 << "\n Velocity of click: " << velocity 260 << "\n Velocity of click: " << velocity
222 << "\n Minimum swipe velocity: " 261 << "\n Minimum swipe velocity: "
223 << gesture_detector_config_.minimum_swipe_velocity; 262 << gesture_detector_config_.minimum_swipe_velocity;
224 263
264 // Change to slide gesture if the slide occurred at the right edge.
265 int where = WithinBoundsOfEdge(event.location(), kMaxDistanceFromEdge);
266 if (where & RIGHT_EDGE) {
267 state_ = SLIDE_GESTURE;
268 VLOG_STATE();
269 return InSlideGesture(event, rewritten_event);
270 }
271
225 // If the user moves fast enough from the initial touch location, start 272 // If the user moves fast enough from the initial touch location, start
226 // gesture detection. Otherwise, jump to the touch exploration mode early. 273 // gesture detection. Otherwise, jump to the touch exploration mode early.
227 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 274 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
228 state_ = GESTURE_IN_PROGRESS; 275 state_ = GESTURE_IN_PROGRESS;
229 VLOG_STATE(); 276 VLOG_STATE();
230 return InGestureInProgress(event, rewritten_event); 277 return InGestureInProgress(event, rewritten_event);
231 } 278 }
232 EnterTouchToMouseMode(); 279 EnterTouchToMouseMode();
233 state_ = TOUCH_EXPLORATION; 280 state_ = TOUCH_EXPLORATION;
234 VLOG_STATE(); 281 VLOG_STATE();
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 if (current_touch_ids_.size() != 1) 542 if (current_touch_ids_.size() != 1)
496 return EVENT_REWRITE_DISCARD; 543 return EVENT_REWRITE_DISCARD;
497 544
498 // Rewrite at location of last touch exploration. 545 // Rewrite at location of last touch exploration.
499 rewritten_event->reset( 546 rewritten_event->reset(
500 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 547 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
501 last_touch_exploration_->location(), 548 last_touch_exploration_->location(),
502 initial_press_->touch_id(), 549 initial_press_->touch_id(),
503 event.time_stamp())); 550 event.time_stamp()));
504 (*rewritten_event)->set_flags(event.flags()); 551 (*rewritten_event)->set_flags(event.flags());
552 EnterTouchToMouseMode();
505 state_ = TOUCH_EXPLORATION; 553 state_ = TOUCH_EXPLORATION;
506 EnterTouchToMouseMode(); 554 EnterTouchToMouseMode();
507 VLOG_STATE(); 555 VLOG_STATE();
508 return ui::EVENT_REWRITE_REWRITTEN; 556 return ui::EVENT_REWRITE_REWRITTEN;
509 } 557 }
510 NOTREACHED() << "Unexpected event type received: " << event.name(); 558 NOTREACHED() << "Unexpected event type received: " << event.name();
511 return ui::EVENT_REWRITE_CONTINUE; 559 return ui::EVENT_REWRITE_CONTINUE;
512 } 560 }
513 561
514 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( 562 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease(
515 const ui::TouchEvent& event, 563 const ui::TouchEvent& event,
516 scoped_ptr<ui::Event>* rewritten_event) { 564 scoped_ptr<ui::Event>* rewritten_event) {
517 ui::EventType type = event.type(); 565 ui::EventType type = event.type();
518 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 566 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
519 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 567 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
520 NOTREACHED() << "Unexpected event type received: " << event.name(); 568 NOTREACHED() << "Unexpected event type received: " << event.name();
521 return ui::EVENT_REWRITE_CONTINUE; 569 return ui::EVENT_REWRITE_CONTINUE;
522 } 570 }
523 if (current_touch_ids_.size() == 0) { 571 if (current_touch_ids_.size() == 0) {
524 state_ = NO_FINGERS_DOWN; 572 state_ = NO_FINGERS_DOWN;
525 VLOG_STATE(); 573 VLOG_STATE();
526 ResetToNoFingersDown(); 574 ResetToNoFingersDown();
527 } 575 }
528 return EVENT_REWRITE_DISCARD; 576 return EVENT_REWRITE_DISCARD;
529 } 577 }
530 578
579 void TouchExplorationController::PlaySoundForTimer() {
580 delegate_->PlayVolumeAdjustSound();
581 }
582
583 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
584 const ui::TouchEvent& event,
585 scoped_ptr<ui::Event>* rewritten_event) {
586 // The timer should not fire when sliding.
587 if (tap_timer_.IsRunning())
588 tap_timer_.Stop();
589
590 ui::EventType type = event.type();
591 // If additional fingers are added before a swipe gesture has been registered,
592 // then wait until all fingers have been lifted.
593 if (type == ui::ET_TOUCH_PRESSED ||
594 event.touch_id() != initial_press_->touch_id()) {
595 if (sound_timer_.IsRunning())
596 sound_timer_.Stop();
597 // Discard any pending gestures.
598 ignore_result(gesture_provider_.GetAndResetPendingGestures());
599 state_ = WAIT_FOR_RELEASE;
600 return EVENT_REWRITE_DISCARD;
601 }
602
603 // Allows user to return to the edge to adjust the sound if they have left the
604 // boundaries.
605 int where = WithinBoundsOfEdge(event.location(), kSlopDistanceFromEdge);
606 if (!(where & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) {
607 if (sound_timer_.IsRunning()) {
608 sound_timer_.Stop();
609 }
610 return EVENT_REWRITE_DISCARD;
611 }
612
613 // This can occur if the user leaves the screen edge and then returns to it to
614 // continue adjusting the sound.
615 if (!sound_timer_.IsRunning()) {
616 sound_timer_.Start(FROM_HERE,
617 kSoundDelay,
618 this,
619 &ui::TouchExplorationController::PlaySoundForTimer);
620 delegate_->PlayVolumeAdjustSound();
621 }
622
623 // There should not be more than one finger down.
624 DCHECK(current_touch_ids_.size() <= 1);
625 if (type == ui::ET_TOUCH_MOVED) {
626 gesture_provider_.OnTouchEvent(event);
627 gesture_provider_.OnTouchEventAck(false);
628 }
629 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
630 gesture_provider_.OnTouchEvent(event);
631 gesture_provider_.OnTouchEventAck(false);
632 ignore_result(gesture_provider_.GetAndResetPendingGestures());
633 if (current_touch_ids_.size() == 0)
634 ResetToNoFingersDown();
635 return ui::EVENT_REWRITE_DISCARD;
636 }
637
638 ProcessGestureEvents();
639 return ui::EVENT_REWRITE_DISCARD;
640 }
641
531 void TouchExplorationController::OnTapTimerFired() { 642 void TouchExplorationController::OnTapTimerFired() {
532 switch (state_) { 643 switch (state_) {
533 case SINGLE_TAP_RELEASED: 644 case SINGLE_TAP_RELEASED:
534 ResetToNoFingersDown(); 645 ResetToNoFingersDown();
535 break; 646 break;
536 case TOUCH_EXPLORE_RELEASED: 647 case TOUCH_EXPLORE_RELEASED:
537 ResetToNoFingersDown(); 648 ResetToNoFingersDown();
538 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 649 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
539 return; 650 return;
540 case SINGLE_TAP_PRESSED: 651 case SINGLE_TAP_PRESSED:
541 case GESTURE_IN_PROGRESS: 652 case GESTURE_IN_PROGRESS:
542 // Discard any pending gestures. 653 // Discard any pending gestures.
543 ignore_result(gesture_provider_.GetAndResetPendingGestures()); 654 ignore_result(gesture_provider_.GetAndResetPendingGestures());
544 EnterTouchToMouseMode(); 655 EnterTouchToMouseMode();
545 state_ = TOUCH_EXPLORATION; 656 state_ = TOUCH_EXPLORATION;
546 VLOG_STATE(); 657 VLOG_STATE();
547 break; 658 break;
548 default: 659 default:
549 return; 660 return;
550 } 661 }
551 scoped_ptr<ui::Event> mouse_move = 662 scoped_ptr<ui::Event> mouse_move =
552 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 663 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
553 DispatchEvent(mouse_move.get()); 664 DispatchEvent(mouse_move.get());
554 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 665 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
555 } 666 }
556 667
557 void TouchExplorationController::DispatchEvent(ui::Event* event) { 668 void TouchExplorationController::DispatchEvent(ui::Event* event) {
558 if (event_handler_for_testing_) { 669 if (event_handler_for_testing_) {
559 event_handler_for_testing_->OnEvent(event); 670 event_handler_for_testing_->OnEvent(event);
560 return; 671 return;
561 } 672 }
562 ui::EventDispatchDetails result ALLOW_UNUSED = 673 ui::EventDispatchDetails result ALLOW_UNUSED =
563 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 674 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
564 } 675 }
565 676
566 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { 677 void TouchExplorationController::OnGestureEvent(
678 ui::GestureEvent* gesture) {
567 CHECK(gesture->IsGestureEvent()); 679 CHECK(gesture->IsGestureEvent());
680 ui::EventType type = gesture->type();
568 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); 681 VLOG(0) << " \n Gesture Triggered: " << gesture->name();
569 if (gesture->type() == ui::ET_GESTURE_SWIPE) { 682 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) {
570 if (tap_timer_.IsRunning()) 683 VLOG(0) << "Swipe!";
571 tap_timer_.Stop(); 684 ignore_result(gesture_provider_.GetAndResetPendingGestures());
572 OnSwipeEvent(gesture); 685 OnSwipeEvent(gesture);
573 return; 686 return;
574 } 687 }
575 } 688 }
576 689
577 void TouchExplorationController::ProcessGestureEvents() { 690 void TouchExplorationController::ProcessGestureEvents() {
578 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( 691 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
579 gesture_provider_.GetAndResetPendingGestures()); 692 gesture_provider_.GetAndResetPendingGestures());
580 if (gestures) { 693 if (gestures) {
581 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); 694 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
582 i != gestures->end(); 695 i != gestures->end();
583 ++i) { 696 ++i) {
584 OnGestureEvent(*i); 697 if (state_ == SLIDE_GESTURE)
698 SideSlideControl(*i);
699 else
700 OnGestureEvent(*i);
585 } 701 }
586 } 702 }
587 } 703 }
588 704
705 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
706 ui::EventType type = gesture->type();
707 if (!gesture->IsScrollGestureEvent())
708 return;
709
710 if (type == ET_GESTURE_SCROLL_BEGIN) {
711 delegate_->PlayVolumeAdjustSound();
712 }
713
714 if (type == ET_GESTURE_SCROLL_END) {
715 if (sound_timer_.IsRunning())
716 sound_timer_.Stop();
717 delegate_->PlayVolumeAdjustSound();
718 }
719
720 // If the user is in the corner of the right side of the screen, the volume
721 // will be automatically set to 100% or muted depending on which corner they
722 // are in. Otherwise, the user will be able to adjust the volume by sliding
723 // their finger along the right side of the screen. Volume is relative to
724 // where they are on the right side of the screen.
725 gfx::Point location = gesture->location();
726 int where = WithinBoundsOfEdge(location, kSlopDistanceFromEdge);
727 if (!(where & RIGHT_EDGE))
728 return;
729
730 if (where == RIGHT_EDGE) {
731 location = gesture->location();
732 root_window_->GetHost()->ConvertPointFromNativeScreen(&location);
733 float volume_adjust_height =
734 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge;
735 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height;
736 float volume = 100 - 100 * ratio;
737 VLOG(0) << "\n Volume = " << volume
738 << "\n Location = " << location.ToString()
739 << "\n Bounds = " << root_window_->bounds().right();
740
741 delegate_->SetOutputLevel(int(volume));
742 return;
743 }
744 else if (where & TOP_EDGE) {
745 delegate_->SetOutputLevel(100);
746 return;
747 } else if (where & BOTTOM_EDGE) {
748 delegate_->SetOutputLevel(0);
749 return;
750 }
751 NOTREACHED() << "Invalid location " << where;
752 }
753
754
589 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 755 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
590 // A swipe gesture contains details for the direction in which the swipe 756 // A swipe gesture contains details for the direction in which the swipe
591 // occurred. 757 // occurred.
592 GestureEventDetails event_details = swipe_gesture->details(); 758 GestureEventDetails event_details = swipe_gesture->details();
593 if (event_details.swipe_left()) { 759 if (event_details.swipe_left()) {
594 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 760 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT);
595 return; 761 return;
596 } else if (event_details.swipe_right()) { 762 } else if (event_details.swipe_right()) {
597 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); 763 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT);
598 return; 764 return;
599 } else if (event_details.swipe_up()) { 765 } else if (event_details.swipe_up()) {
600 DispatchShiftSearchKeyEvent(ui::VKEY_UP); 766 DispatchShiftSearchKeyEvent(ui::VKEY_UP);
601 return; 767 return;
602 } else if (event_details.swipe_down()) { 768 } else if (event_details.swipe_down()) {
603 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); 769 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN);
604 return; 770 return;
605 } 771 }
606 } 772 }
607 773
774 int TouchExplorationController::WithinBoundsOfEdge(gfx::Point point,
775 float bounds) {
776 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be
777 // converted.
778 root_window_->GetHost()->ConvertPointFromNativeScreen(&point);
779 gfx::Rect window = root_window_->GetBoundsInScreen();
780
781 float left_edge_limit = window.x() + bounds;
782 float right_edge_limit = window.right() - bounds;
783 float top_edge_limit = window.y() + bounds;
784 float bottom_edge_limit = window.bottom() - bounds;
785
786 // Bitwise manipulation in order to determine where on the screen the point
787 // lies. If more than one bit is turned on, then it is a corner where the two
788 // bit/edges intersect. Otherwise, if no bits are turned on, the point must be
789 // in the center of the screen.
790 int result = SCREEN_CENTER;
791 if (point.x() < left_edge_limit)
792 result |= LEFT_EDGE;
793 if (point.x() > right_edge_limit)
794 result |= RIGHT_EDGE;
795 if (point.y() < top_edge_limit)
796 result |= TOP_EDGE;
797 if (point.y() > bottom_edge_limit)
798 result |= BOTTOM_EDGE;
799 return result;
800 }
801
608 void TouchExplorationController::DispatchShiftSearchKeyEvent( 802 void TouchExplorationController::DispatchShiftSearchKeyEvent(
609 const ui::KeyboardCode direction) { 803 const ui::KeyboardCode direction) {
610 // In order to activate the shortcut shift+search+<arrow key> 804 // In order to activate the shortcut shift+search+<arrow key>
611 // three KeyPressed events must be dispatched in succession along 805 // three KeyPressed events must be dispatched in succession along
612 // with three KeyReleased events. 806 // with three KeyReleased events.
613 ui::KeyEvent shift_down = ui::KeyEvent( 807 ui::KeyEvent shift_down = ui::KeyEvent(
614 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false); 808 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false);
615 ui::KeyEvent search_down = ui::KeyEvent( 809 ui::KeyEvent search_down = ui::KeyEvent(
616 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false); 810 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false);
617 ui::KeyEvent direction_down = 811 ui::KeyEvent direction_down =
(...skipping 29 matching lines...) Expand all
647 void TouchExplorationController::EnterTouchToMouseMode() { 841 void TouchExplorationController::EnterTouchToMouseMode() {
648 aura::client::CursorClient* cursor_client = 842 aura::client::CursorClient* cursor_client =
649 aura::client::GetCursorClient(root_window_); 843 aura::client::GetCursorClient(root_window_);
650 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 844 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
651 cursor_client->EnableMouseEvents(); 845 cursor_client->EnableMouseEvents();
652 if (cursor_client && cursor_client->IsCursorVisible()) 846 if (cursor_client && cursor_client->IsCursorVisible())
653 cursor_client->HideCursor(); 847 cursor_client->HideCursor();
654 } 848 }
655 849
656 void TouchExplorationController::ResetToNoFingersDown() { 850 void TouchExplorationController::ResetToNoFingersDown() {
851 ProcessGestureEvents();
852 if (sound_timer_.IsRunning())
853 sound_timer_.Stop();
657 state_ = NO_FINGERS_DOWN; 854 state_ = NO_FINGERS_DOWN;
658 VLOG_STATE(); 855 VLOG_STATE();
659 if (tap_timer_.IsRunning()) 856 if (tap_timer_.IsRunning())
660 tap_timer_.Stop(); 857 tap_timer_.Stop();
661 } 858 }
662 859
663 void TouchExplorationController::VlogState(const char* function_name) { 860 void TouchExplorationController::VlogState(const char* function_name) {
664 if (!VLOG_on_) 861 if (!VLOG_on_)
665 return; 862 return;
666 if (prev_state_ == state_) 863 if (prev_state_ == state_)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 case GESTURE_IN_PROGRESS: 915 case GESTURE_IN_PROGRESS:
719 return "GESTURE_IN_PROGRESS"; 916 return "GESTURE_IN_PROGRESS";
720 case TOUCH_EXPLORE_SECOND_PRESS: 917 case TOUCH_EXPLORE_SECOND_PRESS:
721 return "TOUCH_EXPLORE_SECOND_PRESS"; 918 return "TOUCH_EXPLORE_SECOND_PRESS";
722 case TWO_TO_ONE_FINGER: 919 case TWO_TO_ONE_FINGER:
723 return "TWO_TO_ONE_FINGER"; 920 return "TWO_TO_ONE_FINGER";
724 case PASSTHROUGH: 921 case PASSTHROUGH:
725 return "PASSTHROUGH"; 922 return "PASSTHROUGH";
726 case WAIT_FOR_RELEASE: 923 case WAIT_FOR_RELEASE:
727 return "WAIT_FOR_RELEASE"; 924 return "WAIT_FOR_RELEASE";
925 case SLIDE_GESTURE:
926 return "SLIDE_GESTURE";
728 } 927 }
729 return "Not a state"; 928 return "Not a state";
730 } 929 }
731 930
732 } // namespace ui 931 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698