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

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: Dominic's 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 case SINGLE_TAP_PRESSED: 123 case SINGLE_TAP_PRESSED:
124 return InSingleTapPressed(touch_event, rewritten_event); 124 return InSingleTapPressed(touch_event, rewritten_event);
125 case SINGLE_TAP_RELEASED: 125 case SINGLE_TAP_RELEASED:
126 return InSingleTapReleased(touch_event, rewritten_event); 126 return InSingleTapReleased(touch_event, rewritten_event);
127 case DOUBLE_TAP_PRESSED: 127 case DOUBLE_TAP_PRESSED:
128 return InDoubleTapPressed(touch_event, rewritten_event); 128 return InDoubleTapPressed(touch_event, rewritten_event);
129 case TOUCH_EXPLORATION: 129 case TOUCH_EXPLORATION:
130 return InTouchExploration(touch_event, rewritten_event); 130 return InTouchExploration(touch_event, rewritten_event);
131 case PASSTHROUGH_MINUS_ONE: 131 case PASSTHROUGH_MINUS_ONE:
132 return InPassthroughMinusOne(touch_event, rewritten_event); 132 return InPassthroughMinusOne(touch_event, rewritten_event);
133 case TE_SECOND_PRESS:
134 return InTouchExplSecondPress(touch_event, rewritten_event);
133 } 135 }
134 136
135 NOTREACHED(); 137 NOTREACHED();
136 return ui::EVENT_REWRITE_CONTINUE; 138 return ui::EVENT_REWRITE_CONTINUE;
137 } 139 }
138 140
139 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 141 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
140 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 142 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
141 NOTREACHED(); 143 NOTREACHED();
142 return ui::EVENT_REWRITE_CONTINUE; 144 return ui::EVENT_REWRITE_CONTINUE;
143 } 145 }
144 146
145 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 147 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
146 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 148 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
147 const ui::EventType type = event.type(); 149 const ui::EventType type = event.type();
148 if (type == ui::ET_TOUCH_PRESSED) { 150 if (type == ui::ET_TOUCH_PRESSED) {
151 // If this is the first ever touch, initialize last_touch_exploration_
aboxhall 2014/06/13 17:06:48 This seems odd to me. If this isn't a touch explor
evy 2014/06/13 17:48:59 This will happen if the user hasn't entered touch
aboxhall 2014/06/13 18:20:00 I see, so this would be the case where a user doub
152 // to avoid null pointer references later.
153 if (last_touch_exploration_ == NULL) {
154 last_touch_exploration_.reset(new TouchEvent(event));
155 }
149 initial_press_.reset(new TouchEvent(event)); 156 initial_press_.reset(new TouchEvent(event));
150 tap_timer_.Start(FROM_HERE, 157 tap_timer_.Start(FROM_HERE,
151 gesture_detector_config_.double_tap_timeout, 158 gesture_detector_config_.double_tap_timeout,
152 this, 159 this,
153 &TouchExplorationController::OnTapTimerFired); 160 &TouchExplorationController::OnTapTimerFired);
154 state_ = SINGLE_TAP_PRESSED; 161 state_ = SINGLE_TAP_PRESSED;
155 VLOG_STATE(); 162 VLOG_STATE();
156 return ui::EVENT_REWRITE_DISCARD; 163 return ui::EVENT_REWRITE_DISCARD;
157 } 164 }
158 NOTREACHED(); 165 NOTREACHED();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 200 }
194 201
195 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased( 202 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased(
196 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 203 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
197 const ui::EventType type = event.type(); 204 const ui::EventType type = event.type();
198 if (type == ui::ET_TOUCH_PRESSED) { 205 if (type == ui::ET_TOUCH_PRESSED) {
199 // This is the second tap in a double-tap (or double tap-hold). 206 // This is the second tap in a double-tap (or double tap-hold).
200 // Rewrite at location of last touch exploration. 207 // Rewrite at location of last touch exploration.
201 ui::TouchEvent* rewritten_press_event = new ui::TouchEvent( 208 ui::TouchEvent* rewritten_press_event = new ui::TouchEvent(
202 ui::ET_TOUCH_PRESSED, 209 ui::ET_TOUCH_PRESSED,
203 last_touch_exploration_location_, 210 last_touch_exploration_->location(),
204 event.touch_id(), 211 event.touch_id(),
205 event.time_stamp()); 212 event.time_stamp());
206 rewritten_press_event->set_flags(event.flags()); 213 rewritten_press_event->set_flags(event.flags());
207 rewritten_event->reset(rewritten_press_event); 214 rewritten_event->reset(rewritten_press_event);
208 state_ = DOUBLE_TAP_PRESSED; 215 state_ = DOUBLE_TAP_PRESSED;
209 VLOG_STATE(); 216 VLOG_STATE();
210 return ui::EVENT_REWRITE_REWRITTEN; 217 return ui::EVENT_REWRITE_REWRITTEN;
211 } 218 }
212 219
213 NOTREACHED(); 220 NOTREACHED();
214 return ui::EVENT_REWRITE_CONTINUE; 221 return ui::EVENT_REWRITE_CONTINUE;
215 } 222 }
216 223
217 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( 224 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed(
218 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 225 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
219 const ui::EventType type = event.type(); 226 const ui::EventType type = event.type();
220 if (type == ui::ET_TOUCH_PRESSED) { 227 if (type == ui::ET_TOUCH_PRESSED) {
221 return ui::EVENT_REWRITE_DISCARD; 228 return ui::EVENT_REWRITE_DISCARD;
222 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 229 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
223 if (current_touch_ids_.size() != 0) 230 if (current_touch_ids_.size() != 0)
224 return EVENT_REWRITE_DISCARD; 231 return EVENT_REWRITE_DISCARD;
225 232
226 // Rewrite at location of last touch exploration. 233 // Rewrite at location of last touch exploration.
227 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent( 234 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent(
228 ui::ET_TOUCH_RELEASED, 235 ui::ET_TOUCH_RELEASED,
229 last_touch_exploration_location_, 236 last_touch_exploration_->location(),
230 event.touch_id(), 237 event.touch_id(),
231 event.time_stamp()); 238 event.time_stamp());
232 rewritten_release_event->set_flags(event.flags()); 239 rewritten_release_event->set_flags(event.flags());
233 rewritten_event->reset(rewritten_release_event); 240 rewritten_event->reset(rewritten_release_event);
234 ResetToNoFingersDown(); 241 ResetToNoFingersDown();
235 return ui::EVENT_REWRITE_REWRITTEN; 242 return ui::EVENT_REWRITE_REWRITTEN;
236 } else if (type == ui::ET_TOUCH_MOVED) { 243 } else if (type == ui::ET_TOUCH_MOVED) {
237 return ui::EVENT_REWRITE_DISCARD; 244 return ui::EVENT_REWRITE_DISCARD;
238 } 245 }
239 NOTREACHED() << "Unexpected event type received."; 246 NOTREACHED() << "Unexpected event type received.";
240 return ui::EVENT_REWRITE_CONTINUE; 247 return ui::EVENT_REWRITE_CONTINUE;
241 } 248 }
242 249
243 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 250 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
244 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 251 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
245 const ui::EventType type = event.type(); 252 const ui::EventType type = event.type();
246 if (type == ui::ET_TOUCH_PRESSED) { 253 if (type == ui::ET_TOUCH_PRESSED) {
247 254 // Split-tap
248 // Ignore any additional fingers when we're already in touch exploration 255 initial_press_.reset(new TouchEvent(event));
249 // mode. TODO(evy, lisayin): Support "split-tap" here instead. 256 if (tap_timer_.IsRunning())
250 return ui::EVENT_REWRITE_DISCARD; 257 tap_timer_.Stop();
258 ui::TouchEvent* rewritten_touch_event =
259 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
260 last_touch_exploration_->location(),
261 event.touch_id(),
262 event.time_stamp());
263 rewritten_touch_event->set_flags(event.flags());
264 rewritten_event->reset(rewritten_touch_event);
265 state_ = TE_SECOND_PRESS;
266 VLOG_STATE();
267 return ui::EVENT_REWRITE_REWRITTEN;
251 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 268 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
252 if (current_touch_ids_.size() == 0) 269 if (current_touch_ids_.size() == 0)
253 ResetToNoFingersDown(); 270 ResetToNoFingersDown();
254 } else if (type != ui::ET_TOUCH_MOVED) { 271 } else if (type != ui::ET_TOUCH_MOVED) {
255 NOTREACHED() << "Unexpected event type received."; 272 NOTREACHED() << "Unexpected event type received.";
256 return ui::EVENT_REWRITE_CONTINUE; 273 return ui::EVENT_REWRITE_CONTINUE;
257 } 274 }
258 275
259 // Rewrite as a mouse-move event. 276 // Rewrite as a mouse-move event.
260 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 277 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
261 last_touch_exploration_location_ = event.location(); 278 last_touch_exploration_.reset(new TouchEvent(event));
262 return ui::EVENT_REWRITE_REWRITTEN; 279 return ui::EVENT_REWRITE_REWRITTEN;
263 } 280 }
264 281
265 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( 282 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne(
266 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 283 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
267 ui::EventType type = event.type(); 284 ui::EventType type = event.type();
268 gfx::PointF location = event.location_f(); 285 gfx::PointF location = event.location_f();
269 286
270 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 287 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
271 if (current_touch_ids_.size() == 0) 288 if (current_touch_ids_.size() == 0)
(...skipping 30 matching lines...) Expand all
302 initial_touch_id_passthrough_mapping_, 319 initial_touch_id_passthrough_mapping_,
303 event.time_stamp()); 320 event.time_stamp());
304 rewritten_passthrough_event->set_flags(event.flags()); 321 rewritten_passthrough_event->set_flags(event.flags());
305 rewritten_event->reset(rewritten_passthrough_event); 322 rewritten_event->reset(rewritten_passthrough_event);
306 return ui::EVENT_REWRITE_REWRITTEN; 323 return ui::EVENT_REWRITE_REWRITTEN;
307 } 324 }
308 325
309 return ui::EVENT_REWRITE_CONTINUE; 326 return ui::EVENT_REWRITE_CONTINUE;
310 } 327 }
311 328
329 ui::EventRewriteStatus TouchExplorationController::InTouchExplSecondPress(
330 const ui::TouchEvent& event,
331 scoped_ptr<ui::Event>* rewritten_event) {
332 ui::EventType type = event.type();
333 gfx::PointF location = event.location_f();
334 if (type == ui::ET_TOUCH_PRESSED) {
335 return ui::EVENT_REWRITE_DISCARD;
336 } else if (type == ui::ET_TOUCH_MOVED) {
337 // Currently this is a discard, but could be something like rotor
338 // in the future.
339 return ui::EVENT_REWRITE_DISCARD;
340 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
341 // If the touch exploration finger is lifted, there is no option to return
342 // to touch explore anymore. The remaining finger acts as a pending
343 // tap or long tap for the last touch explore location.
344 if (event.touch_id() == last_touch_exploration_->touch_id()){
345 state_ = DOUBLE_TAP_PRESSED;
346 VLOG_STATE();
347 return EVENT_REWRITE_DISCARD;
348 }
349
350 // Continue to release the touch only if the touch explore finger is the
351 // only finger remaining.
352 if (current_touch_ids_.size() != 1)
353 return EVENT_REWRITE_DISCARD;
354
355 // Rewrite at location of last touch exploration.
356 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent(
357 ui::ET_TOUCH_RELEASED,
358 last_touch_exploration_->location(),
359 initial_press_->touch_id(),
360 event.time_stamp());
361 rewritten_release_event->set_flags(event.flags());
362 rewritten_event->reset(rewritten_release_event);
363 state_ = TOUCH_EXPLORATION;
364 VLOG_STATE();
365 return ui::EVENT_REWRITE_REWRITTEN;
366 }
367 NOTREACHED() << "Unexpected event type received.";
368 return ui::EVENT_REWRITE_CONTINUE;
369 }
370
312 void TouchExplorationController::OnTapTimerFired() { 371 void TouchExplorationController::OnTapTimerFired() {
313 if (state_ != SINGLE_TAP_RELEASED && state_ != SINGLE_TAP_PRESSED) 372 if (state_ != SINGLE_TAP_RELEASED && state_ != SINGLE_TAP_PRESSED)
314 return; 373 return;
315 374
316 if (state_ == SINGLE_TAP_RELEASED) { 375 if (state_ == SINGLE_TAP_RELEASED) {
317 ResetToNoFingersDown(); 376 ResetToNoFingersDown();
318 } else { 377 } else {
319 EnterTouchToMouseMode(); 378 EnterTouchToMouseMode();
320 state_ = TOUCH_EXPLORATION; 379 state_ = TOUCH_EXPLORATION;
321 VLOG_STATE(); 380 VLOG_STATE();
322 } 381 }
323 382
324 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( 383 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent(
325 initial_press_->location(), initial_press_->flags()); 384 initial_press_->location(), initial_press_->flags());
326 DispatchEvent(mouse_move.get()); 385 DispatchEvent(mouse_move.get());
327 last_touch_exploration_location_ = initial_press_->location(); 386 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
328 } 387 }
329 388
330 void TouchExplorationController::DispatchEvent(ui::Event* event) { 389 void TouchExplorationController::DispatchEvent(ui::Event* event) {
331 if (event_handler_for_testing_) { 390 if (event_handler_for_testing_) {
332 event_handler_for_testing_->OnEvent(event); 391 event_handler_for_testing_->OnEvent(event);
333 return; 392 return;
334 } 393 }
335 ui::EventDispatchDetails result ALLOW_UNUSED = 394 ui::EventDispatchDetails result ALLOW_UNUSED =
336 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 395 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
337 } 396 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 case SINGLE_TAP_PRESSED: 458 case SINGLE_TAP_PRESSED:
400 return "SINGLE_TAP_PRESSED"; 459 return "SINGLE_TAP_PRESSED";
401 case SINGLE_TAP_RELEASED: 460 case SINGLE_TAP_RELEASED:
402 return "SINGLE_TAP_RELEASED"; 461 return "SINGLE_TAP_RELEASED";
403 case DOUBLE_TAP_PRESSED: 462 case DOUBLE_TAP_PRESSED:
404 return "DOUBLE_TAP_PRESSED"; 463 return "DOUBLE_TAP_PRESSED";
405 case TOUCH_EXPLORATION: 464 case TOUCH_EXPLORATION:
406 return "TOUCH_EXPLORATION"; 465 return "TOUCH_EXPLORATION";
407 case PASSTHROUGH_MINUS_ONE: 466 case PASSTHROUGH_MINUS_ONE:
408 return "PASSTHROUGH_MINUS_ONE"; 467 return "PASSTHROUGH_MINUS_ONE";
468 case TE_SECOND_PRESS:
469 return "TE_SECOND_PRESS";
409 } 470 }
410 return "Not a state"; 471 return "Not a state";
411 } 472 }
412 473
413 const char* TouchExplorationController::EnumEventTypeToString( 474 const char* TouchExplorationController::EnumEventTypeToString(
414 ui::EventType type) { 475 ui::EventType type) {
415 // Add more cases later. For now, these are the most frequently seen 476 // Add more cases later. For now, these are the most frequently seen
416 // event types. 477 // event types.
417 switch (type) { 478 switch (type) {
418 case ET_TOUCH_RELEASED: 479 case ET_TOUCH_RELEASED:
419 return "ET_TOUCH_RELEASED"; 480 return "ET_TOUCH_RELEASED";
420 case ET_TOUCH_PRESSED: 481 case ET_TOUCH_PRESSED:
421 return "ET_TOUCH_PRESSED"; 482 return "ET_TOUCH_PRESSED";
422 case ET_TOUCH_MOVED: 483 case ET_TOUCH_MOVED:
423 return "ET_TOUCH_MOVED"; 484 return "ET_TOUCH_MOVED";
424 case ET_TOUCH_CANCELLED: 485 case ET_TOUCH_CANCELLED:
425 return "ET_TOUCH_CANCELLED"; 486 return "ET_TOUCH_CANCELLED";
426 default: 487 default:
427 return base::IntToString(type).c_str(); 488 return base::IntToString(type).c_str();
428 } 489 }
429 } 490 }
430 491
431 } // namespace ui 492 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698