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

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

Issue 333623003: Added split tap to TouchExplorationController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@VLOG
Patch Set: Little nit changes Created 6 years, 6 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 "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
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
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_){
James Cook 2014/06/17 17:06:17 nit: space between ) and { (I'm surprised git cl
evy 2014/06/17 18:36:22 Done.
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.
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
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
James Cook 2014/06/17 17:06:17 rotor?
evy 2014/06/17 18:36:22 On an iPad, rotating two fingers (like they are op
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(
James Cook 2014/06/17 17:06:17 Can you do it like this? rewritten_event->reset(n
evy 2014/06/17 18:36:22 Done. I also changed it the other few times this p
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698