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

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

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
« no previous file with comments | « no previous file | ui/chromeos/touch_exploration_controller.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 5 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
7 7
8 #include "base/time/tick_clock.h" 8 #include "base/time/tick_clock.h"
9 #include "base/timer/timer.h" 9 #include "base/timer/timer.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // edge of the screen can change settings. 51 // edge of the screen can change settings.
52 // 52 //
53 // ** Short version ** 53 // ** Short version **
54 // 54 //
55 // At a high-level, single-finger events are used for accessibility - 55 // At a high-level, single-finger events are used for accessibility -
56 // exploring the screen gets turned into mouse moves (which can then be 56 // exploring the screen gets turned into mouse moves (which can then be
57 // spoken by an accessibility service running), a single tap while the user 57 // spoken by an accessibility service running), a single tap while the user
58 // is in touch exploration or a double-tap simulates a click, and gestures 58 // is in touch exploration or a double-tap simulates a click, and gestures
59 // can be used to send high-level accessibility commands. For example, a swipe 59 // can be used to send high-level accessibility commands. For example, a swipe
60 // right would correspond to the keyboard short cut shift+search+right. 60 // right would correspond to the keyboard short cut shift+search+right.
61 // When two or more fingers are pressed initially, from then on the events 61 // Swipes with up to four fingers are also mapped to commands. Slide
62 // are passed through, but with the initial finger removed - so if you swipe
63 // down with two fingers, the running app will see a one-finger swipe. Slide
64 // gestures performed on the edge of the screen can change settings 62 // gestures performed on the edge of the screen can change settings
65 // continuously. For example, sliding a finger along the right side of the 63 // continuously. For example, sliding a finger along the right side of the
66 // screen will change the volume. When a user double taps and holds with one 64 // screen will change the volume. When a user double taps and holds with one
67 // finger, the finger is passed through as if accessibility was turned off. If 65 // finger, the finger is passed through as if accessibility was turned off. If
68 // the user taps the screen with two fingers, the user can silence spoken 66 // the user taps the screen with two fingers, the user can silence spoken
69 // feedback if it is playing. 67 // feedback if it is playing.
70 // 68 //
71 // ** Long version ** 69 // ** Long version **
72 // 70 //
73 // Here are the details of the implementation: 71 // Here are the details of the implementation:
(...skipping 12 matching lines...) Expand all
86 // If the user taps and releases their finger, after 300 ms from the initial 84 // If the user taps and releases their finger, after 300 ms from the initial
87 // touch, a single mouse move is fired. 85 // touch, a single mouse move is fired.
88 // 86 //
89 // While in touch exploration mode, the user can perform a single tap 87 // While in touch exploration mode, the user can perform a single tap
90 // if the user releases their finger and taps before 300 ms passes. 88 // if the user releases their finger and taps before 300 ms passes.
91 // This will result in a click on the last successful touch exploration 89 // This will result in a click on the last successful touch exploration
92 // location. This allows the user to perform a single tap 90 // location. This allows the user to perform a single tap
93 // anywhere to activate it. 91 // anywhere to activate it.
94 // 92 //
95 // The user can perform swipe gestures in one of the four cardinal directions 93 // The user can perform swipe gestures in one of the four cardinal directions
96 // which will be interpreted and used to control the UI. The gesture will only 94 // which will be interpreted and used to control the UI. All gestures will only
97 // be registered if the finger moves outside the slop and completed within the 95 // be registered if the fingers move outside the slop, and all fingers will only
98 // grace period. If additional fingers are added during the grace period, the 96 // be registered if they are completed within the grace period. If a single
99 // state changes to wait for those fingers to be released, and then goes to 97 // finger gesture fails to be completed within the grace period, the state
100 // touch exploration mode. If the gesture fails to be completed within the 98 // changes to touch exploration mode. If a multi finger gesture fails to be
101 // grace period, the state changes to touch exploration mode. Once the state has 99 // completed within the grace period, the user must lift all fingers before
102 // changed, any gestures made during the grace period are discarded. 100 // completing any more actions.
103 // 101 //
104 // If the user double-taps, the second tap is passed through, allowing the 102 // If the user double-taps, the second tap is passed through, allowing the
105 // user to click - however, the double-tap location is changed to the location 103 // user to click - however, the double-tap location is changed to the location
106 // of the last successful touch exploration - that allows the user to explore 104 // of the last successful touch exploration - that allows the user to explore
107 // anywhere on the screen, hear its description, then double-tap anywhere 105 // anywhere on the screen, hear its description, then double-tap anywhere
108 // to activate it. 106 // to activate it.
109 // 107 //
110 // If the user double taps and holds, any event from that finger is passed 108 // If the user double taps and holds, any event from that finger is passed
111 // through. These events are passed through with an offset such that the first 109 // through. These events are passed through with an offset such that the first
112 // touch is offset to be at the location of the last touch exploration 110 // touch is offset to be at the location of the last touch exploration
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 ui::EventRewriteStatus InSingleTapPressed( 169 ui::EventRewriteStatus InSingleTapPressed(
172 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
173 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( 171 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased(
174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 172 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
175 ui::EventRewriteStatus InDoubleTapPending( 173 ui::EventRewriteStatus InDoubleTapPending(
176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
177 ui::EventRewriteStatus InTouchReleasePending( 175 ui::EventRewriteStatus InTouchReleasePending(
178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
179 ui::EventRewriteStatus InTouchExploration( 177 ui::EventRewriteStatus InTouchExploration(
180 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
181 ui::EventRewriteStatus InTwoToOneFinger(
182 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
183 ui::EventRewriteStatus InOneFingerPassthrough( 179 ui::EventRewriteStatus InOneFingerPassthrough(
184 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 180 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
185 ui::EventRewriteStatus InGestureInProgress( 181 ui::EventRewriteStatus InGestureInProgress(
186 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 182 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
187 ui::EventRewriteStatus InTouchExploreSecondPress( 183 ui::EventRewriteStatus InTouchExploreSecondPress(
188 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 184 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
189 ui::EventRewriteStatus InWaitForOneFinger( 185 ui::EventRewriteStatus InWaitForNoFingers(
190 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 186 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
191 ui::EventRewriteStatus InSlideGesture( 187 ui::EventRewriteStatus InSlideGesture(
192 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 188 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
193 ui::EventRewriteStatus InTwoFingerTap( 189 ui::EventRewriteStatus InTwoFingerTap(
194 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 190 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
195 191
196 // Returns the current time of the tick clock. 192 // Returns the current time of the tick clock.
197 base::TimeDelta Now(); 193 base::TimeDelta Now();
198 194
199 // This timer is started every time we get the first press event, and 195 // This timer is started every time we get the first press event, and
(...skipping 16 matching lines...) Expand all
216 212
217 // Process the gesture events that have been created. 213 // Process the gesture events that have been created.
218 void ProcessGestureEvents(); 214 void ProcessGestureEvents();
219 215
220 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); 216 void OnSwipeEvent(ui::GestureEvent* swipe_gesture);
221 217
222 void SideSlideControl(ui::GestureEvent* gesture); 218 void SideSlideControl(ui::GestureEvent* gesture);
223 219
224 // Dispatches the keyboard short cut Shift+Search+<arrow key> 220 // Dispatches the keyboard short cut Shift+Search+<arrow key>
225 // outside the event rewritting flow. 221 // outside the event rewritting flow.
226 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction); 222 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode third_key);
223
224 // Binds DispatchShiftSearchKeyEvent to a specific third key.
225 base::Closure BindShiftSearchKeyEvent(const ui::KeyboardCode third_key);
226
227 // Dispatches a single key with the given flags.
228 void DispatchKeyWithFlags(const ui::KeyboardCode key, int flags);
229
230 // Binds DispatchKeyWithFlags to a specific key and flags.
231 base::Closure BindKeyEventWithFlags(const ui::KeyboardCode key, int flags);
227 232
228 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, 233 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
229 int flags); 234 int flags);
230 235
231 void EnterTouchToMouseMode(); 236 void EnterTouchToMouseMode();
232 237
233 // Set the state to NO_FINGERS_DOWN and reset any other fields to their
234 // default value.
235 void ResetToNoFingersDown();
236
237 void PlaySoundForTimer(); 238 void PlaySoundForTimer();
238 239
239 // Some constants used in touch_exploration_controller: 240 // Some constants used in touch_exploration_controller:
240 241
241 // Within this many dips of the screen edge, the release event generated will 242 // Within this many dips of the screen edge, the release event generated will
242 // reset the state to NoFingersDown. 243 // reset the state to NoFingersDown.
243 const float kLeavingScreenEdge = 6; 244 const float kLeavingScreenEdge = 6;
244 245
245 // Swipe/scroll gestures within these bounds (in DIPs) will change preset 246 // Swipe/scroll gestures within these bounds (in DIPs) will change preset
246 // settings. 247 // settings.
(...skipping 13 matching lines...) Expand all
260 261
261 // The user pressed and released a single finger - a tap - but we have 262 // The user pressed and released a single finger - a tap - but we have
262 // to wait until the end of the grace period to allow the user to tap the 263 // to wait until the end of the grace period to allow the user to tap the
263 // second time. If the second tap doesn't occurs within the grace period, 264 // second time. If the second tap doesn't occurs within the grace period,
264 // we dispatch a mouse move at the location of the first tap. 265 // we dispatch a mouse move at the location of the first tap.
265 SINGLE_TAP_RELEASED, 266 SINGLE_TAP_RELEASED,
266 267
267 // The user was in touch explore mode and released the finger. 268 // The user was in touch explore mode and released the finger.
268 // If another touch press occurs within the grace period, a single 269 // If another touch press occurs within the grace period, a single
269 // tap click occurs. This state differs from SINGLE_TAP_RELEASED 270 // tap click occurs. This state differs from SINGLE_TAP_RELEASED
270 // In that if a second tap doesn't occur within the grace period, 271 // in that if a second tap doesn't occur within the grace period,
271 // there is no mouse move dispatched. 272 // there is no mouse move dispatched.
272 TOUCH_EXPLORE_RELEASED, 273 TOUCH_EXPLORE_RELEASED,
273 274
274 // The user tapped once, and before the grace period expired, pressed 275 // The user tapped once, and before the grace period expired, pressed
275 // one finger down to begin a double-tap, but has not released it yet. 276 // one finger down to begin a double-tap, but has not released it yet.
276 // This could become passthrough, so no touch press is dispatched yet. 277 // This could become passthrough, so no touch press is dispatched yet.
277 DOUBLE_TAP_PENDING, 278 DOUBLE_TAP_PENDING,
278 279
279 // The user was doing touch exploration, started split tap, but lifted the 280 // The user was doing touch exploration, started split tap, but lifted the
280 // touch exploration finger. Once they remove all fingers, a touch release 281 // touch exploration finger. Once they remove all fingers, a touch release
(...skipping 26 matching lines...) Expand all
307 308
308 // After the user double taps and holds with a single finger, all events 309 // After the user double taps and holds with a single finger, all events
309 // for that finger are passed through, displaced by an offset. Adding 310 // for that finger are passed through, displaced by an offset. Adding
310 // extra fingers has no effect. This state is left when the user removes 311 // extra fingers has no effect. This state is left when the user removes
311 // all fingers. 312 // all fingers.
312 ONE_FINGER_PASSTHROUGH, 313 ONE_FINGER_PASSTHROUGH,
313 314
314 // If the user added another finger in SINGLE_TAP_PRESSED, or if the user 315 // If the user added another finger in SINGLE_TAP_PRESSED, or if the user
315 // has multiple fingers fingers down in any other state between 316 // has multiple fingers fingers down in any other state between
316 // passthrough, touch exploration, and gestures, they must release 317 // passthrough, touch exploration, and gestures, they must release
317 // all fingers except before completing any more actions. This state is 318 // all fingers before completing any more actions. This state is
318 // generally useful for developing new features, because it creates a 319 // generally useful for developing new features, because it creates a
319 // simple way to handle a dead end in user flow. 320 // simple way to handle a dead end in user flow.
320 WAIT_FOR_ONE_FINGER, 321 WAIT_FOR_NO_FINGERS,
321 322
322 // If the user is within the given bounds from an edge of the screen, not 323 // If the user is within the given bounds from an edge of the screen, not
323 // including corners, then the resulting movements will be interpreted as 324 // including corners, then the resulting movements will be interpreted as
324 // slide gestures. 325 // slide gestures.
325 SLIDE_GESTURE, 326 SLIDE_GESTURE,
326 327
327 // If the user taps the screen with two fingers and releases both fingers 328 // If the user taps the screen with two fingers and releases both fingers
328 // before the grace period has passed, spoken feedback will be silenced. 329 // before the grace period has passed, spoken feedback will be silenced.
329 TWO_FINGER_TAP, 330 TWO_FINGER_TAP,
330 }; 331 };
331 332
332 enum ScreenLocation { 333 enum ScreenLocation {
333 // Hot "edges" of the screen are each represented by a respective bit. 334 // Hot "edges" of the screen are each represented by a respective bit.
334 NO_EDGE = 0, 335 NO_EDGE = 0,
335 RIGHT_EDGE = 1 << 0, 336 RIGHT_EDGE = 1 << 0,
336 TOP_EDGE = 1 << 1, 337 TOP_EDGE = 1 << 1,
337 LEFT_EDGE = 1 << 2, 338 LEFT_EDGE = 1 << 2,
338 BOTTOM_EDGE = 1 << 3, 339 BOTTOM_EDGE = 1 << 3,
339 }; 340 };
340 341
341 // Given a point, if it is within the given bounds of an edge, returns the 342 // Given a point, if it is within the given bounds of an edge, returns the
342 // edge. If it is within the given bounds of two edges, returns an int with 343 // edge. If it is within the given bounds of two edges, returns an int with
343 // both bits that represent the respective edges turned on. Otherwise returns 344 // both bits that represent the respective edges turned on. Otherwise returns
344 // SCREEN_CENTER. 345 // SCREEN_CENTER.
345 int FindEdgesWithinBounds(gfx::Point point, float bounds); 346 int FindEdgesWithinBounds(gfx::Point point, float bounds);
346 347
348 // Set the state and modifies any variables related to the state change.
349 // (e.g. resetting the gesture provider).
350 void SetState(State new_state, const char* function_name);
351
347 void VlogState(const char* function_name); 352 void VlogState(const char* function_name);
348 353
349 void VlogEvent(const ui::TouchEvent& event, const char* function_name); 354 void VlogEvent(const ui::TouchEvent& event, const char* function_name);
350 355
351 // Gets enum name from integer value. 356 // Gets enum name from integer value.
352 const char* EnumStateToString(State state); 357 const char* EnumStateToString(State state);
353 358
359 // Maps each single/multi finger swipe to the function that dispatches
360 // the corresponding key events.
361 void InitializeSwipeGestureMaps();
362
354 aura::Window* root_window_; 363 aura::Window* root_window_;
355 364
356 // Handles volume control. Not owned. 365 // Handles volume control. Not owned.
357 ui::TouchExplorationControllerDelegate* delegate_; 366 ui::TouchExplorationControllerDelegate* delegate_;
358 367
359 // A set of touch ids for fingers currently touching the screen. 368 // A set of touch ids for fingers currently touching the screen.
360 std::vector<int> current_touch_ids_; 369 std::vector<int> current_touch_ids_;
361 370
362 // Map of touch ids to their last known location. 371 // Map of touch ids to their last known location.
363 std::map<int, gfx::PointF> touch_locations_; 372 std::map<int, gfx::PointF> touch_locations_;
(...skipping 14 matching lines...) Expand all
378 387
379 // Stores the most recent event from a finger that is currently not 388 // Stores the most recent event from a finger that is currently not
380 // sending events through, but might in the future (e.g. before a finger 389 // sending events through, but might in the future (e.g. before a finger
381 // enters double-tap-hold passthrough, we need to update its location.) 390 // enters double-tap-hold passthrough, we need to update its location.)
382 scoped_ptr<ui::TouchEvent> last_unused_finger_event_; 391 scoped_ptr<ui::TouchEvent> last_unused_finger_event_;
383 392
384 // The last synthesized mouse move event. When the user double-taps, 393 // The last synthesized mouse move event. When the user double-taps,
385 // we send the passed-through tap to the location of this event. 394 // we send the passed-through tap to the location of this event.
386 scoped_ptr<ui::TouchEvent> last_touch_exploration_; 395 scoped_ptr<ui::TouchEvent> last_touch_exploration_;
387 396
388 // A timer to fire the mouse move event after the double-tap delay. 397 // A timer that fires after the double-tap delay.
389 base::OneShotTimer<TouchExplorationController> tap_timer_; 398 base::OneShotTimer<TouchExplorationController> tap_timer_;
390 399
391 // A timer to fire an indicating sound when sliding to change volume. 400 // A timer to fire an indicating sound when sliding to change volume.
392 base::RepeatingTimer<TouchExplorationController> sound_timer_; 401 base::RepeatingTimer<TouchExplorationController> sound_timer_;
393 402
394 // A default gesture detector config, so we can share the same 403 // A default gesture detector config, so we can share the same
395 // timeout and pixel slop constants. 404 // timeout and pixel slop constants.
396 ui::GestureDetector::Config gesture_detector_config_; 405 ui::GestureDetector::Config gesture_detector_config_;
397 406
398 // Gesture Handler to interpret the touch events. 407 // Gesture Handler to interpret the touch events.
399 ui::GestureProviderAura gesture_provider_; 408 scoped_ptr<ui::GestureProviderAura> gesture_provider_;
400 409
401 // The previous state entered. 410 // The previous state entered.
402 State prev_state_; 411 State prev_state_;
403 412
404 // A copy of the previous event passed. 413 // A copy of the previous event passed.
405 scoped_ptr<ui::TouchEvent> prev_event_; 414 scoped_ptr<ui::TouchEvent> prev_event_;
406 415
407 // This toggles whether VLOGS are turned on or not. 416 // This toggles whether VLOGS are turned on or not.
408 bool VLOG_on_; 417 bool VLOG_on_;
409 418
410 // When touch_exploration_controller gets time relative to real time during 419 // When touch_exploration_controller gets time relative to real time during
411 // testing, this clock is set to the simulated clock and used. 420 // testing, this clock is set to the simulated clock and used.
412 base::TickClock* tick_clock_; 421 base::TickClock* tick_clock_;
413 422
423 // Maps the number of fingers in a swipe to the resulting functions that
424 // dispatch key events.
425 std::map<int, base::Closure> left_swipe_gestures_;
426 std::map<int, base::Closure> right_swipe_gestures_;
427 std::map<int, base::Closure> up_swipe_gestures_;
428 std::map<int, base::Closure> down_swipe_gestures_;
429
414 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); 430 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
415 }; 431 };
416 432
417 } // namespace ui 433 } // namespace ui
418 434
419 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 435 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
OLDNEW
« no previous file with comments | « no previous file | ui/chromeos/touch_exploration_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698