OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "ui/aura/client/cursor_client.h" | 9 #include "ui/aura/client/cursor_client.h" |
10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 case SINGLE_TAP_PRESSED: | 122 case SINGLE_TAP_PRESSED: |
123 return InSingleTapPressed(touch_event, rewritten_event); | 123 return InSingleTapPressed(touch_event, rewritten_event); |
124 case SINGLE_TAP_RELEASED: | 124 case SINGLE_TAP_RELEASED: |
125 return InSingleTapReleased(touch_event, rewritten_event); | 125 return InSingleTapReleased(touch_event, rewritten_event); |
126 case DOUBLE_TAP_PRESSED: | 126 case DOUBLE_TAP_PRESSED: |
127 return InDoubleTapPressed(touch_event, rewritten_event); | 127 return InDoubleTapPressed(touch_event, rewritten_event); |
128 case TOUCH_EXPLORATION: | 128 case TOUCH_EXPLORATION: |
129 return InTouchExploration(touch_event, rewritten_event); | 129 return InTouchExploration(touch_event, rewritten_event); |
130 case PASSTHROUGH_MINUS_ONE: | 130 case PASSTHROUGH_MINUS_ONE: |
131 return InPassthroughMinusOne(touch_event, rewritten_event); | 131 return InPassthroughMinusOne(touch_event, rewritten_event); |
132 case TOUCH_EXPL_SECOND_PRESS: | |
133 return InTouchExplSecondPress(touch_event, rewritten_event); | |
132 } | 134 } |
133 | 135 |
134 NOTREACHED(); | 136 NOTREACHED(); |
135 return ui::EVENT_REWRITE_CONTINUE; | 137 return ui::EVENT_REWRITE_CONTINUE; |
136 } | 138 } |
137 | 139 |
138 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 140 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
139 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 141 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
140 NOTREACHED(); | 142 NOTREACHED(); |
141 return ui::EVENT_REWRITE_CONTINUE; | 143 return ui::EVENT_REWRITE_CONTINUE; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 NOTREACHED() << "Unexpected event type received."; | 192 NOTREACHED() << "Unexpected event type received."; |
191 return ui::EVENT_REWRITE_CONTINUE; | 193 return ui::EVENT_REWRITE_CONTINUE; |
192 } | 194 } |
193 | 195 |
194 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased( | 196 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased( |
195 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 197 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
196 const ui::EventType type = event.type(); | 198 const ui::EventType type = event.type(); |
197 if (type == ui::ET_TOUCH_PRESSED) { | 199 if (type == ui::ET_TOUCH_PRESSED) { |
198 // This is the second tap in a double-tap (or double tap-hold). | 200 // This is the second tap in a double-tap (or double tap-hold). |
199 // Rewrite at location of last touch exploration. | 201 // Rewrite at location of last touch exploration. |
200 ui::TouchEvent* rewritten_press_event = new ui::TouchEvent( | 202 // If there is no touch exploration yet, discard instead. |
201 ui::ET_TOUCH_PRESSED, | 203 if (!last_touch_exploration_) { |
202 last_touch_exploration_location_, | 204 return ui::EVENT_REWRITE_DISCARD; |
203 event.touch_id(), | 205 } |
204 event.time_stamp()); | 206 ui::TouchEvent* rewritten_press_event = |
207 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
208 last_touch_exploration_->location(), | |
209 event.touch_id(), | |
210 event.time_stamp()); | |
205 rewritten_press_event->set_flags(event.flags()); | 211 rewritten_press_event->set_flags(event.flags()); |
206 rewritten_event->reset(rewritten_press_event); | 212 rewritten_event->reset(rewritten_press_event); |
207 state_ = DOUBLE_TAP_PRESSED; | 213 state_ = DOUBLE_TAP_PRESSED; |
208 VLOG_STATE(); | 214 VLOG_STATE(); |
209 return ui::EVENT_REWRITE_REWRITTEN; | 215 return ui::EVENT_REWRITE_REWRITTEN; |
210 } | 216 } |
211 | 217 // If the previous press was discarded, we need to also handle its release. |
218 if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_){ | |
219 if (current_touch_ids_.size() == 0) { | |
220 state_ = NO_FINGERS_DOWN; | |
221 } | |
222 return ui::EVENT_REWRITE_DISCARD; | |
223 } | |
212 NOTREACHED(); | 224 NOTREACHED(); |
213 return ui::EVENT_REWRITE_CONTINUE; | 225 return ui::EVENT_REWRITE_CONTINUE; |
214 } | 226 } |
215 | 227 |
216 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( | 228 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( |
217 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 229 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
218 const ui::EventType type = event.type(); | 230 const ui::EventType type = event.type(); |
219 if (type == ui::ET_TOUCH_PRESSED) { | 231 if (type == ui::ET_TOUCH_PRESSED) { |
220 return ui::EVENT_REWRITE_DISCARD; | 232 return ui::EVENT_REWRITE_DISCARD; |
221 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 233 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
222 if (current_touch_ids_.size() != 0) | 234 if (current_touch_ids_.size() != 0) |
223 return EVENT_REWRITE_DISCARD; | 235 return EVENT_REWRITE_DISCARD; |
224 | 236 |
225 // Rewrite at location of last touch exploration. | 237 // Rewrite at location of last touch exploration. |
226 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent( | 238 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent( |
227 ui::ET_TOUCH_RELEASED, | 239 ui::ET_TOUCH_RELEASED, |
228 last_touch_exploration_location_, | 240 last_touch_exploration_->location(), |
229 event.touch_id(), | 241 event.touch_id(), |
230 event.time_stamp()); | 242 event.time_stamp()); |
231 rewritten_release_event->set_flags(event.flags()); | 243 rewritten_release_event->set_flags(event.flags()); |
232 rewritten_event->reset(rewritten_release_event); | 244 rewritten_event->reset(rewritten_release_event); |
233 ResetToNoFingersDown(); | 245 ResetToNoFingersDown(); |
234 return ui::EVENT_REWRITE_REWRITTEN; | 246 return ui::EVENT_REWRITE_REWRITTEN; |
235 } else if (type == ui::ET_TOUCH_MOVED) { | 247 } else if (type == ui::ET_TOUCH_MOVED) { |
236 return ui::EVENT_REWRITE_DISCARD; | 248 return ui::EVENT_REWRITE_DISCARD; |
237 } | 249 } |
238 NOTREACHED() << "Unexpected event type received."; | 250 NOTREACHED() << "Unexpected event type received."; |
239 return ui::EVENT_REWRITE_CONTINUE; | 251 return ui::EVENT_REWRITE_CONTINUE; |
240 } | 252 } |
241 | 253 |
242 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( | 254 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( |
243 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 255 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
244 const ui::EventType type = event.type(); | 256 const ui::EventType type = event.type(); |
245 if (type == ui::ET_TOUCH_PRESSED) { | 257 if (type == ui::ET_TOUCH_PRESSED) { |
246 | 258 // Handle split-tap |
dmazzoni
2014/06/17 15:50:40
Nit: period at end of sentence.
evy
2014/06/17 15:57:33
Done.
| |
247 // Ignore any additional fingers when we're already in touch exploration | 259 initial_press_.reset(new TouchEvent(event)); |
248 // mode. TODO(evy, lisayin): Support "split-tap" here instead. | 260 if (tap_timer_.IsRunning()) |
249 return ui::EVENT_REWRITE_DISCARD; | 261 tap_timer_.Stop(); |
262 ui::TouchEvent* rewritten_touch_event = | |
263 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
264 last_touch_exploration_->location(), | |
265 event.touch_id(), | |
266 event.time_stamp()); | |
267 rewritten_touch_event->set_flags(event.flags()); | |
268 rewritten_event->reset(rewritten_touch_event); | |
269 state_ = TOUCH_EXPL_SECOND_PRESS; | |
270 VLOG_STATE(); | |
271 return ui::EVENT_REWRITE_REWRITTEN; | |
250 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 272 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
251 if (current_touch_ids_.size() == 0) | 273 if (current_touch_ids_.size() == 0) |
252 ResetToNoFingersDown(); | 274 ResetToNoFingersDown(); |
253 } else if (type != ui::ET_TOUCH_MOVED) { | 275 } else if (type != ui::ET_TOUCH_MOVED) { |
254 NOTREACHED() << "Unexpected event type received."; | 276 NOTREACHED() << "Unexpected event type received."; |
255 return ui::EVENT_REWRITE_CONTINUE; | 277 return ui::EVENT_REWRITE_CONTINUE; |
256 } | 278 } |
257 | 279 |
258 // Rewrite as a mouse-move event. | 280 // Rewrite as a mouse-move event. |
259 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 281 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
260 last_touch_exploration_location_ = event.location(); | 282 last_touch_exploration_.reset(new TouchEvent(event)); |
261 return ui::EVENT_REWRITE_REWRITTEN; | 283 return ui::EVENT_REWRITE_REWRITTEN; |
262 } | 284 } |
263 | 285 |
264 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( | 286 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( |
265 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 287 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
266 ui::EventType type = event.type(); | 288 ui::EventType type = event.type(); |
267 gfx::PointF location = event.location_f(); | 289 gfx::PointF location = event.location_f(); |
268 | 290 |
269 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 291 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
270 if (current_touch_ids_.size() == 0) | 292 if (current_touch_ids_.size() == 0) |
(...skipping 30 matching lines...) Expand all Loading... | |
301 initial_touch_id_passthrough_mapping_, | 323 initial_touch_id_passthrough_mapping_, |
302 event.time_stamp()); | 324 event.time_stamp()); |
303 rewritten_passthrough_event->set_flags(event.flags()); | 325 rewritten_passthrough_event->set_flags(event.flags()); |
304 rewritten_event->reset(rewritten_passthrough_event); | 326 rewritten_event->reset(rewritten_passthrough_event); |
305 return ui::EVENT_REWRITE_REWRITTEN; | 327 return ui::EVENT_REWRITE_REWRITTEN; |
306 } | 328 } |
307 | 329 |
308 return ui::EVENT_REWRITE_CONTINUE; | 330 return ui::EVENT_REWRITE_CONTINUE; |
309 } | 331 } |
310 | 332 |
333 ui::EventRewriteStatus TouchExplorationController::InTouchExplSecondPress( | |
334 const ui::TouchEvent& event, | |
335 scoped_ptr<ui::Event>* rewritten_event) { | |
336 ui::EventType type = event.type(); | |
337 gfx::PointF location = event.location_f(); | |
338 if (type == ui::ET_TOUCH_PRESSED) { | |
339 return ui::EVENT_REWRITE_DISCARD; | |
340 } else if (type == ui::ET_TOUCH_MOVED) { | |
341 // Currently this is a discard, but could be something like rotor | |
342 // in the future. | |
343 return ui::EVENT_REWRITE_DISCARD; | |
344 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
345 // If the touch exploration finger is lifted, there is no option to return | |
346 // to touch explore anymore. The remaining finger acts as a pending | |
347 // tap or long tap for the last touch explore location. | |
348 if (event.touch_id() == last_touch_exploration_->touch_id()){ | |
349 state_ = DOUBLE_TAP_PRESSED; | |
350 VLOG_STATE(); | |
351 return EVENT_REWRITE_DISCARD; | |
352 } | |
353 | |
354 // Continue to release the touch only if the touch explore finger is the | |
355 // only finger remaining. | |
356 if (current_touch_ids_.size() != 1) | |
357 return EVENT_REWRITE_DISCARD; | |
358 | |
359 // Rewrite at location of last touch exploration. | |
360 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent( | |
361 ui::ET_TOUCH_RELEASED, | |
362 last_touch_exploration_->location(), | |
363 initial_press_->touch_id(), | |
364 event.time_stamp()); | |
365 rewritten_release_event->set_flags(event.flags()); | |
366 rewritten_event->reset(rewritten_release_event); | |
367 state_ = TOUCH_EXPLORATION; | |
368 VLOG_STATE(); | |
369 return ui::EVENT_REWRITE_REWRITTEN; | |
370 } | |
371 NOTREACHED() << "Unexpected event type received."; | |
372 return ui::EVENT_REWRITE_CONTINUE; | |
373 } | |
374 | |
311 void TouchExplorationController::OnTapTimerFired() { | 375 void TouchExplorationController::OnTapTimerFired() { |
312 if (state_ != SINGLE_TAP_RELEASED && state_ != SINGLE_TAP_PRESSED) | 376 if (state_ != SINGLE_TAP_RELEASED && state_ != SINGLE_TAP_PRESSED) |
313 return; | 377 return; |
314 | 378 |
315 if (state_ == SINGLE_TAP_RELEASED) { | 379 if (state_ == SINGLE_TAP_RELEASED) { |
316 ResetToNoFingersDown(); | 380 ResetToNoFingersDown(); |
317 } else { | 381 } else { |
318 EnterTouchToMouseMode(); | 382 EnterTouchToMouseMode(); |
319 state_ = TOUCH_EXPLORATION; | 383 state_ = TOUCH_EXPLORATION; |
320 VLOG_STATE(); | 384 VLOG_STATE(); |
321 } | 385 } |
322 | 386 |
323 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( | 387 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( |
324 initial_press_->location(), initial_press_->flags()); | 388 initial_press_->location(), initial_press_->flags()); |
325 DispatchEvent(mouse_move.get()); | 389 DispatchEvent(mouse_move.get()); |
326 last_touch_exploration_location_ = initial_press_->location(); | 390 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
327 } | 391 } |
328 | 392 |
329 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 393 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
330 if (event_handler_for_testing_) { | 394 if (event_handler_for_testing_) { |
331 event_handler_for_testing_->OnEvent(event); | 395 event_handler_for_testing_->OnEvent(event); |
332 return; | 396 return; |
333 } | 397 } |
334 ui::EventDispatchDetails result ALLOW_UNUSED = | 398 ui::EventDispatchDetails result ALLOW_UNUSED = |
335 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 399 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
336 } | 400 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 case SINGLE_TAP_PRESSED: | 462 case SINGLE_TAP_PRESSED: |
399 return "SINGLE_TAP_PRESSED"; | 463 return "SINGLE_TAP_PRESSED"; |
400 case SINGLE_TAP_RELEASED: | 464 case SINGLE_TAP_RELEASED: |
401 return "SINGLE_TAP_RELEASED"; | 465 return "SINGLE_TAP_RELEASED"; |
402 case DOUBLE_TAP_PRESSED: | 466 case DOUBLE_TAP_PRESSED: |
403 return "DOUBLE_TAP_PRESSED"; | 467 return "DOUBLE_TAP_PRESSED"; |
404 case TOUCH_EXPLORATION: | 468 case TOUCH_EXPLORATION: |
405 return "TOUCH_EXPLORATION"; | 469 return "TOUCH_EXPLORATION"; |
406 case PASSTHROUGH_MINUS_ONE: | 470 case PASSTHROUGH_MINUS_ONE: |
407 return "PASSTHROUGH_MINUS_ONE"; | 471 return "PASSTHROUGH_MINUS_ONE"; |
472 case TOUCH_EXPL_SECOND_PRESS: | |
473 return "TOUCH_EXPL_SECOND_PRESS"; | |
408 } | 474 } |
409 return "Not a state"; | 475 return "Not a state"; |
410 } | 476 } |
411 | 477 |
412 std::string TouchExplorationController::EnumEventTypeToString( | 478 std::string TouchExplorationController::EnumEventTypeToString( |
413 ui::EventType type) { | 479 ui::EventType type) { |
414 // Add more cases later. For now, these are the most frequently seen | 480 // Add more cases later. For now, these are the most frequently seen |
415 // event types. | 481 // event types. |
416 switch (type) { | 482 switch (type) { |
417 case ET_TOUCH_RELEASED: | 483 case ET_TOUCH_RELEASED: |
418 return "ET_TOUCH_RELEASED"; | 484 return "ET_TOUCH_RELEASED"; |
419 case ET_TOUCH_PRESSED: | 485 case ET_TOUCH_PRESSED: |
420 return "ET_TOUCH_PRESSED"; | 486 return "ET_TOUCH_PRESSED"; |
421 case ET_TOUCH_MOVED: | 487 case ET_TOUCH_MOVED: |
422 return "ET_TOUCH_MOVED"; | 488 return "ET_TOUCH_MOVED"; |
423 case ET_TOUCH_CANCELLED: | 489 case ET_TOUCH_CANCELLED: |
424 return "ET_TOUCH_CANCELLED"; | 490 return "ET_TOUCH_CANCELLED"; |
425 default: | 491 default: |
426 return base::IntToString(type); | 492 return base::IntToString(type); |
427 } | 493 } |
428 } | 494 } |
429 | 495 |
430 } // namespace ui | 496 } // namespace ui |
OLD | NEW |