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

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

Issue 429633002: Added multi-finger gestures to touch_exploration_controller (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@passthrough
Patch Set: rebased Created 6 years, 4 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" 7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/time/default_tick_clock.h"
9 #include "ui/aura/client/cursor_client.h" 10 #include "ui/aura/client/cursor_client.h"
10 #include "ui/aura/window.h" 11 #include "ui/aura/window.h"
11 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 14 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 15 #include "ui/events/event_processor.h"
15 #include "ui/events/event_utils.h" 16 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/rect.h" 17 #include "ui/gfx/geometry/rect.h"
17 18
18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 19 #define SET_STATE(state) SetState(state, __func__)
19 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 20 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
20 21
21 namespace ui { 22 namespace ui {
22 23
23 namespace { 24 namespace {
24 25
25 // Delay between adjustment sounds. 26 // Delay between adjustment sounds.
26 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); 27 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
27 28
28 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 29 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 30 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
30 } // namespace 31 } // namespace
31 32
32 TouchExplorationController::TouchExplorationController( 33 TouchExplorationController::TouchExplorationController(
33 aura::Window* root_window, 34 aura::Window* root_window,
34 TouchExplorationControllerDelegate* delegate) 35 TouchExplorationControllerDelegate* delegate)
35 : root_window_(root_window), 36 : root_window_(root_window),
36 delegate_(delegate), 37 delegate_(delegate),
37 state_(NO_FINGERS_DOWN), 38 state_(NO_FINGERS_DOWN),
38 gesture_provider_(this), 39 gesture_provider_(new GestureProviderAura(this)),
39 prev_state_(NO_FINGERS_DOWN), 40 prev_state_(NO_FINGERS_DOWN),
40 VLOG_on_(true), 41 VLOG_on_(true),
41 tick_clock_(NULL) { 42 tick_clock_(NULL) {
42 CHECK(root_window); 43 CHECK(root_window);
43 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
45 InitializeSwipeGestureMaps();
44 } 46 }
45 47
46 TouchExplorationController::~TouchExplorationController() { 48 TouchExplorationController::~TouchExplorationController() {
47 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
48 } 50 }
49 51
50 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 52 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
51 const ui::Event& event, 53 const ui::Event& event,
52 scoped_ptr<ui::Event>* rewritten_event) { 54 scoped_ptr<ui::Event>* rewritten_event) {
53 if (!event.IsTouchEvent()) { 55 if (!event.IsTouchEvent()) {
56 if (event.IsKeyEvent()) {
57 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
58 VLOG(0) << "\nKeyboard event: " << key_event.name()
59 << "\n Key code: " << key_event.key_code()
60 << ", Flags: " << key_event.flags()
61 << ", Is char: " << key_event.is_char();
62 }
54 return ui::EVENT_REWRITE_CONTINUE; 63 return ui::EVENT_REWRITE_CONTINUE;
55 } 64 }
56 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); 65 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
57 66
58 // If the tap timer should have fired by now but hasn't, run it now and 67 // If the tap timer should have fired by now but hasn't, run it now and
59 // stop the timer. This is important so that behavior is consistent with 68 // stop the timer. This is important so that behavior is consistent with
60 // the timestamps of the events, and not dependent on the granularity of 69 // the timestamps of the events, and not dependent on the granularity of
61 // the timer. 70 // the timer.
62 if (tap_timer_.IsRunning() && 71 if (tap_timer_.IsRunning() &&
63 touch_event.time_stamp() - initial_press_->time_stamp() > 72 touch_event.time_stamp() - initial_press_->time_stamp() >
64 gesture_detector_config_.double_tap_timeout) { 73 gesture_detector_config_.double_tap_timeout) {
65 tap_timer_.Stop(); 74 tap_timer_.Stop();
66 OnTapTimerFired(); 75 OnTapTimerFired();
67 // Note: this may change the state. We should now continue and process 76 // Note: this may change the state. We should now continue and process
68 // this event under this new state. 77 // this event under this new state.
69 } 78 }
70 79
71 const ui::EventType type = touch_event.type(); 80 const ui::EventType type = touch_event.type();
72 const gfx::PointF& location = touch_event.location_f(); 81 const gfx::PointF& location = touch_event.location_f();
73 const int touch_id = touch_event.touch_id(); 82 const int touch_id = touch_event.touch_id();
74 83
75 // Always update touch ids and touch locations, so we can use those 84 // Always update touch ids and touch locations, so we can use those
76 // no matter what state we're in. 85 // no matter what state we're in.
77 if (type == ui::ET_TOUCH_PRESSED) { 86 if (type == ui::ET_TOUCH_PRESSED) {
78 current_touch_ids_.push_back(touch_id); 87 current_touch_ids_.push_back(touch_id);
79 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 88 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
80 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 89 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
81 // In order to avoid accidentally double tapping when moving off the edge of
82 // the screen, the state will be rewritten to NoFingersDown.
83 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
84 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) !=
85 NO_EDGE) {
86 if (current_touch_ids_.size() == 0) {
87 ResetToNoFingersDown();
88 }
89 }
90
91 std::vector<int>::iterator it = std::find( 90 std::vector<int>::iterator it = std::find(
92 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 91 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
93 92
94 // Can happen if touch exploration is enabled while fingers were down. 93 // Can happen if touch exploration is enabled while fingers were down.
95 if (it == current_touch_ids_.end()) 94 if (it == current_touch_ids_.end())
96 return ui::EVENT_REWRITE_CONTINUE; 95 return ui::EVENT_REWRITE_CONTINUE;
97 96
98 current_touch_ids_.erase(it); 97 current_touch_ids_.erase(it);
99 touch_locations_.erase(touch_id); 98 touch_locations_.erase(touch_id);
100 } else if (type == ui::ET_TOUCH_MOVED) { 99 } else if (type == ui::ET_TOUCH_MOVED) {
101 std::vector<int>::iterator it = std::find( 100 std::vector<int>::iterator it = std::find(
102 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 101 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
103 102
104 // Can happen if touch exploration is enabled while fingers were down. 103 // Can happen if touch exploration is enabled while fingers were down.
105 if (it == current_touch_ids_.end()) 104 if (it == current_touch_ids_.end())
106 return ui::EVENT_REWRITE_CONTINUE; 105 return ui::EVENT_REWRITE_CONTINUE;
107 106
108 touch_locations_[*it] = location; 107 touch_locations_[*it] = location;
108 } else {
109 NOTREACHED() << "Unexpected event type received: " << event.name();
110 return ui::EVENT_REWRITE_CONTINUE;
109 } 111 }
110 VLOG_STATE();
111 VLOG_EVENT(touch_event); 112 VLOG_EVENT(touch_event);
113
114 // In order to avoid accidentally double tapping when moving off the edge
115 // of the screen, the state will be rewritten to NoFingersDown.
116 if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) &&
117 FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) !=
118 NO_EDGE) {
119 if (current_touch_ids_.size() == 0) {
120 SET_STATE(NO_FINGERS_DOWN);
121 if (VLOG_on_) {
122 VLOG(0) << "Reset to no fingers in Rewrite event because the touch "
123 "release or cancel was on the edge of the screen.";
124 }
125 return ui::EVENT_REWRITE_DISCARD;
126 }
127 }
128
129 // If the user is in a gesture state, or if there is a possiblity that the
130 // user will enter it in the future, we send the event to the gesture
131 // provider so it can keep track of the state of the fingers. When the user
132 // leaves one of these states, SET_STATE will set the gesture provider to
133 // NULL.
134 if (gesture_provider_.get()) {
135 gesture_provider_->OnTouchEvent(touch_event);
136 gesture_provider_->OnTouchEventAck(false);
137 ProcessGestureEvents();
138 }
139
112 // The rest of the processing depends on what state we're in. 140 // The rest of the processing depends on what state we're in.
113 switch(state_) { 141 switch (state_) {
114 case NO_FINGERS_DOWN: 142 case NO_FINGERS_DOWN:
115 return InNoFingersDown(touch_event, rewritten_event); 143 return InNoFingersDown(touch_event, rewritten_event);
116 case SINGLE_TAP_PRESSED: 144 case SINGLE_TAP_PRESSED:
117 return InSingleTapPressed(touch_event, rewritten_event); 145 return InSingleTapPressed(touch_event, rewritten_event);
118 case SINGLE_TAP_RELEASED: 146 case SINGLE_TAP_RELEASED:
119 case TOUCH_EXPLORE_RELEASED: 147 case TOUCH_EXPLORE_RELEASED:
120 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); 148 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event);
121 case DOUBLE_TAP_PENDING: 149 case DOUBLE_TAP_PENDING:
122 return InDoubleTapPending(touch_event, rewritten_event); 150 return InDoubleTapPending(touch_event, rewritten_event);
123 case TOUCH_RELEASE_PENDING: 151 case TOUCH_RELEASE_PENDING:
124 return InTouchReleasePending(touch_event, rewritten_event); 152 return InTouchReleasePending(touch_event, rewritten_event);
125 case TOUCH_EXPLORATION: 153 case TOUCH_EXPLORATION:
126 return InTouchExploration(touch_event, rewritten_event); 154 return InTouchExploration(touch_event, rewritten_event);
127 case GESTURE_IN_PROGRESS: 155 case GESTURE_IN_PROGRESS:
128 return InGestureInProgress(touch_event, rewritten_event); 156 return InGestureInProgress(touch_event, rewritten_event);
129 case TOUCH_EXPLORE_SECOND_PRESS: 157 case TOUCH_EXPLORE_SECOND_PRESS:
130 return InTouchExploreSecondPress(touch_event, rewritten_event); 158 return InTouchExploreSecondPress(touch_event, rewritten_event);
131 case SLIDE_GESTURE: 159 case SLIDE_GESTURE:
132 return InSlideGesture(touch_event, rewritten_event); 160 return InSlideGesture(touch_event, rewritten_event);
133 case ONE_FINGER_PASSTHROUGH: 161 case ONE_FINGER_PASSTHROUGH:
134 return InOneFingerPassthrough(touch_event, rewritten_event); 162 return InOneFingerPassthrough(touch_event, rewritten_event);
135 case WAIT_FOR_ONE_FINGER: 163 case WAIT_FOR_NO_FINGERS:
136 return InWaitForOneFinger(touch_event, rewritten_event); 164 return InWaitForNoFingers(touch_event, rewritten_event);
137 case TWO_FINGER_TAP: 165 case TWO_FINGER_TAP:
138 return InTwoFingerTap(touch_event, rewritten_event); 166 return InTwoFingerTap(touch_event, rewritten_event);
139 } 167 }
140 NOTREACHED(); 168 NOTREACHED();
141 return ui::EVENT_REWRITE_CONTINUE; 169 return ui::EVENT_REWRITE_CONTINUE;
142 } 170 }
143 171
144 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 172 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
145 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 173 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
146 NOTREACHED(); 174 NOTREACHED();
147 return ui::EVENT_REWRITE_CONTINUE; 175 return ui::EVENT_REWRITE_CONTINUE;
148 } 176 }
149 177
150 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 178 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
151 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 179 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
152 const ui::EventType type = event.type(); 180 ui::EventType type = event.type();
153 if (type != ui::ET_TOUCH_PRESSED) { 181 if (type == ui::ET_TOUCH_PRESSED) {
154 NOTREACHED() << "Unexpected event type received: " << event.name(); 182 initial_press_.reset(new TouchEvent(event));
155 return ui::EVENT_REWRITE_CONTINUE; 183 initial_presses_[event.touch_id()] = event.location();
184 last_unused_finger_event_.reset(new TouchEvent(event));
185 StartTapTimer();
186 SET_STATE(SINGLE_TAP_PRESSED);
187 return ui::EVENT_REWRITE_DISCARD;
156 } 188 }
157 initial_press_.reset(new TouchEvent(event)); 189 NOTREACHED() << "Unexpected event type received: " << event.name();
158 initial_presses_[event.touch_id()] = event.location(); 190 return ui::EVENT_REWRITE_CONTINUE;
159 last_unused_finger_event_.reset(new TouchEvent(event));
160 StartTapTimer();
161 gesture_provider_.OnTouchEvent(event);
162 gesture_provider_.OnTouchEventAck(false);
163 ProcessGestureEvents();
164 state_ = SINGLE_TAP_PRESSED;
165 VLOG_STATE();
166 return ui::EVENT_REWRITE_DISCARD;
167 } 191 }
168 192
169 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 193 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 194 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
171 const ui::EventType type = event.type(); 195 const ui::EventType type = event.type();
172 196
173 if (type == ui::ET_TOUCH_PRESSED) { 197 if (type == ui::ET_TOUCH_PRESSED) {
174 initial_presses_[event.touch_id()] = event.location(); 198 initial_presses_[event.touch_id()] = event.location();
175 state_ = TWO_FINGER_TAP; 199 SET_STATE(TWO_FINGER_TAP);
176 VLOG_STATE();
177 return EVENT_REWRITE_DISCARD; 200 return EVENT_REWRITE_DISCARD;
178 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 201 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
179 if (current_touch_ids_.size() == 0 && 202 if (current_touch_ids_.size() == 0 &&
180 event.touch_id() == initial_press_->touch_id()) { 203 event.touch_id() == initial_press_->touch_id()) {
181 state_ = SINGLE_TAP_RELEASED; 204 SET_STATE(SINGLE_TAP_RELEASED);
182 VLOG_STATE();
183 } else if (current_touch_ids_.size() == 0) { 205 } else if (current_touch_ids_.size() == 0) {
184 ResetToNoFingersDown(); 206 SET_STATE(NO_FINGERS_DOWN);
185 } 207 }
186 return EVENT_REWRITE_DISCARD; 208 return EVENT_REWRITE_DISCARD;
187 } else if (type == ui::ET_TOUCH_MOVED) { 209 } else if (type == ui::ET_TOUCH_MOVED) {
188 float distance = (event.location() - initial_press_->location()).Length(); 210 float distance = (event.location() - initial_press_->location()).Length();
189 // If the user does not move far enough from the original position, then the 211 // If the user does not move far enough from the original position, then the
190 // resulting movement should not be considered to be a deliberate gesture or 212 // resulting movement should not be considered to be a deliberate gesture or
191 // touch exploration. 213 // touch exploration.
192 if (distance <= gesture_detector_config_.touch_slop) 214 if (distance <= gesture_detector_config_.touch_slop)
193 return EVENT_REWRITE_DISCARD; 215 return EVENT_REWRITE_DISCARD;
194 216
195 float delta_time = 217 float delta_time =
196 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 218 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
197 float velocity = distance / delta_time; 219 float velocity = distance / delta_time;
198 if (VLOG_on_) { 220 if (VLOG_on_) {
199 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance 221 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance
200 << "\n Velocity of click: " << velocity 222 << "\n Velocity of click: " << velocity
201 << "\n Minimum swipe velocity: " 223 << "\n Minimum swipe velocity: "
202 << gesture_detector_config_.minimum_swipe_velocity; 224 << gesture_detector_config_.minimum_swipe_velocity;
203 } 225 }
204 // Change to slide gesture if the slide occurred at the right edge. 226 // Change to slide gesture if the slide occurred at the right edge.
205 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); 227 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
206 if (edge & RIGHT_EDGE) { 228 if (edge & RIGHT_EDGE) {
207 state_ = SLIDE_GESTURE; 229 SET_STATE(SLIDE_GESTURE);
208 VLOG_STATE();
209 return InSlideGesture(event, rewritten_event); 230 return InSlideGesture(event, rewritten_event);
210 } 231 }
211 232
212 // If the user moves fast enough from the initial touch location, start 233 // If the user moves fast enough from the initial touch location, start
213 // gesture detection. Otherwise, jump to the touch exploration mode early. 234 // gesture detection. Otherwise, jump to the touch exploration mode early.
214 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 235 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
215 state_ = GESTURE_IN_PROGRESS; 236 SET_STATE(GESTURE_IN_PROGRESS);
216 VLOG_STATE();
217 return InGestureInProgress(event, rewritten_event); 237 return InGestureInProgress(event, rewritten_event);
218 } 238 }
219 EnterTouchToMouseMode(); 239 EnterTouchToMouseMode();
220 state_ = TOUCH_EXPLORATION; 240 SET_STATE(TOUCH_EXPLORATION);
221 VLOG_STATE();
222 return InTouchExploration(event, rewritten_event); 241 return InTouchExploration(event, rewritten_event);
223 } 242 }
224 NOTREACHED() << "Unexpected event type received: " << event.name(); 243 NOTREACHED();
225 return ui::EVENT_REWRITE_CONTINUE; 244 return ui::EVENT_REWRITE_CONTINUE;
226 } 245 }
227 246
228 ui::EventRewriteStatus 247 ui::EventRewriteStatus
229 TouchExplorationController::InSingleTapOrTouchExploreReleased( 248 TouchExplorationController::InSingleTapOrTouchExploreReleased(
230 const ui::TouchEvent& event, 249 const ui::TouchEvent& event,
231 scoped_ptr<ui::Event>* rewritten_event) { 250 scoped_ptr<ui::Event>* rewritten_event) {
232 const ui::EventType type = event.type(); 251 const ui::EventType type = event.type();
233 // If there is more than one finger down, then discard to wait until only one 252 // If there is more than one finger down, then discard to wait until no
234 // finger is or no fingers are down. 253 // fingers are down.
235 if (current_touch_ids_.size() > 1) { 254 if (current_touch_ids_.size() > 1) {
236 state_ = WAIT_FOR_ONE_FINGER; 255 SET_STATE(WAIT_FOR_NO_FINGERS);
237 return ui::EVENT_REWRITE_DISCARD; 256 return ui::EVENT_REWRITE_DISCARD;
238 } 257 }
239 if (type == ui::ET_TOUCH_PRESSED) { 258 if (type == ui::ET_TOUCH_PRESSED) {
240 // If there is no touch exploration yet, we can't send a click, so discard. 259 // If there is no touch exploration yet, we can't send a click, so discard.
241 if (!last_touch_exploration_) { 260 if (!last_touch_exploration_) {
242 tap_timer_.Stop(); 261 tap_timer_.Stop();
243 return ui::EVENT_REWRITE_DISCARD; 262 return ui::EVENT_REWRITE_DISCARD;
244 } 263 }
245 // This is the second tap in a double-tap (or double tap-hold). 264 // This is the second tap in a double-tap (or double tap-hold).
246 // We set the tap timer. If it fires before the user lifts their finger, 265 // We set the tap timer. If it fires before the user lifts their finger,
247 // one-finger passthrough begins. Otherwise, there is a touch press and 266 // one-finger passthrough begins. Otherwise, there is a touch press and
248 // release at the location of the last touch exploration. 267 // release at the location of the last touch exploration.
249 state_ = DOUBLE_TAP_PENDING; 268 SET_STATE(DOUBLE_TAP_PENDING);
250 VLOG_STATE(); 269 // The old tap timer (from the initial click) is stopped if it is still
270 // going, and the new one is set.
271 tap_timer_.Stop();
251 StartTapTimer(); 272 StartTapTimer();
252 // This will update as the finger moves before a possible passthrough, and 273 // This will update as the finger moves before a possible passthrough, and
253 // will determine the offset. 274 // will determine the offset.
254 last_unused_finger_event_.reset(new ui::TouchEvent(event)); 275 last_unused_finger_event_.reset(new ui::TouchEvent(event));
255 return ui::EVENT_REWRITE_DISCARD; 276 return ui::EVENT_REWRITE_DISCARD;
256 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { 277 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
257 // If the previous press was discarded, we need to also handle its 278 // If the previous press was discarded, we need to also handle its
258 // release. 279 // release.
259 if (current_touch_ids_.size() == 0) { 280 if (current_touch_ids_.size() == 0) {
260 ResetToNoFingersDown(); 281 SET_STATE(NO_FINGERS_DOWN);
261 } 282 }
262 return ui::EVENT_REWRITE_DISCARD; 283 return ui::EVENT_REWRITE_DISCARD;
263 } else if (type == ui::ET_TOUCH_MOVED) { 284 } else if (type == ui::ET_TOUCH_MOVED) {
264 return ui::EVENT_REWRITE_DISCARD; 285 return ui::EVENT_REWRITE_DISCARD;
265 } 286 }
266 NOTREACHED() << "Unexpected event type received: " << event.name(); 287 NOTREACHED();
267 return ui::EVENT_REWRITE_CONTINUE; 288 return ui::EVENT_REWRITE_CONTINUE;
268 } 289 }
269 290
270 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( 291 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending(
271 const ui::TouchEvent& event, 292 const ui::TouchEvent& event,
272 scoped_ptr<ui::Event>* rewritten_event) { 293 scoped_ptr<ui::Event>* rewritten_event) {
273 const ui::EventType type = event.type(); 294 const ui::EventType type = event.type();
274 if (type == ui::ET_TOUCH_PRESSED) { 295 if (type == ui::ET_TOUCH_PRESSED) {
275 return ui::EVENT_REWRITE_DISCARD; 296 return ui::EVENT_REWRITE_DISCARD;
276 } else if (type == ui::ET_TOUCH_MOVED) { 297 } else if (type == ui::ET_TOUCH_MOVED) {
(...skipping 15 matching lines...) Expand all
292 initial_press_->touch_id(), 313 initial_press_->touch_id(),
293 event.time_stamp())); 314 event.time_stamp()));
294 DispatchEvent(touch_press.get()); 315 DispatchEvent(touch_press.get());
295 316
296 rewritten_event->reset( 317 rewritten_event->reset(
297 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 318 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
298 last_touch_exploration_->location(), 319 last_touch_exploration_->location(),
299 initial_press_->touch_id(), 320 initial_press_->touch_id(),
300 event.time_stamp())); 321 event.time_stamp()));
301 (*rewritten_event)->set_flags(event.flags()); 322 (*rewritten_event)->set_flags(event.flags());
302 ResetToNoFingersDown(); 323 SET_STATE(NO_FINGERS_DOWN);
303 return ui::EVENT_REWRITE_REWRITTEN; 324 return ui::EVENT_REWRITE_REWRITTEN;
304 } 325 }
305 NOTREACHED() << "Unexpected event type received: " << event.name(); 326 NOTREACHED();
306 return ui::EVENT_REWRITE_CONTINUE; 327 return ui::EVENT_REWRITE_CONTINUE;
307 } 328 }
308 329
309 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( 330 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending(
310 const ui::TouchEvent& event, 331 const ui::TouchEvent& event,
311 scoped_ptr<ui::Event>* rewritten_event) { 332 scoped_ptr<ui::Event>* rewritten_event) {
312 const ui::EventType type = event.type(); 333 const ui::EventType type = event.type();
313 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { 334 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) {
314 return ui::EVENT_REWRITE_DISCARD; 335 return ui::EVENT_REWRITE_DISCARD;
315 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 336 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
316 if (current_touch_ids_.size() != 0) 337 if (current_touch_ids_.size() != 0)
317 return EVENT_REWRITE_DISCARD; 338 return EVENT_REWRITE_DISCARD;
318 339
319 rewritten_event->reset( 340 rewritten_event->reset(
320 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 341 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
321 last_touch_exploration_->location(), 342 last_touch_exploration_->location(),
322 initial_press_->touch_id(), 343 initial_press_->touch_id(),
323 event.time_stamp())); 344 event.time_stamp()));
324 (*rewritten_event)->set_flags(event.flags()); 345 (*rewritten_event)->set_flags(event.flags());
325 ResetToNoFingersDown(); 346 SET_STATE(NO_FINGERS_DOWN);
326 return ui::EVENT_REWRITE_REWRITTEN; 347 return ui::EVENT_REWRITE_REWRITTEN;
327 } 348 }
328 NOTREACHED() << "Unexpected event type received: " << event.name(); 349 NOTREACHED();
329 return ui::EVENT_REWRITE_CONTINUE; 350 return ui::EVENT_REWRITE_CONTINUE;
330 } 351 }
331 352
332 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 353 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
333 const ui::TouchEvent& event, 354 const ui::TouchEvent& event,
334 scoped_ptr<ui::Event>* rewritten_event) { 355 scoped_ptr<ui::Event>* rewritten_event) {
335 const ui::EventType type = event.type(); 356 const ui::EventType type = event.type();
336 if (type == ui::ET_TOUCH_PRESSED) { 357 if (type == ui::ET_TOUCH_PRESSED) {
337 // Handle split-tap. 358 // Handle split-tap.
338 initial_press_.reset(new TouchEvent(event)); 359 initial_press_.reset(new TouchEvent(event));
339 if (tap_timer_.IsRunning()) 360 tap_timer_.Stop();
340 tap_timer_.Stop();
341 rewritten_event->reset( 361 rewritten_event->reset(
342 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 362 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
343 last_touch_exploration_->location(), 363 last_touch_exploration_->location(),
344 event.touch_id(), 364 event.touch_id(),
345 event.time_stamp())); 365 event.time_stamp()));
346 (*rewritten_event)->set_flags(event.flags()); 366 (*rewritten_event)->set_flags(event.flags());
347 state_ = TOUCH_EXPLORE_SECOND_PRESS; 367 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS);
348 VLOG_STATE();
349 return ui::EVENT_REWRITE_REWRITTEN; 368 return ui::EVENT_REWRITE_REWRITTEN;
350 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 369 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
351 initial_press_.reset(new TouchEvent(event)); 370 initial_press_.reset(new TouchEvent(event));
352 StartTapTimer(); 371 StartTapTimer();
353 state_ = TOUCH_EXPLORE_RELEASED; 372 SET_STATE(TOUCH_EXPLORE_RELEASED);
354 VLOG_STATE();
355 } else if (type != ui::ET_TOUCH_MOVED) { 373 } else if (type != ui::ET_TOUCH_MOVED) {
356 NOTREACHED() << "Unexpected event type received: " << event.name(); 374 NOTREACHED();
357 return ui::EVENT_REWRITE_CONTINUE; 375 return ui::EVENT_REWRITE_CONTINUE;
358 } 376 }
359 377
360 // Rewrite as a mouse-move event. 378 // Rewrite as a mouse-move event.
361 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 379 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
362 last_touch_exploration_.reset(new TouchEvent(event)); 380 last_touch_exploration_.reset(new TouchEvent(event));
363 return ui::EVENT_REWRITE_REWRITTEN; 381 return ui::EVENT_REWRITE_REWRITTEN;
364 } 382 }
365 383
366 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( 384 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
367 const ui::TouchEvent& event, 385 const ui::TouchEvent& event,
368 scoped_ptr<ui::Event>* rewritten_event) { 386 scoped_ptr<ui::Event>* rewritten_event) {
369 ui::EventType type = event.type(); 387 // The events were sent to the gesture provider in RewriteEvent already.
370 // If additional fingers are added before a swipe gesture has been 388 // If no gesture is registered before the tap timer times out, the state
371 // registered, then the state will no longer be GESTURE_IN_PROGRESS. 389 // will change to "wait for no fingers down" or "touch exploration" depending
372 if (type == ui::ET_TOUCH_PRESSED || 390 // on the number of fingers down, and this function will stop being called.
373 event.touch_id() != initial_press_->touch_id()) { 391 if (current_touch_ids_.size() == 0) {
374 if (tap_timer_.IsRunning()) 392 SET_STATE(NO_FINGERS_DOWN);
375 tap_timer_.Stop();
376 // Discard any pending gestures.
377 delete gesture_provider_.GetAndResetPendingGestures();
378 state_ = WAIT_FOR_ONE_FINGER;
379 return EVENT_REWRITE_DISCARD;
380 } 393 }
381
382 // There should not be more than one finger down.
383 DCHECK(current_touch_ids_.size() <= 1);
384 if (type == ui::ET_TOUCH_MOVED) {
385 gesture_provider_.OnTouchEvent(event);
386 gesture_provider_.OnTouchEventAck(false);
387 }
388 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
389 gesture_provider_.OnTouchEvent(event);
390 gesture_provider_.OnTouchEventAck(false);
391 if (current_touch_ids_.size() == 0) {
392 ResetToNoFingersDown();
393 }
394 }
395 ProcessGestureEvents();
396 return ui::EVENT_REWRITE_DISCARD; 394 return ui::EVENT_REWRITE_DISCARD;
397 } 395 }
398 396
399 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( 397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough(
400 const ui::TouchEvent& event, 398 const ui::TouchEvent& event,
401 scoped_ptr<ui::Event>* rewritten_event) { 399 scoped_ptr<ui::Event>* rewritten_event) {
402 ui::EventType type = event.type();
403
404 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED ||
405 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
406 NOTREACHED() << "Unexpected event type received: " << event.name();
407 return ui::EVENT_REWRITE_CONTINUE;
408 }
409 if (event.touch_id() != initial_press_->touch_id()) { 400 if (event.touch_id() != initial_press_->touch_id()) {
410 if (current_touch_ids_.size() == 0) { 401 if (current_touch_ids_.size() == 0) {
411 ResetToNoFingersDown(); 402 SET_STATE(NO_FINGERS_DOWN);
412 } 403 }
413 return ui::EVENT_REWRITE_DISCARD; 404 return ui::EVENT_REWRITE_DISCARD;
414 } 405 }
415 rewritten_event->reset( 406 rewritten_event->reset(
416 new ui::TouchEvent(event.type(), 407 new ui::TouchEvent(event.type(),
417 event.location() - passthrough_offset_, 408 event.location() - passthrough_offset_,
418 event.touch_id(), 409 event.touch_id(),
419 event.time_stamp())); 410 event.time_stamp()));
420 411
421 (*rewritten_event)->set_flags(event.flags()); 412 (*rewritten_event)->set_flags(event.flags());
422 if (current_touch_ids_.size() == 0) { 413 if (current_touch_ids_.size() == 0) {
423 ResetToNoFingersDown(); 414 SET_STATE(NO_FINGERS_DOWN);
424 } 415 }
425
426 return ui::EVENT_REWRITE_REWRITTEN; 416 return ui::EVENT_REWRITE_REWRITTEN;
427 } 417 }
428 418
429 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress( 419 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
430 const ui::TouchEvent& event, 420 const ui::TouchEvent& event,
431 scoped_ptr<ui::Event>* rewritten_event) { 421 scoped_ptr<ui::Event>* rewritten_event) {
432 ui::EventType type = event.type(); 422 ui::EventType type = event.type();
433 gfx::PointF location = event.location_f(); 423 gfx::PointF location = event.location_f();
434 if (type == ui::ET_TOUCH_PRESSED) { 424 if (type == ui::ET_TOUCH_PRESSED) {
435 return ui::EVENT_REWRITE_DISCARD; 425 return ui::EVENT_REWRITE_DISCARD;
436 } else if (type == ui::ET_TOUCH_MOVED) { 426 } else if (type == ui::ET_TOUCH_MOVED) {
437 // Currently this is a discard, but could be something like rotor 427 // Currently this is a discard, but could be something like rotor
438 // in the future. 428 // in the future.
439 return ui::EVENT_REWRITE_DISCARD; 429 return ui::EVENT_REWRITE_DISCARD;
440 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 430 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
441 // If the touch exploration finger is lifted, there is no option to return 431 // If the touch exploration finger is lifted, there is no option to return
442 // to touch explore anymore. The remaining finger acts as a pending 432 // to touch explore anymore. The remaining finger acts as a pending
443 // tap or long tap for the last touch explore location. 433 // tap or long tap for the last touch explore location.
444 if (event.touch_id() == last_touch_exploration_->touch_id()){ 434 if (event.touch_id() == last_touch_exploration_->touch_id()){
445 state_ = TOUCH_RELEASE_PENDING; 435 SET_STATE(TOUCH_RELEASE_PENDING);
446 VLOG_STATE();
447 return EVENT_REWRITE_DISCARD; 436 return EVENT_REWRITE_DISCARD;
448 } 437 }
449 438
450 // Continue to release the touch only if the touch explore finger is the 439 // Continue to release the touch only if the touch explore finger is the
451 // only finger remaining. 440 // only finger remaining.
452 if (current_touch_ids_.size() != 1) 441 if (current_touch_ids_.size() != 1)
453 return EVENT_REWRITE_DISCARD; 442 return EVENT_REWRITE_DISCARD;
454 443
455 // Rewrite at location of last touch exploration. 444 // Rewrite at location of last touch exploration.
456 rewritten_event->reset( 445 rewritten_event->reset(
457 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 446 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
458 last_touch_exploration_->location(), 447 last_touch_exploration_->location(),
459 initial_press_->touch_id(), 448 initial_press_->touch_id(),
460 event.time_stamp())); 449 event.time_stamp()));
461 (*rewritten_event)->set_flags(event.flags()); 450 (*rewritten_event)->set_flags(event.flags());
462 state_ = TOUCH_EXPLORATION; 451 SET_STATE(TOUCH_EXPLORATION);
463 EnterTouchToMouseMode(); 452 EnterTouchToMouseMode();
464 VLOG_STATE();
465 return ui::EVENT_REWRITE_REWRITTEN; 453 return ui::EVENT_REWRITE_REWRITTEN;
466 } 454 }
467 NOTREACHED() << "Unexpected event type received: " << event.name(); 455 NOTREACHED();
468 return ui::EVENT_REWRITE_CONTINUE; 456 return ui::EVENT_REWRITE_CONTINUE;
469 } 457 }
470 458
471 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( 459 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
472 const ui::TouchEvent& event, 460 const ui::TouchEvent& event,
473 scoped_ptr<ui::Event>* rewritten_event) { 461 scoped_ptr<ui::Event>* rewritten_event) {
474 ui::EventType type = event.type(); 462 if (current_touch_ids_.size() == 0)
475 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 463 SET_STATE(NO_FINGERS_DOWN);
476 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
477 NOTREACHED() << "Unexpected event type received: " << event.name();
478 return ui::EVENT_REWRITE_CONTINUE;
479 }
480 if (current_touch_ids_.size() == 1) {
481 EnterTouchToMouseMode();
482 state_ = TOUCH_EXPLORATION;
483 VLOG_STATE();
484 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
485 last_touch_exploration_.reset(new TouchEvent(event));
486 return ui::EVENT_REWRITE_REWRITTEN;
487 }
488 return EVENT_REWRITE_DISCARD; 464 return EVENT_REWRITE_DISCARD;
489 } 465 }
490 466
491 void TouchExplorationController::PlaySoundForTimer() { 467 void TouchExplorationController::PlaySoundForTimer() {
492 delegate_->PlayVolumeAdjustSound(); 468 delegate_->PlayVolumeAdjustSound();
493 } 469 }
494 470
495 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 471 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
496 const ui::TouchEvent& event, 472 const ui::TouchEvent& event,
497 scoped_ptr<ui::Event>* rewritten_event) { 473 scoped_ptr<ui::Event>* rewritten_event) {
498 // The timer should not fire when sliding. 474 // The timer should not fire when sliding.
499 if (tap_timer_.IsRunning()) 475 tap_timer_.Stop();
500 tap_timer_.Stop();
501 476
502 ui::EventType type = event.type(); 477 ui::EventType type = event.type();
503 // If additional fingers are added before a swipe gesture has been registered, 478 // If additional fingers are added before a swipe gesture has been registered,
504 // then wait until all fingers have been lifted. 479 // then wait until all fingers have been lifted.
505 if (type == ui::ET_TOUCH_PRESSED || 480 if (type == ui::ET_TOUCH_PRESSED ||
506 event.touch_id() != initial_press_->touch_id()) { 481 event.touch_id() != initial_press_->touch_id()) {
507 if (sound_timer_.IsRunning()) 482 if (sound_timer_.IsRunning())
508 sound_timer_.Stop(); 483 sound_timer_.Stop();
509 // Discard any pending gestures. 484 SET_STATE(WAIT_FOR_NO_FINGERS);
510 delete gesture_provider_.GetAndResetPendingGestures();
511 state_ = WAIT_FOR_ONE_FINGER;
512 return EVENT_REWRITE_DISCARD; 485 return EVENT_REWRITE_DISCARD;
513 } 486 }
514 487
488 // There should not be more than one finger down.
489 DCHECK(current_touch_ids_.size() <= 1);
490
515 // Allows user to return to the edge to adjust the sound if they have left the 491 // Allows user to return to the edge to adjust the sound if they have left the
516 // boundaries. 492 // boundaries.
517 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); 493 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
518 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { 494 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) {
519 if (sound_timer_.IsRunning()) { 495 if (sound_timer_.IsRunning()) {
520 sound_timer_.Stop(); 496 sound_timer_.Stop();
521 } 497 }
522 return EVENT_REWRITE_DISCARD; 498 return EVENT_REWRITE_DISCARD;
523 } 499 }
524 500
525 // This can occur if the user leaves the screen edge and then returns to it to 501 // This can occur if the user leaves the screen edge and then returns to it to
526 // continue adjusting the sound. 502 // continue adjusting the sound.
527 if (!sound_timer_.IsRunning()) { 503 if (!sound_timer_.IsRunning()) {
528 sound_timer_.Start(FROM_HERE, 504 sound_timer_.Start(FROM_HERE,
529 kSoundDelay, 505 kSoundDelay,
530 this, 506 this,
531 &ui::TouchExplorationController::PlaySoundForTimer); 507 &ui::TouchExplorationController::PlaySoundForTimer);
532 delegate_->PlayVolumeAdjustSound(); 508 delegate_->PlayVolumeAdjustSound();
533 } 509 }
534 510
535 // There should not be more than one finger down. 511 if (current_touch_ids_.size() == 0) {
536 DCHECK(current_touch_ids_.size() <= 1); 512 SET_STATE(NO_FINGERS_DOWN);
537 if (type == ui::ET_TOUCH_MOVED) {
538 gesture_provider_.OnTouchEvent(event);
539 gesture_provider_.OnTouchEventAck(false);
540 } 513 }
541 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
542 gesture_provider_.OnTouchEvent(event);
543 gesture_provider_.OnTouchEventAck(false);
544 delete gesture_provider_.GetAndResetPendingGestures();
545 if (current_touch_ids_.size() == 0) {
546 ResetToNoFingersDown();
547 }
548 return ui::EVENT_REWRITE_DISCARD;
549 }
550
551 ProcessGestureEvents();
552 return ui::EVENT_REWRITE_DISCARD; 514 return ui::EVENT_REWRITE_DISCARD;
553 } 515 }
554 516
555 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( 517 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap(
556 const ui::TouchEvent& event, 518 const ui::TouchEvent& event,
557 scoped_ptr<ui::Event>* rewritten_event) { 519 scoped_ptr<ui::Event>* rewritten_event) {
558 ui::EventType type = event.type(); 520 ui::EventType type = event.type();
559 if (type == ui::ET_TOUCH_PRESSED) { 521 if (type == ui::ET_TOUCH_PRESSED) {
560 // TODO(evy): Process three finger gestures here. 522 // This is now a three finger gesture.
561 state_ = WAIT_FOR_ONE_FINGER; 523 SET_STATE(GESTURE_IN_PROGRESS);
562 VLOG_STATE();
563 return ui::EVENT_REWRITE_DISCARD; 524 return ui::EVENT_REWRITE_DISCARD;
564 } 525 }
565 526
566 if (type == ui::ET_TOUCH_MOVED) { 527 if (type == ui::ET_TOUCH_MOVED) {
567 // Determine if it was a swipe. 528 // Determine if it was a swipe.
568 gfx::Point original_location = initial_presses_[event.touch_id()]; 529 gfx::Point original_location = initial_presses_[event.touch_id()];
569 float distance = (event.location() - original_location).Length(); 530 float distance = (event.location() - original_location).Length();
570 // If the user moves too far from the original position, consider the 531 // If the user moves too far from the original position, consider the
571 // movement a swipe. 532 // movement a swipe.
572 // TODO(evy, lisayin): Add multifinger swipe processing.
573 if (distance > gesture_detector_config_.touch_slop) { 533 if (distance > gesture_detector_config_.touch_slop) {
574 state_ = WAIT_FOR_ONE_FINGER; 534 SET_STATE(GESTURE_IN_PROGRESS);
575 } 535 }
576 return ui::EVENT_REWRITE_DISCARD; 536 return ui::EVENT_REWRITE_DISCARD;
577 } 537 }
578 538
579 if (current_touch_ids_.size() != 0) 539 if (current_touch_ids_.size() != 0)
580 return ui::EVENT_REWRITE_DISCARD; 540 return ui::EVENT_REWRITE_DISCARD;
581 541
582 if (type == ui::ET_TOUCH_RELEASED) { 542 if (type == ui::ET_TOUCH_RELEASED) {
583 // In ChromeVox, pressing control will stop ChromeVox from speaking. 543 // In ChromeVox, pressing control will stop ChromeVox from speaking.
584 ui::KeyEvent control_down( 544 ui::KeyEvent control_down(
585 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN); 545 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN);
586 ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE); 546 ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE);
587 547
588 DispatchEvent(&control_down); 548 DispatchEvent(&control_down);
589 DispatchEvent(&control_up); 549 DispatchEvent(&control_up);
590 550 SET_STATE(NO_FINGERS_DOWN);
591 ResetToNoFingersDown();
592 return ui::EVENT_REWRITE_DISCARD; 551 return ui::EVENT_REWRITE_DISCARD;
593 } 552 }
594 return ui::EVENT_REWRITE_DISCARD; 553 return ui::EVENT_REWRITE_DISCARD;
595 } 554 }
596 555
597 base::TimeDelta TouchExplorationController::Now() { 556 base::TimeDelta TouchExplorationController::Now() {
598 if (tick_clock_) { 557 if (tick_clock_) {
599 // This is the same as what EventTimeForNow() does, but here we do it 558 // This is the same as what EventTimeForNow() does, but here we do it
600 // with a clock that can be replaced with a simulated clock for tests. 559 // with a clock that can be replaced with a simulated clock for tests.
601 return base::TimeDelta::FromInternalValue( 560 return base::TimeDelta::FromInternalValue(
602 tick_clock_->NowTicks().ToInternalValue()); 561 tick_clock_->NowTicks().ToInternalValue());
603 } 562 }
604 return ui::EventTimeForNow(); 563 return ui::EventTimeForNow();
605 } 564 }
606 565
607 void TouchExplorationController::StartTapTimer() { 566 void TouchExplorationController::StartTapTimer() {
608 tap_timer_.Start(FROM_HERE, 567 tap_timer_.Start(FROM_HERE,
609 gesture_detector_config_.double_tap_timeout, 568 gesture_detector_config_.double_tap_timeout,
610 this, 569 this,
611 &TouchExplorationController::OnTapTimerFired); 570 &TouchExplorationController::OnTapTimerFired);
612 } 571 }
613 572
614 void TouchExplorationController::OnTapTimerFired() { 573 void TouchExplorationController::OnTapTimerFired() {
615 switch (state_) { 574 switch (state_) {
616 case SINGLE_TAP_RELEASED: 575 case SINGLE_TAP_RELEASED:
617 ResetToNoFingersDown(); 576 SET_STATE(NO_FINGERS_DOWN);
618 break; 577 break;
619 case TOUCH_EXPLORE_RELEASED: 578 case TOUCH_EXPLORE_RELEASED:
620 ResetToNoFingersDown(); 579 SET_STATE(NO_FINGERS_DOWN);
621 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 580 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
622 return; 581 return;
623 case DOUBLE_TAP_PENDING: { 582 case DOUBLE_TAP_PENDING: {
624 state_ = ONE_FINGER_PASSTHROUGH; 583 SET_STATE(ONE_FINGER_PASSTHROUGH);
625 VLOG_STATE();
626 passthrough_offset_ = last_unused_finger_event_->location() - 584 passthrough_offset_ = last_unused_finger_event_->location() -
627 last_touch_exploration_->location(); 585 last_touch_exploration_->location();
628 scoped_ptr<ui::TouchEvent> passthrough_press( 586 scoped_ptr<ui::TouchEvent> passthrough_press(
629 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 587 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
630 last_touch_exploration_->location(), 588 last_touch_exploration_->location(),
631 last_unused_finger_event_->touch_id(), 589 last_unused_finger_event_->touch_id(),
632 Now())); 590 Now()));
633 DispatchEvent(passthrough_press.get()); 591 DispatchEvent(passthrough_press.get());
634 return; 592 return;
635 } 593 }
636 case SINGLE_TAP_PRESSED: 594 case SINGLE_TAP_PRESSED:
595 EnterTouchToMouseMode();
596 SET_STATE(TOUCH_EXPLORATION);
597 break;
637 case GESTURE_IN_PROGRESS: 598 case GESTURE_IN_PROGRESS:
638 // Discard any pending gestures. 599 // If only one finger is down, go into touch exploration.
639 delete gesture_provider_.GetAndResetPendingGestures(); 600 if (current_touch_ids_.size() == 1) {
640 state_ = TOUCH_EXPLORATION; 601 EnterTouchToMouseMode();
641 VLOG_STATE(); 602 SET_STATE(TOUCH_EXPLORATION);
642 break; 603 break;
604 }
605 // Otherwise wait for all fingers to be lifted.
606 SET_STATE(WAIT_FOR_NO_FINGERS);
607 return;
643 case TWO_FINGER_TAP: 608 case TWO_FINGER_TAP:
644 state_ = WAIT_FOR_ONE_FINGER; 609 SET_STATE(WAIT_FOR_NO_FINGERS);
645 VLOG_STATE();
646 break; 610 break;
647 default: 611 default:
648 return; 612 return;
649 } 613 }
650 EnterTouchToMouseMode(); 614 EnterTouchToMouseMode();
651 scoped_ptr<ui::Event> mouse_move = 615 scoped_ptr<ui::Event> mouse_move =
652 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 616 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
653 DispatchEvent(mouse_move.get()); 617 DispatchEvent(mouse_move.get());
654 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 618 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
655 } 619 }
656 620
657 void TouchExplorationController::DispatchEvent(ui::Event* event) { 621 void TouchExplorationController::DispatchEvent(ui::Event* event) {
658 ui::EventDispatchDetails result ALLOW_UNUSED = 622 ui::EventDispatchDetails result ALLOW_UNUSED =
659 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 623 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
660 } 624 }
661 625
662 void TouchExplorationController::OnGestureEvent( 626 // This is an override for a function that is only called for timer-based events
663 ui::GestureEvent* gesture) { 627 // like long press. Events that are created synchronously as a result of
664 CHECK(gesture->IsGestureEvent()); 628 // certain touch events are added to the vector accessible via
665 ui::EventType type = gesture->type(); 629 // GetAndResetPendingGestures(). We only care about swipes (which are created
666 if (VLOG_on_) 630 // synchronously), so we ignore this callback.
667 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); 631 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) {
668 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) {
669 if (VLOG_on_)
670 VLOG(0) << "Swipe!";
671 delete gesture_provider_.GetAndResetPendingGestures();
672 OnSwipeEvent(gesture);
673 return;
674 }
675 } 632 }
676 633
677 void TouchExplorationController::ProcessGestureEvents() { 634 void TouchExplorationController::ProcessGestureEvents() {
678 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( 635 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
679 gesture_provider_.GetAndResetPendingGestures()); 636 gesture_provider_->GetAndResetPendingGestures());
680 if (gestures) { 637 if (gestures) {
681 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); 638 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
682 i != gestures->end(); 639 i != gestures->end();
683 ++i) { 640 ++i) {
684 if (state_ == SLIDE_GESTURE) 641 if ((*i)->type() == ui::ET_GESTURE_SWIPE &&
642 state_ == GESTURE_IN_PROGRESS) {
643 OnSwipeEvent(*i);
644 // The tap timer to leave gesture state is ended, and we now wait for
645 // all fingers to be released.
646 tap_timer_.Stop();
647 SET_STATE(WAIT_FOR_NO_FINGERS);
648 return;
649 }
650 if (state_ == SLIDE_GESTURE && (*i)->IsScrollGestureEvent()) {
685 SideSlideControl(*i); 651 SideSlideControl(*i);
686 else 652 }
687 OnGestureEvent(*i);
688 } 653 }
689 } 654 }
690 } 655 }
691 656
692 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 657 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
693 ui::EventType type = gesture->type(); 658 ui::EventType type = gesture->type();
694 if (!gesture->IsScrollGestureEvent())
695 return;
696 659
697 if (type == ET_GESTURE_SCROLL_BEGIN) { 660 if (type == ET_GESTURE_SCROLL_BEGIN) {
698 delegate_->PlayVolumeAdjustSound(); 661 delegate_->PlayVolumeAdjustSound();
699 } 662 }
700 663
701 if (type == ET_GESTURE_SCROLL_END) { 664 if (type == ET_GESTURE_SCROLL_END) {
702 if (sound_timer_.IsRunning()) 665 if (sound_timer_.IsRunning())
703 sound_timer_.Stop(); 666 sound_timer_.Stop();
704 delegate_->PlayVolumeAdjustSound(); 667 delegate_->PlayVolumeAdjustSound();
705 } 668 }
(...skipping 24 matching lines...) Expand all
730 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; 693 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height;
731 float volume = 100 - 100 * ratio; 694 float volume = 100 - 100 * ratio;
732 if (VLOG_on_) { 695 if (VLOG_on_) {
733 VLOG(0) << "\n Volume = " << volume 696 VLOG(0) << "\n Volume = " << volume
734 << "\n Location = " << location.ToString() 697 << "\n Location = " << location.ToString()
735 << "\n Bounds = " << root_window_->bounds().right(); 698 << "\n Bounds = " << root_window_->bounds().right();
736 } 699 }
737 delegate_->SetOutputLevel(int(volume)); 700 delegate_->SetOutputLevel(int(volume));
738 } 701 }
739 702
740
741 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 703 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
742 // A swipe gesture contains details for the direction in which the swipe 704 // A swipe gesture contains details for the direction in which the swipe
743 // occurred. 705 // occurred. TODO(evy) : Research which swipe results users most want and
706 // remap these swipes to the best events. Hopefully in the near future
707 // there will also be a menu for users to pick custom mappings.
744 GestureEventDetails event_details = swipe_gesture->details(); 708 GestureEventDetails event_details = swipe_gesture->details();
745 if (event_details.swipe_left()) { 709 int num_fingers = event_details.touch_points();
746 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 710 if(VLOG_on_)
711 VLOG(0) << "\nSwipe with " << num_fingers << " fingers.";
712
713 if (num_fingers > 4)
747 return; 714 return;
748 } else if (event_details.swipe_right()) { 715
749 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); 716 if (event_details.swipe_left() &&
750 return; 717 !left_swipe_gestures_[num_fingers].is_null()) {
751 } else if (event_details.swipe_up()) { 718 left_swipe_gestures_[num_fingers].Run();
752 DispatchShiftSearchKeyEvent(ui::VKEY_UP); 719 } else if (event_details.swipe_right() &&
753 return; 720 !right_swipe_gestures_[num_fingers].is_null()) {
754 } else if (event_details.swipe_down()) { 721 right_swipe_gestures_[num_fingers].Run();
755 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); 722 } else if (event_details.swipe_up() &&
756 return; 723 !up_swipe_gestures_[num_fingers].is_null()) {
724 up_swipe_gestures_[num_fingers].Run();
725 } else if (event_details.swipe_down() &&
726 !down_swipe_gestures_[num_fingers].is_null()) {
727 down_swipe_gestures_[num_fingers].Run();
757 } 728 }
758 } 729 }
759 730
760 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, 731 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point,
761 float bounds) { 732 float bounds) {
762 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be 733 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be
763 // converted. 734 // converted.
764 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); 735 root_window_->GetHost()->ConvertPointFromNativeScreen(&point);
765 gfx::Rect window = root_window_->GetBoundsInScreen(); 736 gfx::Rect window = root_window_->GetBoundsInScreen();
766 737
(...skipping 12 matching lines...) Expand all
779 if (point.x() > right_edge_limit) 750 if (point.x() > right_edge_limit)
780 result |= RIGHT_EDGE; 751 result |= RIGHT_EDGE;
781 if (point.y() < top_edge_limit) 752 if (point.y() < top_edge_limit)
782 result |= TOP_EDGE; 753 result |= TOP_EDGE;
783 if (point.y() > bottom_edge_limit) 754 if (point.y() > bottom_edge_limit)
784 result |= BOTTOM_EDGE; 755 result |= BOTTOM_EDGE;
785 return result; 756 return result;
786 } 757 }
787 758
788 void TouchExplorationController::DispatchShiftSearchKeyEvent( 759 void TouchExplorationController::DispatchShiftSearchKeyEvent(
789 const ui::KeyboardCode direction) { 760 const ui::KeyboardCode third_key) {
790 // In order to activate the shortcut shift+search+<arrow key> 761 // In order to activate the shortcut shift+search+<arrow key>
791 // three KeyPressed events must be dispatched in succession along 762 // three KeyPressed events must be dispatched in succession along
792 // with three KeyReleased events. 763 // with three KeyReleased events.
793 ui::KeyEvent shift_down = ui::KeyEvent( 764
765 ui::KeyEvent shift_down(
794 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); 766 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
795 ui::KeyEvent search_down = ui::KeyEvent( 767 ui::KeyEvent search_down(
796 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 768 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
797 ui::KeyEvent direction_down = 769 ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN);
798 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN);
799 770
800 ui::KeyEvent direction_up = 771 ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN);
801 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); 772 ui::KeyEvent search_up(
802 ui::KeyEvent search_up = ui::KeyEvent(
803 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 773 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
804 ui::KeyEvent shift_up = 774 ui::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
805 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
806 775
807 DispatchEvent(&shift_down); 776 DispatchEvent(&shift_down);
808 DispatchEvent(&search_down); 777 DispatchEvent(&search_down);
809 DispatchEvent(&direction_down); 778 DispatchEvent(&third_key_down);
810 DispatchEvent(&direction_up); 779 DispatchEvent(&third_key_up);
811 DispatchEvent(&search_up); 780 DispatchEvent(&search_up);
812 DispatchEvent(&shift_up); 781 DispatchEvent(&shift_up);
813 } 782 }
814 783
784 base::Closure TouchExplorationController::BindShiftSearchKeyEvent(
785 const ui::KeyboardCode third_key) {
786 return base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
787 base::Unretained(this),
788 third_key);
789 }
790
791 void TouchExplorationController::DispatchKeyWithFlags(
792 const ui::KeyboardCode key,
793 int flags) {
794 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags);
795 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags);
796 DispatchEvent(&key_down);
797 DispatchEvent(&key_up);
798 if(VLOG_on_) {
799 VLOG(0) << "\nKey down: key code : " << key_down.key_code()
800 << ", flags: " << key_down.flags()
801 << "\nKey up: key code : " << key_up.key_code()
802 << ", flags: " << key_up.flags();
803 }
804 }
805
806 base::Closure TouchExplorationController::BindKeyEventWithFlags(
807 const ui::KeyboardCode key,
808 int flags) {
809 return base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
810 base::Unretained(this),
811 key,
812 flags);
813 }
814
815 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( 815 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
816 const gfx::PointF& location, 816 const gfx::PointF& location,
817 int flags) { 817 int flags) {
818 // The "synthesized" flag should be set on all events that don't have a 818 // The "synthesized" flag should be set on all events that don't have a
819 // backing native event. 819 // backing native event.
820 flags |= ui::EF_IS_SYNTHESIZED; 820 flags |= ui::EF_IS_SYNTHESIZED;
821 821
822 // This flag is used to identify mouse move events that were generated from 822 // This flag is used to identify mouse move events that were generated from
823 // touch exploration in Chrome code. 823 // touch exploration in Chrome code.
824 flags |= ui::EF_TOUCH_ACCESSIBILITY; 824 flags |= ui::EF_TOUCH_ACCESSIBILITY;
(...skipping 15 matching lines...) Expand all
840 840
841 void TouchExplorationController::EnterTouchToMouseMode() { 841 void TouchExplorationController::EnterTouchToMouseMode() {
842 aura::client::CursorClient* cursor_client = 842 aura::client::CursorClient* cursor_client =
843 aura::client::GetCursorClient(root_window_); 843 aura::client::GetCursorClient(root_window_);
844 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 844 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
845 cursor_client->EnableMouseEvents(); 845 cursor_client->EnableMouseEvents();
846 if (cursor_client && cursor_client->IsCursorVisible()) 846 if (cursor_client && cursor_client->IsCursorVisible())
847 cursor_client->HideCursor(); 847 cursor_client->HideCursor();
848 } 848 }
849 849
850 void TouchExplorationController::ResetToNoFingersDown() { 850 void TouchExplorationController::SetState(State new_state,
851 ProcessGestureEvents(); 851 const char* function_name) {
852 initial_presses_.clear(); 852 state_ = new_state;
853 if (sound_timer_.IsRunning()) 853 VlogState(function_name);
854 sound_timer_.Stop(); 854 // These are the states the user can be in that will never result in a
855 state_ = NO_FINGERS_DOWN; 855 // gesture before the user returns to NO_FINGERS_DOWN. Therefore, if the
856 VLOG_STATE(); 856 // gesture provider still exists, it's reset to NULL until the user returns
857 if (tap_timer_.IsRunning()) 857 // to NO_FINGERS_DOWN.
858 tap_timer_.Stop(); 858 switch (new_state) {
859 case SINGLE_TAP_RELEASED:
860 case TOUCH_EXPLORE_RELEASED:
861 case DOUBLE_TAP_PENDING:
862 case TOUCH_RELEASE_PENDING:
863 case TOUCH_EXPLORATION:
864 case TOUCH_EXPLORE_SECOND_PRESS:
865 case ONE_FINGER_PASSTHROUGH:
866 case WAIT_FOR_NO_FINGERS:
867 if (gesture_provider_.get())
868 gesture_provider_.reset(NULL);
869 break;
870 case NO_FINGERS_DOWN:
871 gesture_provider_.reset(new GestureProviderAura(this));
872 if (sound_timer_.IsRunning())
873 sound_timer_.Stop();
874 tap_timer_.Stop();
875 break;
876 case SINGLE_TAP_PRESSED:
877 case GESTURE_IN_PROGRESS:
878 case SLIDE_GESTURE:
879 case TWO_FINGER_TAP:
880 break;
881 }
859 } 882 }
860 883
861 void TouchExplorationController::VlogState(const char* function_name) { 884 void TouchExplorationController::VlogState(const char* function_name) {
862 if (!VLOG_on_) 885 if (!VLOG_on_)
863 return; 886 return;
864 if (prev_state_ == state_) 887 if (prev_state_ == state_)
865 return; 888 return;
866 prev_state_ = state_; 889 prev_state_ = state_;
867 const char* state_string = EnumStateToString(state_); 890 const char* state_string = EnumStateToString(state_);
868 VLOG(0) << "\n Function name: " << function_name 891 VLOG(0) << "\n Function name: " << function_name
869 << "\n State: " << state_string; 892 << "\n State: " << state_string;
870 } 893 }
871 894
872 void TouchExplorationController::VlogEvent(const ui::TouchEvent& touch_event, 895 void TouchExplorationController::VlogEvent(const ui::TouchEvent& touch_event,
873 const char* function_name) { 896 const char* function_name) {
874 if (!VLOG_on_) 897 if (!VLOG_on_)
875 return; 898 return;
876 899
877 CHECK(touch_event.IsTouchEvent());
878 if (prev_event_ != NULL && 900 if (prev_event_ != NULL &&
879 prev_event_->type() == touch_event.type() && 901 prev_event_->type() == touch_event.type() &&
880 prev_event_->touch_id() == touch_event.touch_id()){ 902 prev_event_->touch_id() == touch_event.touch_id()){
881 return; 903 return;
882 } 904 }
883 // The above statement prevents events of the same type and id from being 905 // The above statement prevents events of the same type and id from being
884 // printed in a row. However, if two fingers are down, they would both be 906 // printed in a row. However, if two fingers are down, they would both be
885 // moving and alternating printing move events unless we check for this. 907 // moving and alternating printing move events unless we check for this.
886 if (prev_event_ != NULL && 908 if (prev_event_ != NULL &&
887 prev_event_->type() == ET_TOUCH_MOVED && 909 prev_event_->type() == ET_TOUCH_MOVED &&
888 touch_event.type() == ET_TOUCH_MOVED){ 910 touch_event.type() == ET_TOUCH_MOVED){
889 return; 911 return;
890 } 912 }
913
891 const std::string& type = touch_event.name(); 914 const std::string& type = touch_event.name();
892 const gfx::PointF& location = touch_event.location_f(); 915 const gfx::PointF& location = touch_event.location_f();
893 const int touch_id = touch_event.touch_id(); 916 const int touch_id = touch_event.touch_id();
894 917
895 VLOG(0) << "\n Function name: " << function_name 918 VLOG(0) << "\n Function name: " << function_name
896 << "\n Event Type: " << type 919 << "\n Event Type: " << type
897 << "\n Location: " << location.ToString() 920 << "\n Location: " << location.ToString()
898 << "\n Touch ID: " << touch_id; 921 << "\n Touch ID: " << touch_id;
899 prev_event_.reset(new TouchEvent(touch_event)); 922 prev_event_.reset(new TouchEvent(touch_event));
900 } 923 }
(...skipping 15 matching lines...) Expand all
916 case TOUCH_EXPLORATION: 939 case TOUCH_EXPLORATION:
917 return "TOUCH_EXPLORATION"; 940 return "TOUCH_EXPLORATION";
918 case GESTURE_IN_PROGRESS: 941 case GESTURE_IN_PROGRESS:
919 return "GESTURE_IN_PROGRESS"; 942 return "GESTURE_IN_PROGRESS";
920 case TOUCH_EXPLORE_SECOND_PRESS: 943 case TOUCH_EXPLORE_SECOND_PRESS:
921 return "TOUCH_EXPLORE_SECOND_PRESS"; 944 return "TOUCH_EXPLORE_SECOND_PRESS";
922 case SLIDE_GESTURE: 945 case SLIDE_GESTURE:
923 return "SLIDE_GESTURE"; 946 return "SLIDE_GESTURE";
924 case ONE_FINGER_PASSTHROUGH: 947 case ONE_FINGER_PASSTHROUGH:
925 return "ONE_FINGER_PASSTHROUGH"; 948 return "ONE_FINGER_PASSTHROUGH";
926 case WAIT_FOR_ONE_FINGER: 949 case WAIT_FOR_NO_FINGERS:
927 return "WAIT_FOR_ONE_FINGER"; 950 return "WAIT_FOR_NO_FINGERS";
928 case TWO_FINGER_TAP: 951 case TWO_FINGER_TAP:
929 return "TWO_FINGER_TAP"; 952 return "TWO_FINGER_TAP";
930 } 953 }
931 return "Not a state"; 954 return "Not a state";
932 } 955 }
933 956
957 // TODO(evy, lisayin) : Just call abstracted methods on the delegate (e.g.
958 // Swipe(Direction direction, int num_fingers)), and add the DispatchXYZ
959 // methods to the delegate. Avoid the middle step of dispatching keys at all,
960 // and simply have ChromeVox/ChromeOS complete the required action.
961
962 void TouchExplorationController::InitializeSwipeGestureMaps() {
963 // Gestures with one finger are used for navigation.
964 left_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_LEFT);
965 right_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_RIGHT);
966 up_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_UP);
967 down_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_DOWN);
968
969 // Gestures with two fingers.
970 left_swipe_gestures_[2] =
971 BindKeyEventWithFlags(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
972 right_swipe_gestures_[2] =
973 BindKeyEventWithFlags(ui::VKEY_BROWSER_FORWARD, ui::EF_NONE);
974 // Jump to top.
975 up_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_A);
976 // Read from here.
977 down_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_R);
978
979 // Gestures with three fingers switch tabs left/right and scroll up/down.
980 left_swipe_gestures_[3] = BindKeyEventWithFlags(
981 ui::VKEY_TAB, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
982 right_swipe_gestures_[3] =
983 BindKeyEventWithFlags(ui::VKEY_TAB, ui::EF_CONTROL_DOWN);
984 up_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_NEXT, ui::EF_NONE);
985 down_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_PRIOR, ui::EF_NONE);
986
987 // Gestures with four fingers should probably eventually be used for rare
988 // needs that are hard to access through menus.
989 // Note that brightness levels are here because they can be important for low
990 // vision users. However, none of these mappings are permanent.
991 left_swipe_gestures_[4] =
992 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
993 right_swipe_gestures_[4] =
994 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE);
995 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE);
996 down_swipe_gestures_[4] =
997 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE);
998 }
999
934 } // namespace ui 1000 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/touch_exploration_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698