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

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

Issue 429633002: Added multi-finger gestures to touch_exploration_controller (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@passthrough
Patch Set: nit changes 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
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 "base/time/default_tick_clock.h"
9 #include "ui/aura/client/cursor_client.h" 10 #include "ui/aura/client/cursor_client.h"
10 #include "ui/aura/window.h" 11 #include "ui/aura/window.h"
11 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 14 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 15 #include "ui/events/event_processor.h"
15 #include "ui/events/event_utils.h" 16 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/rect.h" 17 #include "ui/gfx/geometry/rect.h"
17 18
18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 19 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
(...skipping 10 matching lines...) Expand all
29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 30 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
30 } // namespace 31 } // namespace
31 32
32 TouchExplorationController::TouchExplorationController( 33 TouchExplorationController::TouchExplorationController(
33 aura::Window* root_window, 34 aura::Window* root_window,
34 TouchExplorationControllerDelegate* delegate) 35 TouchExplorationControllerDelegate* delegate)
35 : root_window_(root_window), 36 : root_window_(root_window),
36 delegate_(delegate), 37 delegate_(delegate),
37 state_(NO_FINGERS_DOWN), 38 state_(NO_FINGERS_DOWN),
38 event_handler_for_testing_(NULL), 39 event_handler_for_testing_(NULL),
39 gesture_provider_(this),
40 prev_state_(NO_FINGERS_DOWN), 40 prev_state_(NO_FINGERS_DOWN),
41 VLOG_on_(true), 41 VLOG_on_(true),
42 tick_clock_(NULL) { 42 tick_clock_(NULL) {
43 CHECK(root_window); 43 CHECK(root_window);
44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
45 InitializeSwipeGestureMaps();
46 gesture_provider_.reset(new GestureProviderAura(this));
mfomitchev 2014/08/07 18:34:58 nit: I think you can just add gesture_provider_(ne
evy 2014/08/07 20:40:26 Done.
45 } 47 }
46 48
47 TouchExplorationController::~TouchExplorationController() { 49 TouchExplorationController::~TouchExplorationController() {
48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
49 } 51 }
50 52
51 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 53 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
52 const ui::Event& event, 54 const ui::Event& event,
53 scoped_ptr<ui::Event>* rewritten_event) { 55 scoped_ptr<ui::Event>* rewritten_event) {
54 if (!event.IsTouchEvent()) { 56 if (!event.IsTouchEvent()) {
57 if (event.IsKeyEvent()) {
58 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
59 VLOG(0) << "\nKeyboard event: " << key_event.name()
60 << "\n Key code: " << key_event.key_code()
61 << ", Flags: " << key_event.flags()
62 << ", Is char: " << key_event.is_char();
63 }
55 return ui::EVENT_REWRITE_CONTINUE; 64 return ui::EVENT_REWRITE_CONTINUE;
56 } 65 }
57 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); 66 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
58 67
59 // If the tap timer should have fired by now but hasn't, run it now and 68 // If the tap timer should have fired by now but hasn't, run it now and
60 // stop the timer. This is important so that behavior is consistent with 69 // stop the timer. This is important so that behavior is consistent with
61 // the timestamps of the events, and not dependent on the granularity of 70 // the timestamps of the events, and not dependent on the granularity of
62 // the timer. 71 // the timer.
63 if (tap_timer_.IsRunning() && 72 if (tap_timer_.IsRunning() &&
64 touch_event.time_stamp() - initial_press_->time_stamp() > 73 touch_event.time_stamp() - initial_press_->time_stamp() >
65 gesture_detector_config_.double_tap_timeout) { 74 gesture_detector_config_.double_tap_timeout) {
66 tap_timer_.Stop(); 75 tap_timer_.Stop();
67 OnTapTimerFired(); 76 OnTapTimerFired();
68 // Note: this may change the state. We should now continue and process 77 // Note: this may change the state. We should now continue and process
69 // this event under this new state. 78 // this event under this new state.
70 } 79 }
71 80
72 const ui::EventType type = touch_event.type(); 81 const ui::EventType type = touch_event.type();
73 const gfx::PointF& location = touch_event.location_f(); 82 const gfx::PointF& location = touch_event.location_f();
74 const int touch_id = touch_event.touch_id(); 83 const int touch_id = touch_event.touch_id();
75 84
76 // Always update touch ids and touch locations, so we can use those 85 // Always update touch ids and touch locations, so we can use those
77 // no matter what state we're in. 86 // no matter what state we're in.
78 if (type == ui::ET_TOUCH_PRESSED) { 87 if (type == ui::ET_TOUCH_PRESSED) {
79 current_touch_ids_.push_back(touch_id); 88 current_touch_ids_.push_back(touch_id);
80 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 89 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
81 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 90 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
82 // In order to avoid accidentally double tapping when moving off the edge of 91 // In order to avoid accidentally double tapping when moving off the edge
83 // the screen, the state will be rewritten to NoFingersDown. 92 // of the screen, the state will be rewritten to NoFingersDown.
84 TouchEvent touch_event = static_cast<const TouchEvent&>(event); 93 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
85 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 94 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) !=
86 NO_EDGE) { 95 NO_EDGE) {
87 if (current_touch_ids_.size() == 0) { 96 if (current_touch_ids_.size() == 0) {
mfomitchev 2014/08/07 18:34:58 Should this be == 1 instead? You shouldn't get a r
evy 2014/08/07 20:40:26 This block of code was actually here before we sta
mfomitchev 2014/08/08 20:23:13 Sounds like lisayin@ wrote this, maybe ask her? Th
evy 2014/08/08 22:39:14 Done.
88 ResetToNoFingersDown(); 97 ResetToNoFingersDown();
89 } 98 }
90 } 99 }
91 100
92 std::vector<int>::iterator it = std::find( 101 std::vector<int>::iterator it = std::find(
93 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 102 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
94 103
95 // Can happen if touch exploration is enabled while fingers were down. 104 // Can happen if touch exploration is enabled while fingers were down.
96 if (it == current_touch_ids_.end()) 105 if (it == current_touch_ids_.end())
97 return ui::EVENT_REWRITE_CONTINUE; 106 return ui::EVENT_REWRITE_CONTINUE;
98 107
99 current_touch_ids_.erase(it); 108 current_touch_ids_.erase(it);
100 touch_locations_.erase(touch_id); 109 touch_locations_.erase(touch_id);
101 } else if (type == ui::ET_TOUCH_MOVED) { 110 } else if (type == ui::ET_TOUCH_MOVED) {
102 std::vector<int>::iterator it = std::find( 111 std::vector<int>::iterator it = std::find(
103 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 112 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
104 113
105 // Can happen if touch exploration is enabled while fingers were down. 114 // Can happen if touch exploration is enabled while fingers were down.
106 if (it == current_touch_ids_.end()) 115 if (it == current_touch_ids_.end())
107 return ui::EVENT_REWRITE_CONTINUE; 116 return ui::EVENT_REWRITE_CONTINUE;
108 117
109 touch_locations_[*it] = location; 118 touch_locations_[*it] = location;
119 } else {
120 NOTREACHED() << "Unexpected event type received: " << event.name();
121 return ui::EVENT_REWRITE_CONTINUE;
110 } 122 }
111 VLOG_STATE(); 123 VLOG_STATE();
112 VLOG_EVENT(touch_event); 124 VLOG_EVENT(touch_event);
125
126 // If the user is in a gesture state, or if there is a possiblity that the
127 // user will enter it in the future, we send the event to the gesture
128 // provider so it can keep track of the state of the fingers.
129 // TODO(lisayin, evy): Add the two finger hold state when that's completed.
130 if (state_ == NO_FINGERS_DOWN ||
mfomitchev 2014/08/07 18:34:58 Hmm.. perhaps it would be better to do gesture_pro
evy 2014/08/07 20:40:26 Done. Great idea - feels much cleaner this way.
131 state_ == SINGLE_TAP_PRESSED ||
132 state_ == GESTURE_IN_PROGRESS ||
133 state_ == SLIDE_GESTURE) {
134 gesture_provider_->OnTouchEvent(touch_event);
135 gesture_provider_->OnTouchEventAck(false);
136 ProcessGestureEvents();
137 }
138
113 // The rest of the processing depends on what state we're in. 139 // The rest of the processing depends on what state we're in.
114 switch(state_) { 140 switch (state_) {
115 case NO_FINGERS_DOWN: 141 case NO_FINGERS_DOWN:
116 return InNoFingersDown(touch_event, rewritten_event); 142 return InNoFingersDown(touch_event, rewritten_event);
117 case SINGLE_TAP_PRESSED: 143 case SINGLE_TAP_PRESSED:
118 return InSingleTapPressed(touch_event, rewritten_event); 144 return InSingleTapPressed(touch_event, rewritten_event);
119 case SINGLE_TAP_RELEASED: 145 case SINGLE_TAP_RELEASED:
120 case TOUCH_EXPLORE_RELEASED: 146 case TOUCH_EXPLORE_RELEASED:
121 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); 147 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event);
122 case DOUBLE_TAP_PENDING: 148 case DOUBLE_TAP_PENDING:
123 return InDoubleTapPending(touch_event, rewritten_event); 149 return InDoubleTapPending(touch_event, rewritten_event);
124 case TOUCH_RELEASE_PENDING: 150 case TOUCH_RELEASE_PENDING:
125 return InTouchReleasePending(touch_event, rewritten_event); 151 return InTouchReleasePending(touch_event, rewritten_event);
126 case TOUCH_EXPLORATION: 152 case TOUCH_EXPLORATION:
127 return InTouchExploration(touch_event, rewritten_event); 153 return InTouchExploration(touch_event, rewritten_event);
128 case GESTURE_IN_PROGRESS: 154 case GESTURE_IN_PROGRESS:
129 return InGestureInProgress(touch_event, rewritten_event); 155 return InGestureInProgress(touch_event, rewritten_event);
130 case TOUCH_EXPLORE_SECOND_PRESS: 156 case TOUCH_EXPLORE_SECOND_PRESS:
131 return InTouchExploreSecondPress(touch_event, rewritten_event); 157 return InTouchExploreSecondPress(touch_event, rewritten_event);
158 case ONE_FINGER_PASSTHROUGH:
159 return InOneFingerPassthrough(touch_event, rewritten_event);
160 case WAIT_FOR_NO_FINGERS:
161 return InWaitForNoFingers(touch_event, rewritten_event);
132 case SLIDE_GESTURE: 162 case SLIDE_GESTURE:
133 return InSlideGesture(touch_event, rewritten_event); 163 return InSlideGesture(touch_event, rewritten_event);
134 case ONE_FINGER_PASSTHROUGH:
135 return InOneFingerPassthrough(touch_event, rewritten_event);
136 case WAIT_FOR_ONE_FINGER:
137 return InWaitForOneFinger(touch_event, rewritten_event);
138 } 164 }
139 NOTREACHED(); 165 NOTREACHED();
140 return ui::EVENT_REWRITE_CONTINUE; 166 return ui::EVENT_REWRITE_CONTINUE;
141 } 167 }
142 168
143 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 169 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
144 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 170 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
145 NOTREACHED(); 171 NOTREACHED();
146 return ui::EVENT_REWRITE_CONTINUE; 172 return ui::EVENT_REWRITE_CONTINUE;
147 } 173 }
148 174
149 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 175 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
150 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
151 const ui::EventType type = event.type(); 177 const ui::EventType type = event.type();
152 if (type == ui::ET_TOUCH_PRESSED) { 178 if (type == ui::ET_TOUCH_PRESSED) {
153 initial_press_.reset(new TouchEvent(event)); 179 initial_press_.reset(new TouchEvent(event));
154 last_unused_finger_event_.reset(new TouchEvent(event)); 180 last_unused_finger_event_.reset(new TouchEvent(event));
155 StartTapTimer(); 181 StartTapTimer();
156 gesture_provider_.OnTouchEvent(event);
157 gesture_provider_.OnTouchEventAck(false);
158 ProcessGestureEvents();
159 state_ = SINGLE_TAP_PRESSED; 182 state_ = SINGLE_TAP_PRESSED;
160 VLOG_STATE(); 183 VLOG_STATE();
161 return ui::EVENT_REWRITE_DISCARD; 184 return ui::EVENT_REWRITE_DISCARD;
162 } 185 }
163 NOTREACHED() << "Unexpected event type received: " << event.name(); 186 NOTREACHED() << "Unexpected event type received: " << event.name();
164 return ui::EVENT_REWRITE_CONTINUE; 187 return ui::EVENT_REWRITE_CONTINUE;
165 } 188 }
166 189
167 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 190 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
168 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 191 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
169 const ui::EventType type = event.type(); 192 const ui::EventType type = event.type();
170 193
171 if (type == ui::ET_TOUCH_PRESSED) { 194 if (type == ui::ET_TOUCH_PRESSED) {
172 // TODO (evy, lisayin) : add support for multifinger swipes. 195 // This is the start of a multifinger gesture.
173 // For now, we wait for there to be only one finger down again. 196 state_ = GESTURE_IN_PROGRESS;
174 state_ = WAIT_FOR_ONE_FINGER; 197 VLOG_STATE();
175 return EVENT_REWRITE_DISCARD; 198 return InGestureInProgress(event, rewritten_event);
176 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 199 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
177 if (current_touch_ids_.size() == 0 && 200 if (current_touch_ids_.size() == 0 &&
178 event.touch_id() == initial_press_->touch_id()) { 201 event.touch_id() == initial_press_->touch_id()) {
179 state_ = SINGLE_TAP_RELEASED; 202 state_ = SINGLE_TAP_RELEASED;
180 VLOG_STATE(); 203 VLOG_STATE();
181 } else if (current_touch_ids_.size() == 0) { 204 } else if (current_touch_ids_.size() == 0) {
182 ResetToNoFingersDown(); 205 ResetToNoFingersDown();
183 } 206 }
184 return EVENT_REWRITE_DISCARD; 207 return EVENT_REWRITE_DISCARD;
185 } else if (type == ui::ET_TOUCH_MOVED) { 208 } else if (type == ui::ET_TOUCH_MOVED) {
(...skipping 26 matching lines...) Expand all
212 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 235 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
213 state_ = GESTURE_IN_PROGRESS; 236 state_ = GESTURE_IN_PROGRESS;
214 VLOG_STATE(); 237 VLOG_STATE();
215 return InGestureInProgress(event, rewritten_event); 238 return InGestureInProgress(event, rewritten_event);
216 } 239 }
217 EnterTouchToMouseMode(); 240 EnterTouchToMouseMode();
218 state_ = TOUCH_EXPLORATION; 241 state_ = TOUCH_EXPLORATION;
219 VLOG_STATE(); 242 VLOG_STATE();
220 return InTouchExploration(event, rewritten_event); 243 return InTouchExploration(event, rewritten_event);
221 } 244 }
222 NOTREACHED() << "Unexpected event type received: " << event.name(); 245 NOTREACHED();
223 return ui::EVENT_REWRITE_CONTINUE; 246 return ui::EVENT_REWRITE_CONTINUE;
224 } 247 }
225 248
226 ui::EventRewriteStatus 249 ui::EventRewriteStatus
227 TouchExplorationController::InSingleTapOrTouchExploreReleased( 250 TouchExplorationController::InSingleTapOrTouchExploreReleased(
228 const ui::TouchEvent& event, 251 const ui::TouchEvent& event,
229 scoped_ptr<ui::Event>* rewritten_event) { 252 scoped_ptr<ui::Event>* rewritten_event) {
230 const ui::EventType type = event.type(); 253 const ui::EventType type = event.type();
231 // If there is more than one finger down, then discard to wait until only one 254 // If there is more than one finger down, then discard to wait until no
232 // finger is or no fingers are down. 255 // fingers are down.
233 if (current_touch_ids_.size() > 1) { 256 if (current_touch_ids_.size() > 1) {
234 state_ = WAIT_FOR_ONE_FINGER; 257 state_ = WAIT_FOR_NO_FINGERS;
258 VLOG_STATE();
235 return ui::EVENT_REWRITE_DISCARD; 259 return ui::EVENT_REWRITE_DISCARD;
236 } 260 }
237 if (type == ui::ET_TOUCH_PRESSED) { 261 if (type == ui::ET_TOUCH_PRESSED) {
238 // If there is no touch exploration yet, we can't send a click, so discard. 262 // If there is no touch exploration yet, we can't send a click, so discard.
239 if (!last_touch_exploration_) { 263 if (!last_touch_exploration_) {
240 tap_timer_.Stop(); 264 tap_timer_.Stop();
241 return ui::EVENT_REWRITE_DISCARD; 265 return ui::EVENT_REWRITE_DISCARD;
242 } 266 }
243 // This is the second tap in a double-tap (or double tap-hold). 267 // This is the second tap in a double-tap (or double tap-hold).
244 // We set the tap timer. If it fires before the user lifts their finger, 268 // We set the tap timer. If it fires before the user lifts their finger,
245 // one-finger passthrough begins. Otherwise, there is a touch press and 269 // one-finger passthrough begins. Otherwise, there is a touch press and
246 // release at the location of the last touch exploration. 270 // release at the location of the last touch exploration.
247 state_ = DOUBLE_TAP_PENDING; 271 state_ = DOUBLE_TAP_PENDING;
248 VLOG_STATE(); 272 VLOG_STATE();
273 // The old tap timer (from the initial click) is stopped if it is still
274 // going, and the new one is set.
275 tap_timer_.Stop();
249 StartTapTimer(); 276 StartTapTimer();
250 // This will update as the finger moves before a possible passthrough, and 277 // This will update as the finger moves before a possible passthrough, and
251 // will determine the offset. 278 // will determine the offset.
252 last_unused_finger_event_.reset(new ui::TouchEvent(event)); 279 last_unused_finger_event_.reset(new ui::TouchEvent(event));
253 return ui::EVENT_REWRITE_DISCARD; 280 return ui::EVENT_REWRITE_DISCARD;
254 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { 281 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
255 // If the previous press was discarded, we need to also handle its 282 // If the previous press was discarded, we need to also handle its
256 // release. 283 // release.
257 if (current_touch_ids_.size() == 0) { 284 if (current_touch_ids_.size() == 0) {
258 ResetToNoFingersDown(); 285 ResetToNoFingersDown();
259 } 286 }
260 return ui::EVENT_REWRITE_DISCARD; 287 return ui::EVENT_REWRITE_DISCARD;
261 } else if (type == ui::ET_TOUCH_MOVED) { 288 } else if (type == ui::ET_TOUCH_MOVED) {
262 return ui::EVENT_REWRITE_DISCARD; 289 return ui::EVENT_REWRITE_DISCARD;
263 } 290 }
264 NOTREACHED() << "Unexpected event type received: " << event.name(); 291 NOTREACHED();
265 return ui::EVENT_REWRITE_CONTINUE; 292 return ui::EVENT_REWRITE_CONTINUE;
266 } 293 }
267 294
268 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( 295 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending(
269 const ui::TouchEvent& event, 296 const ui::TouchEvent& event,
270 scoped_ptr<ui::Event>* rewritten_event) { 297 scoped_ptr<ui::Event>* rewritten_event) {
271 const ui::EventType type = event.type(); 298 const ui::EventType type = event.type();
272 if (type == ui::ET_TOUCH_PRESSED) { 299 if (type == ui::ET_TOUCH_PRESSED) {
273 return ui::EVENT_REWRITE_DISCARD; 300 return ui::EVENT_REWRITE_DISCARD;
274 } else if (type == ui::ET_TOUCH_MOVED) { 301 } else if (type == ui::ET_TOUCH_MOVED) {
(...skipping 18 matching lines...) Expand all
293 320
294 rewritten_event->reset( 321 rewritten_event->reset(
295 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 322 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
296 last_touch_exploration_->location(), 323 last_touch_exploration_->location(),
297 initial_press_->touch_id(), 324 initial_press_->touch_id(),
298 event.time_stamp())); 325 event.time_stamp()));
299 (*rewritten_event)->set_flags(event.flags()); 326 (*rewritten_event)->set_flags(event.flags());
300 ResetToNoFingersDown(); 327 ResetToNoFingersDown();
301 return ui::EVENT_REWRITE_REWRITTEN; 328 return ui::EVENT_REWRITE_REWRITTEN;
302 } 329 }
303 NOTREACHED() << "Unexpected event type received: " << event.name(); 330 NOTREACHED();
304 return ui::EVENT_REWRITE_CONTINUE; 331 return ui::EVENT_REWRITE_CONTINUE;
305 } 332 }
306 333
307 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( 334 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending(
308 const ui::TouchEvent& event, 335 const ui::TouchEvent& event,
309 scoped_ptr<ui::Event>* rewritten_event) { 336 scoped_ptr<ui::Event>* rewritten_event) {
310 const ui::EventType type = event.type(); 337 const ui::EventType type = event.type();
311 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { 338 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) {
312 return ui::EVENT_REWRITE_DISCARD; 339 return ui::EVENT_REWRITE_DISCARD;
313 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 340 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
314 if (current_touch_ids_.size() != 0) 341 if (current_touch_ids_.size() != 0)
315 return EVENT_REWRITE_DISCARD; 342 return EVENT_REWRITE_DISCARD;
316 343
317 rewritten_event->reset( 344 rewritten_event->reset(
318 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 345 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
319 last_touch_exploration_->location(), 346 last_touch_exploration_->location(),
320 initial_press_->touch_id(), 347 initial_press_->touch_id(),
321 event.time_stamp())); 348 event.time_stamp()));
322 (*rewritten_event)->set_flags(event.flags()); 349 (*rewritten_event)->set_flags(event.flags());
323 ResetToNoFingersDown(); 350 ResetToNoFingersDown();
324 return ui::EVENT_REWRITE_REWRITTEN; 351 return ui::EVENT_REWRITE_REWRITTEN;
325 } 352 }
326 NOTREACHED() << "Unexpected event type received: " << event.name(); 353 NOTREACHED();
327 return ui::EVENT_REWRITE_CONTINUE; 354 return ui::EVENT_REWRITE_CONTINUE;
328 } 355 }
329 356
330 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 357 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
331 const ui::TouchEvent& event, 358 const ui::TouchEvent& event,
332 scoped_ptr<ui::Event>* rewritten_event) { 359 scoped_ptr<ui::Event>* rewritten_event) {
333 const ui::EventType type = event.type(); 360 const ui::EventType type = event.type();
334 if (type == ui::ET_TOUCH_PRESSED) { 361 if (type == ui::ET_TOUCH_PRESSED) {
335 // Handle split-tap. 362 // Handle split-tap.
336 initial_press_.reset(new TouchEvent(event)); 363 initial_press_.reset(new TouchEvent(event));
337 if (tap_timer_.IsRunning()) 364 tap_timer_.Stop();
338 tap_timer_.Stop();
339 rewritten_event->reset( 365 rewritten_event->reset(
340 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 366 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
341 last_touch_exploration_->location(), 367 last_touch_exploration_->location(),
342 event.touch_id(), 368 event.touch_id(),
343 event.time_stamp())); 369 event.time_stamp()));
344 (*rewritten_event)->set_flags(event.flags()); 370 (*rewritten_event)->set_flags(event.flags());
345 state_ = TOUCH_EXPLORE_SECOND_PRESS; 371 state_ = TOUCH_EXPLORE_SECOND_PRESS;
346 VLOG_STATE(); 372 VLOG_STATE();
347 return ui::EVENT_REWRITE_REWRITTEN; 373 return ui::EVENT_REWRITE_REWRITTEN;
348 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 374 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
349 initial_press_.reset(new TouchEvent(event)); 375 initial_press_.reset(new TouchEvent(event));
350 StartTapTimer(); 376 StartTapTimer();
351 state_ = TOUCH_EXPLORE_RELEASED; 377 state_ = TOUCH_EXPLORE_RELEASED;
352 VLOG_STATE(); 378 VLOG_STATE();
353 } else if (type != ui::ET_TOUCH_MOVED) { 379 } else if (type != ui::ET_TOUCH_MOVED) {
354 NOTREACHED() << "Unexpected event type received: " << event.name(); 380 NOTREACHED();
355 return ui::EVENT_REWRITE_CONTINUE; 381 return ui::EVENT_REWRITE_CONTINUE;
356 } 382 }
357 383
358 // Rewrite as a mouse-move event. 384 // Rewrite as a mouse-move event.
359 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 385 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
360 last_touch_exploration_.reset(new TouchEvent(event)); 386 last_touch_exploration_.reset(new TouchEvent(event));
361 return ui::EVENT_REWRITE_REWRITTEN; 387 return ui::EVENT_REWRITE_REWRITTEN;
362 } 388 }
363 389
364 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( 390 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
365 const ui::TouchEvent& event, 391 const ui::TouchEvent& event,
366 scoped_ptr<ui::Event>* rewritten_event) { 392 scoped_ptr<ui::Event>* rewritten_event) {
367 ui::EventType type = event.type(); 393 // The events were sent to the gesture provider in RewriteEvent already.
368 // If additional fingers are added before a swipe gesture has been 394 // If no gesture is registered before the tap timer times out, the state
369 // registered, then the state will no longer be GESTURE_IN_PROGRESS. 395 // will change to wait for no fingers down and this function will stop
mfomitchev 2014/08/07 18:34:59 "the state will change to wait for no fingers down
evy 2014/08/07 20:40:26 yup - thanks for catching that
370 if (type == ui::ET_TOUCH_PRESSED || 396 // being called.
371 event.touch_id() != initial_press_->touch_id()) { 397 if (current_touch_ids_.size() == 0) {
372 if (tap_timer_.IsRunning()) 398 ResetToNoFingersDown();
373 tap_timer_.Stop();
374 // Discard any pending gestures.
375 delete gesture_provider_.GetAndResetPendingGestures();
376 state_ = WAIT_FOR_ONE_FINGER;
377 return EVENT_REWRITE_DISCARD;
378 } 399 }
379
380 // There should not be more than one finger down.
381 DCHECK(current_touch_ids_.size() <= 1);
382 if (type == ui::ET_TOUCH_MOVED) {
383 gesture_provider_.OnTouchEvent(event);
384 gesture_provider_.OnTouchEventAck(false);
385 }
386 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
387 gesture_provider_.OnTouchEvent(event);
388 gesture_provider_.OnTouchEventAck(false);
389 if (current_touch_ids_.size() == 0) {
390 ResetToNoFingersDown();
391 }
392 }
393 ProcessGestureEvents();
394 return ui::EVENT_REWRITE_DISCARD; 400 return ui::EVENT_REWRITE_DISCARD;
395 } 401 }
396 402
397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( 403 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough(
398 const ui::TouchEvent& event, 404 const ui::TouchEvent& event,
399 scoped_ptr<ui::Event>* rewritten_event) { 405 scoped_ptr<ui::Event>* rewritten_event) {
400 ui::EventType type = event.type();
401
402 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED ||
403 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
404 NOTREACHED() << "Unexpected event type received: " << event.name();
405 return ui::EVENT_REWRITE_CONTINUE;
406 }
407 if (event.touch_id() != initial_press_->touch_id()) { 406 if (event.touch_id() != initial_press_->touch_id()) {
408 if (current_touch_ids_.size() == 0) { 407 if (current_touch_ids_.size() == 0) {
409 ResetToNoFingersDown(); 408 ResetToNoFingersDown();
410 } 409 }
411 return ui::EVENT_REWRITE_DISCARD; 410 return ui::EVENT_REWRITE_DISCARD;
412 } 411 }
413 rewritten_event->reset( 412 rewritten_event->reset(
414 new ui::TouchEvent(event.type(), 413 new ui::TouchEvent(event.type(),
415 event.location() - passthrough_offset_, 414 event.location() - passthrough_offset_,
416 event.touch_id(), 415 event.touch_id(),
417 event.time_stamp())); 416 event.time_stamp()));
418 417
419 (*rewritten_event)->set_flags(event.flags()); 418 (*rewritten_event)->set_flags(event.flags());
420 if (current_touch_ids_.size() == 0) { 419 if (current_touch_ids_.size() == 0) {
421 ResetToNoFingersDown(); 420 ResetToNoFingersDown();
422 } 421 }
423
424 return ui::EVENT_REWRITE_REWRITTEN; 422 return ui::EVENT_REWRITE_REWRITTEN;
425 } 423 }
426 424
427 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress( 425 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
428 const ui::TouchEvent& event, 426 const ui::TouchEvent& event,
429 scoped_ptr<ui::Event>* rewritten_event) { 427 scoped_ptr<ui::Event>* rewritten_event) {
430 ui::EventType type = event.type(); 428 ui::EventType type = event.type();
431 gfx::PointF location = event.location_f(); 429 gfx::PointF location = event.location_f();
432 if (type == ui::ET_TOUCH_PRESSED) { 430 if (type == ui::ET_TOUCH_PRESSED) {
433 return ui::EVENT_REWRITE_DISCARD; 431 return ui::EVENT_REWRITE_DISCARD;
(...skipping 21 matching lines...) Expand all
455 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 453 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
456 last_touch_exploration_->location(), 454 last_touch_exploration_->location(),
457 initial_press_->touch_id(), 455 initial_press_->touch_id(),
458 event.time_stamp())); 456 event.time_stamp()));
459 (*rewritten_event)->set_flags(event.flags()); 457 (*rewritten_event)->set_flags(event.flags());
460 state_ = TOUCH_EXPLORATION; 458 state_ = TOUCH_EXPLORATION;
461 EnterTouchToMouseMode(); 459 EnterTouchToMouseMode();
462 VLOG_STATE(); 460 VLOG_STATE();
463 return ui::EVENT_REWRITE_REWRITTEN; 461 return ui::EVENT_REWRITE_REWRITTEN;
464 } 462 }
465 NOTREACHED() << "Unexpected event type received: " << event.name(); 463 NOTREACHED();
466 return ui::EVENT_REWRITE_CONTINUE; 464 return ui::EVENT_REWRITE_CONTINUE;
467 } 465 }
468 466
469 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( 467 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
470 const ui::TouchEvent& event, 468 const ui::TouchEvent& event,
471 scoped_ptr<ui::Event>* rewritten_event) { 469 scoped_ptr<ui::Event>* rewritten_event) {
472 ui::EventType type = event.type(); 470 if (current_touch_ids_.size() == 0)
473 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 471 ResetToNoFingersDown();
474 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
475 NOTREACHED() << "Unexpected event type received: " << event.name();
476 return ui::EVENT_REWRITE_CONTINUE;
477 }
478 if (current_touch_ids_.size() == 1) {
479 EnterTouchToMouseMode();
480 state_ = TOUCH_EXPLORATION;
481 VLOG_STATE();
482 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
483 last_touch_exploration_.reset(new TouchEvent(event));
484 return ui::EVENT_REWRITE_REWRITTEN;
485 }
486 return EVENT_REWRITE_DISCARD; 472 return EVENT_REWRITE_DISCARD;
487 } 473 }
488 474
489 void TouchExplorationController::PlaySoundForTimer() { 475 void TouchExplorationController::PlaySoundForTimer() {
490 delegate_->PlayVolumeAdjustSound(); 476 delegate_->PlayVolumeAdjustSound();
491 } 477 }
492 478
493 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 479 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
494 const ui::TouchEvent& event, 480 const ui::TouchEvent& event,
495 scoped_ptr<ui::Event>* rewritten_event) { 481 scoped_ptr<ui::Event>* rewritten_event) {
496 // The timer should not fire when sliding. 482 // The timer should not fire when sliding.
497 if (tap_timer_.IsRunning()) 483 tap_timer_.Stop();
498 tap_timer_.Stop();
499 484
500 ui::EventType type = event.type(); 485 ui::EventType type = event.type();
501 // If additional fingers are added before a swipe gesture has been registered, 486 // If additional fingers are added before a swipe gesture has been registered,
502 // then wait until all fingers have been lifted. 487 // then wait until all fingers have been lifted.
503 if (type == ui::ET_TOUCH_PRESSED || 488 if (type == ui::ET_TOUCH_PRESSED ||
504 event.touch_id() != initial_press_->touch_id()) { 489 event.touch_id() != initial_press_->touch_id()) {
505 if (sound_timer_.IsRunning()) 490 if (sound_timer_.IsRunning())
506 sound_timer_.Stop(); 491 sound_timer_.Stop();
507 // Discard any pending gestures. 492 state_ = WAIT_FOR_NO_FINGERS;
508 delete gesture_provider_.GetAndResetPendingGestures(); 493 VLOG_STATE();
509 state_ = WAIT_FOR_ONE_FINGER;
510 return EVENT_REWRITE_DISCARD; 494 return EVENT_REWRITE_DISCARD;
511 } 495 }
512 496
497 // There should not be more than one finger down.
498 DCHECK(current_touch_ids_.size() <= 1);
499
500
513 // Allows user to return to the edge to adjust the sound if they have left the 501 // Allows user to return to the edge to adjust the sound if they have left the
514 // boundaries. 502 // boundaries.
515 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); 503 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
516 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { 504 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) {
517 if (sound_timer_.IsRunning()) { 505 if (sound_timer_.IsRunning()) {
518 sound_timer_.Stop(); 506 sound_timer_.Stop();
519 } 507 }
520 return EVENT_REWRITE_DISCARD; 508 return EVENT_REWRITE_DISCARD;
521 } 509 }
522 510
523 // This can occur if the user leaves the screen edge and then returns to it to 511 // This can occur if the user leaves the screen edge and then returns to it to
524 // continue adjusting the sound. 512 // continue adjusting the sound.
525 if (!sound_timer_.IsRunning()) { 513 if (!sound_timer_.IsRunning()) {
526 sound_timer_.Start(FROM_HERE, 514 sound_timer_.Start(FROM_HERE,
527 kSoundDelay, 515 kSoundDelay,
528 this, 516 this,
529 &ui::TouchExplorationController::PlaySoundForTimer); 517 &ui::TouchExplorationController::PlaySoundForTimer);
530 delegate_->PlayVolumeAdjustSound(); 518 delegate_->PlayVolumeAdjustSound();
531 } 519 }
532 520
533 // There should not be more than one finger down. 521 if (current_touch_ids_.size() == 0) {
534 DCHECK(current_touch_ids_.size() <= 1); 522 ResetToNoFingersDown();
535 if (type == ui::ET_TOUCH_MOVED) {
536 gesture_provider_.OnTouchEvent(event);
537 gesture_provider_.OnTouchEventAck(false);
538 }
539 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
540 gesture_provider_.OnTouchEvent(event);
541 gesture_provider_.OnTouchEventAck(false);
542 delete gesture_provider_.GetAndResetPendingGestures();
543 if (current_touch_ids_.size() == 0) {
544 ResetToNoFingersDown();
545 }
546 return ui::EVENT_REWRITE_DISCARD;
547 } 523 }
548 524
549 ProcessGestureEvents();
550 return ui::EVENT_REWRITE_DISCARD; 525 return ui::EVENT_REWRITE_DISCARD;
551 } 526 }
552 527
553 base::TimeDelta TouchExplorationController::Now() { 528 base::TimeDelta TouchExplorationController::Now() {
554 if (tick_clock_) { 529 if (tick_clock_) {
555 // This is the same as what EventTimeForNow() does, but here we do it 530 // This is the same as what EventTimeForNow() does, but here we do it
556 // with a clock that can be replaced with a simulated clock for tests. 531 // with a clock that can be replaced with a simulated clock for tests.
557 return base::TimeDelta::FromInternalValue( 532 return base::TimeDelta::FromInternalValue(
558 tick_clock_->NowTicks().ToInternalValue()); 533 tick_clock_->NowTicks().ToInternalValue());
559 } 534 }
(...skipping 23 matching lines...) Expand all
583 last_touch_exploration_->location(); 558 last_touch_exploration_->location();
584 scoped_ptr<ui::TouchEvent> passthrough_press( 559 scoped_ptr<ui::TouchEvent> passthrough_press(
585 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 560 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
586 last_touch_exploration_->location(), 561 last_touch_exploration_->location(),
587 last_unused_finger_event_->touch_id(), 562 last_unused_finger_event_->touch_id(),
588 Now())); 563 Now()));
589 DispatchEvent(passthrough_press.get()); 564 DispatchEvent(passthrough_press.get());
590 return; 565 return;
591 } 566 }
592 case SINGLE_TAP_PRESSED: 567 case SINGLE_TAP_PRESSED:
593 case GESTURE_IN_PROGRESS:
594 // Discard any pending gestures.
595 delete gesture_provider_.GetAndResetPendingGestures();
596 EnterTouchToMouseMode(); 568 EnterTouchToMouseMode();
597 state_ = TOUCH_EXPLORATION; 569 state_ = TOUCH_EXPLORATION;
570 break;
571 case GESTURE_IN_PROGRESS:
572 // If only one finger is down, go into touch exploration.
573 if (current_touch_ids_.size() == 1) {
574 EnterTouchToMouseMode();
575 state_ = TOUCH_EXPLORATION;
576 VLOG_STATE();
577 break;
578 }
579 // Otherwise wait for all fingers to be lifted.
580 state_ = WAIT_FOR_NO_FINGERS;
598 VLOG_STATE(); 581 VLOG_STATE();
599 break; 582 return;
600 default: 583 default:
601 return; 584 return;
602 } 585 }
603 scoped_ptr<ui::Event> mouse_move = 586 scoped_ptr<ui::Event> mouse_move =
604 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 587 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
605 DispatchEvent(mouse_move.get()); 588 DispatchEvent(mouse_move.get());
606 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 589 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
607 } 590 }
608 591
609 void TouchExplorationController::DispatchEvent(ui::Event* event) { 592 void TouchExplorationController::DispatchEvent(ui::Event* event) {
610 if (event_handler_for_testing_) { 593 if (event_handler_for_testing_) {
611 event_handler_for_testing_->OnEvent(event); 594 event_handler_for_testing_->OnEvent(event);
612 return; 595 return;
613 } 596 }
614 ui::EventDispatchDetails result ALLOW_UNUSED = 597 ui::EventDispatchDetails result ALLOW_UNUSED =
615 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 598 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
616 } 599 }
617 600
618 void TouchExplorationController::OnGestureEvent( 601 // This is an override. We're using other more specific functions for possible
mfomitchev 2014/08/07 18:34:58 Would be good to clarify that this is only called
evy 2014/08/07 20:40:26 Done.
619 ui::GestureEvent* gesture) { 602 // processed gesture events.
620 CHECK(gesture->IsGestureEvent()); 603 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) {
621 ui::EventType type = gesture->type();
622 if (VLOG_on_)
623 VLOG(0) << " \n Gesture Triggered: " << gesture->name();
624 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) {
625 if (VLOG_on_)
626 VLOG(0) << "Swipe!";
627 delete gesture_provider_.GetAndResetPendingGestures();
628 OnSwipeEvent(gesture);
629 return;
630 }
631 } 604 }
632 605
633 void TouchExplorationController::ProcessGestureEvents() { 606 void TouchExplorationController::ProcessGestureEvents() {
634 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( 607 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
635 gesture_provider_.GetAndResetPendingGestures()); 608 gesture_provider_->GetAndResetPendingGestures());
636 if (gestures) { 609 if (gestures) {
637 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); 610 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
638 i != gestures->end(); 611 i != gestures->end();
639 ++i) { 612 ++i) {
640 if (state_ == SLIDE_GESTURE) 613 if ((*i)->type() == ui::ET_GESTURE_SWIPE &&
614 state_ == GESTURE_IN_PROGRESS) {
615 OnSwipeEvent(*i);
616 // The tap timer to leave gesture state is ended, and we now wait for
617 // all fingers to be released.
618 tap_timer_.Stop();
619 state_ = WAIT_FOR_NO_FINGERS;
620 VLOG_STATE();
621 return;
622 }
623 if (state_ == SLIDE_GESTURE && (*i)->IsScrollGestureEvent()) {
641 SideSlideControl(*i); 624 SideSlideControl(*i);
642 else 625 return;
mfomitchev 2014/08/07 18:34:58 Are you sure we want to ignore all the subsequent
evy 2014/08/07 20:40:26 yeah, we would - thanks
643 OnGestureEvent(*i); 626 }
644 } 627 }
645 } 628 }
646 } 629 }
647 630
648 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 631 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
649 ui::EventType type = gesture->type(); 632 ui::EventType type = gesture->type();
650 if (!gesture->IsScrollGestureEvent()) 633 CHECK(gesture->IsGestureEvent());
mfomitchev 2014/08/07 18:34:58 I don't think this can ever fail since gesture is
evy 2014/08/07 20:40:26 Done.
651 return; 634 CHECK(gesture->IsScrollGestureEvent());
mfomitchev 2014/08/07 18:34:58 If you do this, I don't think you need the above?
evy 2014/08/07 20:40:26 Done.
652 635
653 if (type == ET_GESTURE_SCROLL_BEGIN) { 636 if (type == ET_GESTURE_SCROLL_BEGIN) {
654 delegate_->PlayVolumeAdjustSound(); 637 delegate_->PlayVolumeAdjustSound();
655 } 638 }
656 639
657 if (type == ET_GESTURE_SCROLL_END) { 640 if (type == ET_GESTURE_SCROLL_END) {
658 if (sound_timer_.IsRunning()) 641 if (sound_timer_.IsRunning())
659 sound_timer_.Stop(); 642 sound_timer_.Stop();
660 delegate_->PlayVolumeAdjustSound(); 643 delegate_->PlayVolumeAdjustSound();
661 } 644 }
(...skipping 24 matching lines...) Expand all
686 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; 669 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height;
687 float volume = 100 - 100 * ratio; 670 float volume = 100 - 100 * ratio;
688 if (VLOG_on_) { 671 if (VLOG_on_) {
689 VLOG(0) << "\n Volume = " << volume 672 VLOG(0) << "\n Volume = " << volume
690 << "\n Location = " << location.ToString() 673 << "\n Location = " << location.ToString()
691 << "\n Bounds = " << root_window_->bounds().right(); 674 << "\n Bounds = " << root_window_->bounds().right();
692 } 675 }
693 delegate_->SetOutputLevel(int(volume)); 676 delegate_->SetOutputLevel(int(volume));
694 } 677 }
695 678
696
697 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 679 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
698 // A swipe gesture contains details for the direction in which the swipe 680 // A swipe gesture contains details for the direction in which the swipe
699 // occurred. 681 // occurred. TODO(evy) : Research which swipe results users most want and
682 // remap these swipes to the best events. Hopefully in the near future
683 // there will also be a menu for users to pick custom mappings.
684 CHECK(swipe_gesture->IsGestureEvent());
mfomitchev 2014/08/07 18:34:58 I don't think this can ever fail since gesture is
evy 2014/08/07 20:40:26 Yeah there are a few of these checks around - I'll
700 GestureEventDetails event_details = swipe_gesture->details(); 685 GestureEventDetails event_details = swipe_gesture->details();
701 if (event_details.swipe_left()) { 686 int num_fingers = event_details.touch_points();
702 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 687 if(VLOG_on_)
688 VLOG(0) << "\nSwipe with " << num_fingers << " fingers.";
689
690 if (num_fingers > 4)
703 return; 691 return;
704 } else if (event_details.swipe_right()) { 692
705 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); 693 if (event_details.swipe_left())
706 return; 694 left_swipe_gestures_[num_fingers].Run();
707 } else if (event_details.swipe_up()) { 695 else if (event_details.swipe_right())
708 DispatchShiftSearchKeyEvent(ui::VKEY_UP); 696 right_swipe_gestures_[num_fingers].Run();
709 return; 697 else if (event_details.swipe_up())
710 } else if (event_details.swipe_down()) { 698 up_swipe_gestures_[num_fingers].Run();
711 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); 699 else if (event_details.swipe_down())
712 return; 700 down_swipe_gestures_[num_fingers].Run();
713 }
714 } 701 }
715 702
716 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, 703 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point,
717 float bounds) { 704 float bounds) {
718 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be 705 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be
719 // converted. 706 // converted.
720 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); 707 root_window_->GetHost()->ConvertPointFromNativeScreen(&point);
721 gfx::Rect window = root_window_->GetBoundsInScreen(); 708 gfx::Rect window = root_window_->GetBoundsInScreen();
722 709
723 float left_edge_limit = window.x() + bounds; 710 float left_edge_limit = window.x() + bounds;
(...skipping 11 matching lines...) Expand all
735 if (point.x() > right_edge_limit) 722 if (point.x() > right_edge_limit)
736 result |= RIGHT_EDGE; 723 result |= RIGHT_EDGE;
737 if (point.y() < top_edge_limit) 724 if (point.y() < top_edge_limit)
738 result |= TOP_EDGE; 725 result |= TOP_EDGE;
739 if (point.y() > bottom_edge_limit) 726 if (point.y() > bottom_edge_limit)
740 result |= BOTTOM_EDGE; 727 result |= BOTTOM_EDGE;
741 return result; 728 return result;
742 } 729 }
743 730
744 void TouchExplorationController::DispatchShiftSearchKeyEvent( 731 void TouchExplorationController::DispatchShiftSearchKeyEvent(
745 const ui::KeyboardCode direction) { 732 const ui::KeyboardCode third_key) {
746 // In order to activate the shortcut shift+search+<arrow key> 733 // In order to activate the shortcut shift+search+<key>
747 // three KeyPressed events must be dispatched in succession along 734 // three KeyPressed events must be dispatched in succession along
748 // with three KeyReleased events. 735 // with three KeyReleased events.
749 ui::KeyEvent shift_down = ui::KeyEvent( 736
737 ui::KeyEvent shift_down(
750 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); 738 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
751 ui::KeyEvent search_down = ui::KeyEvent( 739 ui::KeyEvent search_down(
752 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 740 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
753 ui::KeyEvent direction_down = 741 ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN);
754 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN);
755 742
756 ui::KeyEvent direction_up = 743 ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN);
757 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); 744 ui::KeyEvent search_up(
758 ui::KeyEvent search_up = ui::KeyEvent(
759 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 745 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
760 ui::KeyEvent shift_up = 746 ui ::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
761 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
762 747
763 DispatchEvent(&shift_down); 748 DispatchEvent(&shift_down);
764 DispatchEvent(&search_down); 749 DispatchEvent(&search_down);
765 DispatchEvent(&direction_down); 750 DispatchEvent(&third_key_down);
766 DispatchEvent(&direction_up); 751 DispatchEvent(&third_key_up);
767 DispatchEvent(&search_up); 752 DispatchEvent(&search_up);
768 DispatchEvent(&shift_up); 753 DispatchEvent(&shift_up);
769 } 754 }
770 755
756 void TouchExplorationController::DispatchKeyWithFlags(
757 const ui::KeyboardCode key,
758 int flags) {
759 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags);
760 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags);
761 DispatchEvent(&key_down);
762 DispatchEvent(&key_up);
763 if(VLOG_on_) {
764 VLOG(0) << "\nKey down: key code : " << key_down.key_code()
765 << ", flags: " << key_down.flags()
766 << "\nKey up: key code : " << key_up.key_code()
767 << ", flags: " << key_up.flags();
768 }
769 }
770
771 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( 771 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
772 const gfx::PointF& location, 772 const gfx::PointF& location,
773 int flags) { 773 int flags) {
774 // The "synthesized" flag should be set on all events that don't have a 774 // The "synthesized" flag should be set on all events that don't have a
775 // backing native event. 775 // backing native event.
776 flags |= ui::EF_IS_SYNTHESIZED; 776 flags |= ui::EF_IS_SYNTHESIZED;
777 777
778 // This flag is used to identify mouse move events that were generated from 778 // This flag is used to identify mouse move events that were generated from
779 // touch exploration in Chrome code. 779 // touch exploration in Chrome code.
780 flags |= ui::EF_TOUCH_ACCESSIBILITY; 780 flags |= ui::EF_TOUCH_ACCESSIBILITY;
(...skipping 16 matching lines...) Expand all
797 void TouchExplorationController::EnterTouchToMouseMode() { 797 void TouchExplorationController::EnterTouchToMouseMode() {
798 aura::client::CursorClient* cursor_client = 798 aura::client::CursorClient* cursor_client =
799 aura::client::GetCursorClient(root_window_); 799 aura::client::GetCursorClient(root_window_);
800 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 800 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
801 cursor_client->EnableMouseEvents(); 801 cursor_client->EnableMouseEvents();
802 if (cursor_client && cursor_client->IsCursorVisible()) 802 if (cursor_client && cursor_client->IsCursorVisible())
803 cursor_client->HideCursor(); 803 cursor_client->HideCursor();
804 } 804 }
805 805
806 void TouchExplorationController::ResetToNoFingersDown() { 806 void TouchExplorationController::ResetToNoFingersDown() {
807 ProcessGestureEvents(); 807 gesture_provider_.reset(new GestureProviderAura(this));
808 if (sound_timer_.IsRunning()) 808 if (sound_timer_.IsRunning())
809 sound_timer_.Stop(); 809 sound_timer_.Stop();
810 state_ = NO_FINGERS_DOWN; 810 state_ = NO_FINGERS_DOWN;
811 VLOG_STATE(); 811 VLOG_STATE();
812 if (tap_timer_.IsRunning()) 812 tap_timer_.Stop();
813 tap_timer_.Stop();
814 } 813 }
815 814
816 void TouchExplorationController::VlogState(const char* function_name) { 815 void TouchExplorationController::VlogState(const char* function_name) {
817 if (!VLOG_on_) 816 if (!VLOG_on_)
818 return; 817 return;
819 if (prev_state_ == state_) 818 if (prev_state_ == state_)
820 return; 819 return;
821 prev_state_ = state_; 820 prev_state_ = state_;
822 const char* state_string = EnumStateToString(state_); 821 const char* state_string = EnumStateToString(state_);
823 VLOG(0) << "\n Function name: " << function_name 822 VLOG(0) << "\n Function name: " << function_name
(...skipping 12 matching lines...) Expand all
836 return; 835 return;
837 } 836 }
838 // The above statement prevents events of the same type and id from being 837 // The above statement prevents events of the same type and id from being
839 // printed in a row. However, if two fingers are down, they would both be 838 // printed in a row. However, if two fingers are down, they would both be
840 // moving and alternating printing move events unless we check for this. 839 // moving and alternating printing move events unless we check for this.
841 if (prev_event_ != NULL && 840 if (prev_event_ != NULL &&
842 prev_event_->type() == ET_TOUCH_MOVED && 841 prev_event_->type() == ET_TOUCH_MOVED &&
843 touch_event.type() == ET_TOUCH_MOVED){ 842 touch_event.type() == ET_TOUCH_MOVED){
844 return; 843 return;
845 } 844 }
845
846 const std::string& type = touch_event.name(); 846 const std::string& type = touch_event.name();
847 const gfx::PointF& location = touch_event.location_f(); 847 const gfx::PointF& location = touch_event.location_f();
848 const int touch_id = touch_event.touch_id(); 848 const int touch_id = touch_event.touch_id();
849 849
850 VLOG(0) << "\n Function name: " << function_name 850 VLOG(0) << "\n Function name: " << function_name
851 << "\n Event Type: " << type 851 << "\n Event Type: " << type
852 << "\n Location: " << location.ToString() 852 << "\n Location: " << location.ToString()
853 << "\n Touch ID: " << touch_id; 853 << "\n Touch ID: " << touch_id;
854 prev_event_.reset(new TouchEvent(touch_event)); 854 prev_event_.reset(new TouchEvent(touch_event));
855 } 855 }
(...skipping 11 matching lines...) Expand all
867 case DOUBLE_TAP_PENDING: 867 case DOUBLE_TAP_PENDING:
868 return "DOUBLE_TAP_PENDING"; 868 return "DOUBLE_TAP_PENDING";
869 case TOUCH_RELEASE_PENDING: 869 case TOUCH_RELEASE_PENDING:
870 return "TOUCH_RELEASE_PENDING"; 870 return "TOUCH_RELEASE_PENDING";
871 case TOUCH_EXPLORATION: 871 case TOUCH_EXPLORATION:
872 return "TOUCH_EXPLORATION"; 872 return "TOUCH_EXPLORATION";
873 case GESTURE_IN_PROGRESS: 873 case GESTURE_IN_PROGRESS:
874 return "GESTURE_IN_PROGRESS"; 874 return "GESTURE_IN_PROGRESS";
875 case TOUCH_EXPLORE_SECOND_PRESS: 875 case TOUCH_EXPLORE_SECOND_PRESS:
876 return "TOUCH_EXPLORE_SECOND_PRESS"; 876 return "TOUCH_EXPLORE_SECOND_PRESS";
877 case ONE_FINGER_PASSTHROUGH:
878 return "ONE_FINGER_PASSTHROUGH";
879 case WAIT_FOR_NO_FINGERS:
880 return "WAIT_FOR_NO_FINGERS";
877 case SLIDE_GESTURE: 881 case SLIDE_GESTURE:
878 return "SLIDE_GESTURE"; 882 return "SLIDE_GESTURE";
879 case ONE_FINGER_PASSTHROUGH:
880 return "ONE_FINGER_PASSTHROUGH";
881 case WAIT_FOR_ONE_FINGER:
882 return "WAIT_FOR_ONE_FINGER";
883 } 883 }
884 return "Not a state"; 884 return "Not a state";
885 } 885 }
886 886
887 void TouchExplorationController::InitializeSwipeGestureMaps() {
888 // Gestures with one finger are used for navigation.
889 left_swipe_gestures_[1] =
890 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
891 base::Unretained(this),
892 ui::VKEY_LEFT);
893 right_swipe_gestures_[1] =
894 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
895 base::Unretained(this),
896 ui::VKEY_RIGHT);
897 up_swipe_gestures_[1] =
898 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
899 base::Unretained(this),
900 ui::VKEY_UP);
901 down_swipe_gestures_[1] =
902 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
903 base::Unretained(this),
904 ui::VKEY_DOWN);
905
906 // Gestures with two fingers.
907 left_swipe_gestures_[2] =
908 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
909 base::Unretained(this),
910 ui::VKEY_BROWSER_BACK,
911 ui::EF_NONE);
912 right_swipe_gestures_[2] =
913 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
914 base::Unretained(this),
915 ui::VKEY_BROWSER_FORWARD,
916 ui::EF_NONE);
917 // Jump to top.
918 up_swipe_gestures_[2] =
919 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
920 base::Unretained(this),
921 ui::VKEY_A);
922 // Read from here.
923 down_swipe_gestures_[2] =
924 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
925 base::Unretained(this),
926 ui::VKEY_R);
927
928 // Gestures with three fingers switch tabs left/right and scroll up/down.
929 left_swipe_gestures_[3] =
930 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
931 base::Unretained(this),
932 ui::VKEY_TAB,
933 ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
934 right_swipe_gestures_[3] =
935 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
936 base::Unretained(this),
937 ui::VKEY_TAB,
938 ui::EF_CONTROL_DOWN);
939 up_swipe_gestures_[3] =
940 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
941 base::Unretained(this),
942 ui::VKEY_NEXT,
943 ui::EF_NONE);
944 down_swipe_gestures_[3] =
945 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
946 base::Unretained(this),
947 ui::VKEY_PRIOR,
948 ui::EF_NONE);
949
950 // Gestures with four fingers should probably eventually be used for rare
951 // needs that are hard to access through menus.
952 // Note that brightness levels are here because they can be important for low
953 // vision users. However, none of these mappings are permanent.
954 left_swipe_gestures_[4] =
955 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
956 base::Unretained(this),
957 ui::VKEY_BRIGHTNESS_DOWN,
958 ui::EF_NONE);
959 right_swipe_gestures_[4] =
960 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
961 base::Unretained(this),
962 VKEY_BRIGHTNESS_UP,
963 ui::EF_NONE);
964 up_swipe_gestures_[4] =
965 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
966 base::Unretained(this),
967 VKEY_BROWSER_HOME,
968 ui::EF_NONE);
969 down_swipe_gestures_[4] =
970 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
971 base::Unretained(this),
972 VKEY_BROWSER_REFRESH,
973 ui::EF_NONE);
974
975 }
976
887 } // namespace ui 977 } // 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