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