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

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

Powered by Google App Engine
This is Rietveld 408576698