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

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: Changes from James 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_EXPLORE_SECOND_PRESS:
133 return InTouchExploreSecondPress(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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 NOTREACHED() << "Unexpected event type received."; 194 NOTREACHED() << "Unexpected event type received.";
193 return ui::EVENT_REWRITE_CONTINUE; 195 return ui::EVENT_REWRITE_CONTINUE;
194 } 196 }
195 197
196 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased( 198 ui::EventRewriteStatus TouchExplorationController::InSingleTapReleased(
197 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 199 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
198 const ui::EventType type = event.type(); 200 const ui::EventType type = event.type();
199 if (type == ui::ET_TOUCH_PRESSED) { 201 if (type == ui::ET_TOUCH_PRESSED) {
200 // This is the second tap in a double-tap (or double tap-hold). 202 // This is the second tap in a double-tap (or double tap-hold).
201 // Rewrite at location of last touch exploration. 203 // Rewrite at location of last touch exploration.
202 ui::TouchEvent* rewritten_press_event = new ui::TouchEvent( 204 // If there is no touch exploration yet, discard instead.
203 ui::ET_TOUCH_PRESSED, 205 if (!last_touch_exploration_) {
204 last_touch_exploration_location_, 206 return ui::EVENT_REWRITE_DISCARD;
205 event.touch_id(), 207 }
206 event.time_stamp()); 208 rewritten_event->reset(
207 rewritten_press_event->set_flags(event.flags()); 209 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
208 rewritten_event->reset(rewritten_press_event); 210 last_touch_exploration_->location(),
211 event.touch_id(),
212 event.time_stamp()));
213 (*rewritten_event)->set_flags(event.flags());
209 state_ = DOUBLE_TAP_PRESSED; 214 state_ = DOUBLE_TAP_PRESSED;
210 VLOG_STATE(); 215 VLOG_STATE();
211 return ui::EVENT_REWRITE_REWRITTEN; 216 return ui::EVENT_REWRITE_REWRITTEN;
212 } 217 }
213 218 // If the previous press was discarded, we need to also handle its release.
219 if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
220 if (current_touch_ids_.size() == 0) {
221 state_ = NO_FINGERS_DOWN;
222 }
223 return ui::EVENT_REWRITE_DISCARD;
224 }
214 NOTREACHED(); 225 NOTREACHED();
215 return ui::EVENT_REWRITE_CONTINUE; 226 return ui::EVENT_REWRITE_CONTINUE;
216 } 227 }
217 228
218 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( 229 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed(
219 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 230 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
220 const ui::EventType type = event.type(); 231 const ui::EventType type = event.type();
221 if (type == ui::ET_TOUCH_PRESSED) { 232 if (type == ui::ET_TOUCH_PRESSED) {
222 return ui::EVENT_REWRITE_DISCARD; 233 return ui::EVENT_REWRITE_DISCARD;
223 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 234 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
224 if (current_touch_ids_.size() != 0) 235 if (current_touch_ids_.size() != 0)
225 return EVENT_REWRITE_DISCARD; 236 return EVENT_REWRITE_DISCARD;
226 237
227 // Rewrite at location of last touch exploration. 238 // Rewrite at location of last touch exploration.
228 ui::TouchEvent* rewritten_release_event = new ui::TouchEvent( 239 rewritten_event->reset(
229 ui::ET_TOUCH_RELEASED, 240 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
230 last_touch_exploration_location_, 241 last_touch_exploration_->location(),
231 event.touch_id(), 242 event.touch_id(),
232 event.time_stamp()); 243 event.time_stamp()));
233 rewritten_release_event->set_flags(event.flags()); 244 (*rewritten_event)->set_flags(event.flags());
234 rewritten_event->reset(rewritten_release_event);
235 ResetToNoFingersDown(); 245 ResetToNoFingersDown();
236 return ui::EVENT_REWRITE_REWRITTEN; 246 return ui::EVENT_REWRITE_REWRITTEN;
237 } else if (type == ui::ET_TOUCH_MOVED) { 247 } else if (type == ui::ET_TOUCH_MOVED) {
238 return ui::EVENT_REWRITE_DISCARD; 248 return ui::EVENT_REWRITE_DISCARD;
239 } 249 }
240 NOTREACHED() << "Unexpected event type received."; 250 NOTREACHED() << "Unexpected event type received.";
241 return ui::EVENT_REWRITE_CONTINUE; 251 return ui::EVENT_REWRITE_CONTINUE;
242 } 252 }
243 253
244 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 254 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
245 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 255 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
246 const ui::EventType type = event.type(); 256 const ui::EventType type = event.type();
247 if (type == ui::ET_TOUCH_PRESSED) { 257 if (type == ui::ET_TOUCH_PRESSED) {
248 // Ignore any additional fingers when we're already in touch exploration 258 // Handle split-tap.
249 // mode. TODO(evy, lisayin): Support "split-tap" here instead. 259 initial_press_.reset(new TouchEvent(event));
250 return ui::EVENT_REWRITE_DISCARD; 260 if (tap_timer_.IsRunning())
261 tap_timer_.Stop();
262 rewritten_event->reset(
263 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
264 last_touch_exploration_->location(),
265 event.touch_id(),
266 event.time_stamp()));
267 (*rewritten_event)->set_flags(event.flags());
268 state_ = TOUCH_EXPLORE_SECOND_PRESS;
269 VLOG_STATE();
270 return ui::EVENT_REWRITE_REWRITTEN;
251 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 271 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
252 if (current_touch_ids_.size() == 0) 272 if (current_touch_ids_.size() == 0)
253 ResetToNoFingersDown(); 273 ResetToNoFingersDown();
254 } else if (type != ui::ET_TOUCH_MOVED) { 274 } else if (type != ui::ET_TOUCH_MOVED) {
255 NOTREACHED() << "Unexpected event type received."; 275 NOTREACHED() << "Unexpected event type received.";
256 return ui::EVENT_REWRITE_CONTINUE; 276 return ui::EVENT_REWRITE_CONTINUE;
257 } 277 }
258 278
259 // Rewrite as a mouse-move event. 279 // Rewrite as a mouse-move event.
260 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 280 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
261 last_touch_exploration_location_ = event.location(); 281 last_touch_exploration_.reset(new TouchEvent(event));
262 return ui::EVENT_REWRITE_REWRITTEN; 282 return ui::EVENT_REWRITE_REWRITTEN;
263 } 283 }
264 284
265 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( 285 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne(
266 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 286 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
267 ui::EventType type = event.type(); 287 ui::EventType type = event.type();
268 gfx::PointF location = event.location_f(); 288 gfx::PointF location = event.location_f();
269 289
270 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 290 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
271 if (current_touch_ids_.size() == 0) 291 if (current_touch_ids_.size() == 0)
272 ResetToNoFingersDown(); 292 ResetToNoFingersDown();
273 293
274 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { 294 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) {
275 if (event.touch_id() == initial_press_->touch_id()) { 295 if (event.touch_id() == initial_press_->touch_id()) {
276 initial_touch_id_passthrough_mapping_ = kTouchIdNone; 296 initial_touch_id_passthrough_mapping_ = kTouchIdNone;
277 } else { 297 } else {
278 // If the only finger now remaining is the first finger, 298 // If the only finger now remaining is the first finger,
279 // rewrite as a move to the location of the first finger. 299 // rewrite as a move to the location of the first finger.
280 initial_touch_id_passthrough_mapping_ = event.touch_id(); 300 initial_touch_id_passthrough_mapping_ = event.touch_id();
281 ui::TouchEvent* rewritten_passthrough_event = new ui::TouchEvent( 301 rewritten_event->reset(
282 ui::ET_TOUCH_MOVED, 302 new ui::TouchEvent(ui::ET_TOUCH_MOVED,
283 touch_locations_[initial_press_->touch_id()], 303 touch_locations_[initial_press_->touch_id()],
284 initial_touch_id_passthrough_mapping_, 304 initial_touch_id_passthrough_mapping_,
285 event.time_stamp()); 305 event.time_stamp()));
286 rewritten_passthrough_event->set_flags(event.flags()); 306 (*rewritten_event)->set_flags(event.flags());
287 rewritten_event->reset(rewritten_passthrough_event);
288 return ui::EVENT_REWRITE_REWRITTEN; 307 return ui::EVENT_REWRITE_REWRITTEN;
289 } 308 }
290 } 309 }
291 } 310 }
292 311
293 if (event.touch_id() == initial_press_->touch_id()) { 312 if (event.touch_id() == initial_press_->touch_id()) {
294 if (initial_touch_id_passthrough_mapping_ == kTouchIdNone || 313 if (initial_touch_id_passthrough_mapping_ == kTouchIdNone ||
295 initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { 314 initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) {
296 return ui::EVENT_REWRITE_DISCARD; 315 return ui::EVENT_REWRITE_DISCARD;
297 } 316 }
298 317
299 ui::TouchEvent* rewritten_passthrough_event = new ui::TouchEvent( 318 rewritten_event->reset(
300 type, 319 new ui::TouchEvent(type,
301 location, 320 location,
302 initial_touch_id_passthrough_mapping_, 321 initial_touch_id_passthrough_mapping_,
303 event.time_stamp()); 322 event.time_stamp()));
304 rewritten_passthrough_event->set_flags(event.flags()); 323 (*rewritten_event)->set_flags(event.flags());
305 rewritten_event->reset(rewritten_passthrough_event);
306 return ui::EVENT_REWRITE_REWRITTEN; 324 return ui::EVENT_REWRITE_REWRITTEN;
307 } 325 }
308 326
309 return ui::EVENT_REWRITE_CONTINUE; 327 return ui::EVENT_REWRITE_CONTINUE;
310 } 328 }
311 329
330 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
331 const ui::TouchEvent& event,
332 scoped_ptr<ui::Event>* rewritten_event) {
333 ui::EventType type = event.type();
334 gfx::PointF location = event.location_f();
335 if (type == ui::ET_TOUCH_PRESSED) {
336 return ui::EVENT_REWRITE_DISCARD;
337 } else if (type == ui::ET_TOUCH_MOVED) {
338 // Currently this is a discard, but could be something like rotor
339 // in the future.
340 return ui::EVENT_REWRITE_DISCARD;
341 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
342 // If the touch exploration finger is lifted, there is no option to return
343 // to touch explore anymore. The remaining finger acts as a pending
344 // tap or long tap for the last touch explore location.
345 if (event.touch_id() == last_touch_exploration_->touch_id()){
346 state_ = DOUBLE_TAP_PRESSED;
347 VLOG_STATE();
348 return EVENT_REWRITE_DISCARD;
349 }
350
351 // Continue to release the touch only if the touch explore finger is the
352 // only finger remaining.
353 if (current_touch_ids_.size() != 1)
354 return EVENT_REWRITE_DISCARD;
355
356 // Rewrite at location of last touch exploration.
357 rewritten_event->reset(
358 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
359 last_touch_exploration_->location(),
360 initial_press_->touch_id(),
361 event.time_stamp()));
362 (*rewritten_event)->set_flags(event.flags());
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 394
336 ui::EventDispatchDetails result ALLOW_UNUSED = 395 ui::EventDispatchDetails result ALLOW_UNUSED =
337 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 396 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
(...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 TOUCH_EXPLORE_SECOND_PRESS:
469 return "TOUCH_EXPLORE_SECOND_PRESS";
409 } 470 }
410 return "Not a state"; 471 return "Not a state";
411 } 472 }
412 473
413 std::string TouchExplorationController::EnumEventTypeToString( 474 std::string 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); 488 return base::IntToString(type);
428 } 489 }
429 } 490 }
430 491
431 } // namespace ui 492 } // 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