OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/events/gestures/gesture_recognizer_impl.h" | 5 #include "ui/events/gestures/gesture_recognizer_impl.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 | 125 |
126 void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, | 126 void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, |
127 GestureConsumer* new_consumer) { | 127 GestureConsumer* new_consumer) { |
128 // Send cancel to all those save |new_consumer| and |current_consumer|. | 128 // Send cancel to all those save |new_consumer| and |current_consumer|. |
129 // Don't send a cancel to |current_consumer|, unless |new_consumer| is NULL. | 129 // Don't send a cancel to |current_consumer|, unless |new_consumer| is NULL. |
130 // Dispatching a touch-cancel event can end up altering |touch_id_target_| | 130 // Dispatching a touch-cancel event can end up altering |touch_id_target_| |
131 // (e.g. when the target of the event is destroyed, causing it to be removed | 131 // (e.g. when the target of the event is destroyed, causing it to be removed |
132 // from |touch_id_target_| in |CleanupStateForConsumer()|). So create a list | 132 // from |touch_id_target_| in |CleanupStateForConsumer()|). So create a list |
133 // of the touch-ids that need to be cancelled, and dispatch the cancel events | 133 // of the touch-ids that need to be cancelled, and dispatch the cancel events |
134 // for them at the end. | 134 // for them at the end. |
135 std::vector<std::pair<int, GestureConsumer*> > ids; | 135 |
136 for (TouchIdToConsumerMap::iterator i = touch_id_target_.begin(); | 136 std::vector<GestureConsumer*> consumers; |
137 i != touch_id_target_.end(); ++i) { | 137 std::map<GestureConsumer*, GestureProviderAura*>::iterator i; |
138 if (i->second && i->second != new_consumer && | 138 for (i = consumer_gesture_provider_.begin(); |
139 (i->second != current_consumer || new_consumer == NULL) && | 139 i != consumer_gesture_provider_.end(); |
140 i->second) { | 140 ++i) { |
141 ids.push_back(std::make_pair(i->first, i->second)); | 141 if (i->first && i->first != new_consumer && |
| 142 (i->first != current_consumer || new_consumer == NULL)) { |
| 143 consumers.push_back(i->first); |
142 } | 144 } |
143 } | 145 } |
144 | 146 for (std::vector<GestureConsumer*>::iterator iter = consumers.begin(); |
145 CancelTouches(&ids); | 147 iter != consumers.end(); |
146 | 148 ++iter) { |
| 149 CancelActiveTouches(*iter); |
| 150 } |
147 // Transfer events from |current_consumer| to |new_consumer|. | 151 // Transfer events from |current_consumer| to |new_consumer|. |
148 if (current_consumer && new_consumer) { | 152 if (current_consumer && new_consumer) { |
149 TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 153 TransferTouchIdToConsumerMap(current_consumer, new_consumer, |
150 &touch_id_target_); | 154 &touch_id_target_); |
151 TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 155 TransferTouchIdToConsumerMap(current_consumer, new_consumer, |
152 &touch_id_target_for_gestures_); | 156 &touch_id_target_for_gestures_); |
153 TransferConsumer( | 157 TransferConsumer( |
154 current_consumer, new_consumer, &consumer_gesture_provider_); | 158 current_consumer, new_consumer, &consumer_gesture_provider_); |
155 } | 159 } |
156 } | 160 } |
157 | 161 |
158 bool GestureRecognizerImpl::GetLastTouchPointForTarget( | 162 bool GestureRecognizerImpl::GetLastTouchPointForTarget( |
159 GestureConsumer* consumer, | 163 GestureConsumer* consumer, |
160 gfx::PointF* point) { | 164 gfx::PointF* point) { |
161 if (consumer_gesture_provider_.count(consumer) == 0) | 165 if (consumer_gesture_provider_.count(consumer) == 0) |
162 return false; | 166 return false; |
163 const MotionEvent& pointer_state = | 167 const MotionEvent& pointer_state = |
164 consumer_gesture_provider_[consumer]->pointer_state(); | 168 consumer_gesture_provider_[consumer]->pointer_state(); |
165 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); | 169 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); |
166 return true; | 170 return true; |
167 } | 171 } |
168 | 172 |
169 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { | 173 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { |
170 std::vector<std::pair<int, GestureConsumer*> > ids; | 174 bool cancelled_touch = false; |
171 for (TouchIdToConsumerMap::const_iterator i = touch_id_target_.begin(); | 175 if (consumer_gesture_provider_.count(consumer) == 0) |
172 i != touch_id_target_.end(); ++i) { | 176 return false; |
173 if (i->second == consumer) | 177 const MotionEventAura& pointer_state = |
174 ids.push_back(std::make_pair(i->first, i->second)); | 178 consumer_gesture_provider_[consumer]->pointer_state(); |
| 179 if (pointer_state.GetPointerCount() == 0) |
| 180 return false; |
| 181 // Pointer_state is modified every time after DispatchCancelTouchEvent. |
| 182 scoped_ptr<MotionEvent> pointer_state_clone = pointer_state.Clone(); |
| 183 for (size_t i = 0; i < pointer_state_clone->GetPointerCount(); ++i) { |
| 184 gfx::PointF point(pointer_state_clone->GetX(i), |
| 185 pointer_state_clone->GetY(i)); |
| 186 TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, |
| 187 point, |
| 188 ui::EF_IS_SYNTHESIZED, |
| 189 pointer_state_clone->GetPointerId(i), |
| 190 ui::EventTimeForNow(), |
| 191 0.0f, |
| 192 0.0f, |
| 193 0.0f, |
| 194 0.0f); |
| 195 GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer); |
| 196 if (helper) |
| 197 helper->DispatchCancelTouchEvent(&touch_event); |
| 198 cancelled_touch = true; |
175 } | 199 } |
176 bool cancelled_touch = !ids.empty(); | |
177 CancelTouches(&ids); | |
178 return cancelled_touch; | 200 return cancelled_touch; |
179 } | 201 } |
180 | 202 |
181 //////////////////////////////////////////////////////////////////////////////// | 203 //////////////////////////////////////////////////////////////////////////////// |
182 // GestureRecognizerImpl, private: | 204 // GestureRecognizerImpl, private: |
183 | 205 |
184 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( | 206 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( |
185 GestureConsumer* consumer) { | 207 GestureConsumer* consumer) { |
186 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; | 208 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; |
187 if (!gesture_provider) { | 209 if (!gesture_provider) { |
188 gesture_provider = CreateGestureProvider(this); | 210 gesture_provider = CreateGestureProvider(this); |
189 consumer_gesture_provider_[consumer] = gesture_provider; | 211 consumer_gesture_provider_[consumer] = gesture_provider; |
190 } | 212 } |
191 return gesture_provider; | 213 return gesture_provider; |
192 } | 214 } |
193 | 215 |
194 void GestureRecognizerImpl::SetupTargets(const TouchEvent& event, | 216 void GestureRecognizerImpl::SetupTargets(const TouchEvent& event, |
195 GestureConsumer* target) { | 217 GestureConsumer* target) { |
196 if (event.type() == ui::ET_TOUCH_RELEASED || | 218 if (event.type() == ui::ET_TOUCH_RELEASED || |
197 event.type() == ui::ET_TOUCH_CANCELLED) { | 219 event.type() == ui::ET_TOUCH_CANCELLED) { |
198 touch_id_target_.erase(event.touch_id()); | 220 touch_id_target_.erase(event.touch_id()); |
199 } else if (event.type() == ui::ET_TOUCH_PRESSED) { | 221 } else if (event.type() == ui::ET_TOUCH_PRESSED) { |
200 touch_id_target_[event.touch_id()] = target; | 222 touch_id_target_[event.touch_id()] = target; |
201 if (target) | 223 if (target) |
202 touch_id_target_for_gestures_[event.touch_id()] = target; | 224 touch_id_target_for_gestures_[event.touch_id()] = target; |
203 } | 225 } |
204 } | 226 } |
205 | 227 |
206 void GestureRecognizerImpl::CancelTouches( | |
207 std::vector<std::pair<int, GestureConsumer*> >* touches) { | |
208 while (!touches->empty()) { | |
209 int touch_id = touches->begin()->first; | |
210 GestureConsumer* target = touches->begin()->second; | |
211 TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, gfx::PointF(0, 0), | |
212 ui::EF_IS_SYNTHESIZED, touch_id, | |
213 ui::EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f); | |
214 GestureEventHelper* helper = FindDispatchHelperForConsumer(target); | |
215 if (helper) | |
216 helper->DispatchCancelTouchEvent(&touch_event); | |
217 touches->erase(touches->begin()); | |
218 } | |
219 } | |
220 | |
221 void GestureRecognizerImpl::DispatchGestureEvent(GestureEvent* event) { | 228 void GestureRecognizerImpl::DispatchGestureEvent(GestureEvent* event) { |
222 GestureConsumer* consumer = GetTargetForGestureEvent(*event); | 229 GestureConsumer* consumer = GetTargetForGestureEvent(*event); |
223 if (consumer) { | 230 if (consumer) { |
224 GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer); | 231 GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer); |
225 if (helper) | 232 if (helper) |
226 helper->DispatchGestureEvent(event); | 233 helper->DispatchGestureEvent(event); |
227 } | 234 } |
228 } | 235 } |
229 | 236 |
230 bool GestureRecognizerImpl::ProcessTouchEventPreDispatch( | 237 bool GestureRecognizerImpl::ProcessTouchEventPreDispatch( |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 std::vector<GestureEventHelper*>::iterator it; | 339 std::vector<GestureEventHelper*>::iterator it; |
333 for (it = helpers.begin(); it != helpers.end(); ++it) | 340 for (it = helpers.begin(); it != helpers.end(); ++it) |
334 gesture_recognizer->AddGestureEventHelper(*it); | 341 gesture_recognizer->AddGestureEventHelper(*it); |
335 | 342 |
336 helpers.clear(); | 343 helpers.clear(); |
337 g_gesture_recognizer_instance = | 344 g_gesture_recognizer_instance = |
338 static_cast<GestureRecognizerImpl*>(gesture_recognizer); | 345 static_cast<GestureRecognizerImpl*>(gesture_recognizer); |
339 } | 346 } |
340 | 347 |
341 } // namespace ui | 348 } // namespace ui |
OLD | NEW |