| 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/base/gestures/gesture_recognizer_impl.h" | 5 #include "ui/base/gestures/gesture_recognizer_impl.h" | 
| 6 | 6 | 
| 7 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" | 
| 9 #include "base/time.h" | 9 #include "base/time.h" | 
| 10 #include "ui/base/events/event.h" | 10 #include "ui/base/events/event.h" | 
| 11 #include "ui/base/events/event_constants.h" | 11 #include "ui/base/events/event_constants.h" | 
| 12 #include "ui/base/gestures/gesture_configuration.h" | 12 #include "ui/base/gestures/gesture_configuration.h" | 
| 13 #include "ui/base/gestures/gesture_sequence.h" | 13 #include "ui/base/gestures/gesture_sequence.h" | 
| 14 #include "ui/base/gestures/gesture_types.h" | 14 #include "ui/base/gestures/gesture_types.h" | 
| 15 | 15 | 
| 16 namespace ui { | 16 namespace ui { | 
| 17 | 17 | 
| 18 namespace { | 18 namespace { | 
| 19 | 19 | 
| 20 // This is used to pop a std::queue when returning from a function. |  | 
| 21 class ScopedPop { |  | 
| 22  public: |  | 
| 23   explicit ScopedPop(std::queue<TouchEvent*>* queue) : queue_(queue) { |  | 
| 24   } |  | 
| 25 |  | 
| 26   ~ScopedPop() { |  | 
| 27     delete queue_->front(); |  | 
| 28     queue_->pop(); |  | 
| 29   } |  | 
| 30 |  | 
| 31  private: |  | 
| 32   std::queue<TouchEvent*>* queue_; |  | 
| 33   DISALLOW_COPY_AND_ASSIGN(ScopedPop); |  | 
| 34 }; |  | 
| 35 |  | 
| 36 // CancelledTouchEvent mirrors a TouchEvent object. | 20 // CancelledTouchEvent mirrors a TouchEvent object. | 
| 37 class MirroredTouchEvent : public TouchEvent { | 21 class MirroredTouchEvent : public TouchEvent { | 
| 38  public: | 22  public: | 
| 39   explicit MirroredTouchEvent(const TouchEvent* real) | 23   explicit MirroredTouchEvent(const TouchEvent* real) | 
| 40       : TouchEvent(real->type(), | 24       : TouchEvent(real->type(), | 
| 41                    real->location(), | 25                    real->location(), | 
| 42                    real->touch_id(), | 26                    real->touch_id(), | 
| 43                    real->time_stamp()) { | 27                    real->time_stamp()) { | 
| 44     set_flags(real->flags()); | 28     set_flags(real->flags()); | 
| 45     set_radius(real->radius_x(), real->radius_y()); | 29     set_radius(real->radius_x(), real->radius_y()); | 
| 46     set_rotation_angle(real->rotation_angle()); | 30     set_rotation_angle(real->rotation_angle()); | 
| 47     set_force(real->force()); | 31     set_force(real->force()); | 
| 48   } | 32   } | 
| 49 | 33 | 
| 50   virtual ~MirroredTouchEvent() { | 34   virtual ~MirroredTouchEvent() { | 
| 51   } | 35   } | 
| 52 | 36 | 
| 53  private: | 37  private: | 
| 54   DISALLOW_COPY_AND_ASSIGN(MirroredTouchEvent); | 38   DISALLOW_COPY_AND_ASSIGN(MirroredTouchEvent); | 
| 55 }; | 39 }; | 
| 56 | 40 | 
| 57 class QueuedTouchEvent : public MirroredTouchEvent { |  | 
| 58  public: |  | 
| 59   QueuedTouchEvent(const TouchEvent* real, EventResult result) |  | 
| 60       : MirroredTouchEvent(real), |  | 
| 61         result_(result) { |  | 
| 62   } |  | 
| 63 |  | 
| 64   virtual ~QueuedTouchEvent() { |  | 
| 65   } |  | 
| 66 |  | 
| 67   EventResult result() const { return result_; } |  | 
| 68 |  | 
| 69  private: |  | 
| 70   EventResult result_; |  | 
| 71 |  | 
| 72   DISALLOW_COPY_AND_ASSIGN(QueuedTouchEvent); |  | 
| 73 }; |  | 
| 74 |  | 
| 75 // A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED. | 41 // A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED. | 
| 76 class CancelledTouchEvent : public MirroredTouchEvent { | 42 class CancelledTouchEvent : public MirroredTouchEvent { | 
| 77  public: | 43  public: | 
| 78   explicit CancelledTouchEvent(const TouchEvent* src) | 44   explicit CancelledTouchEvent(const TouchEvent* src) | 
| 79       : MirroredTouchEvent(src) { | 45       : MirroredTouchEvent(src) { | 
| 80     set_type(ET_TOUCH_CANCELLED); | 46     set_type(ET_TOUCH_CANCELLED); | 
| 81   } | 47   } | 
| 82 | 48 | 
| 83   virtual ~CancelledTouchEvent() {} | 49   virtual ~CancelledTouchEvent() {} | 
| 84 | 50 | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 132 //////////////////////////////////////////////////////////////////////////////// | 98 //////////////////////////////////////////////////////////////////////////////// | 
| 133 // GestureRecognizerImpl, public: | 99 // GestureRecognizerImpl, public: | 
| 134 | 100 | 
| 135 GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper) | 101 GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper) | 
| 136     : helper_(helper) { | 102     : helper_(helper) { | 
| 137   gesture_consumer_ignorer_.reset(new GestureConsumerIgnorer()); | 103   gesture_consumer_ignorer_.reset(new GestureConsumerIgnorer()); | 
| 138 } | 104 } | 
| 139 | 105 | 
| 140 GestureRecognizerImpl::~GestureRecognizerImpl() { | 106 GestureRecognizerImpl::~GestureRecognizerImpl() { | 
| 141   STLDeleteValues(&consumer_sequence_); | 107   STLDeleteValues(&consumer_sequence_); | 
| 142   STLDeleteValues(&event_queue_); |  | 
| 143 } | 108 } | 
| 144 | 109 | 
| 145 // Checks if this finger is already down, if so, returns the current target. | 110 // Checks if this finger is already down, if so, returns the current target. | 
| 146 // Otherwise, returns NULL. | 111 // Otherwise, returns NULL. | 
| 147 GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget( | 112 GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget( | 
| 148     TouchEvent* event) { | 113     TouchEvent* event) { | 
| 149   return touch_id_target_[event->touch_id()]; | 114   return touch_id_target_[event->touch_id()]; | 
| 150 } | 115 } | 
| 151 | 116 | 
| 152 GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent( | 117 GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent( | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 201       i->second = gesture_consumer_ignorer_.get(); | 166       i->second = gesture_consumer_ignorer_.get(); | 
| 202     } | 167     } | 
| 203   } | 168   } | 
| 204 | 169 | 
| 205   // Transer events from |current_consumer| to |new_consumer|. | 170   // Transer events from |current_consumer| to |new_consumer|. | 
| 206   if (current_consumer && new_consumer) { | 171   if (current_consumer && new_consumer) { | 
| 207     TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 172     TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 
| 208                                  &touch_id_target_); | 173                                  &touch_id_target_); | 
| 209     TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 174     TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 
| 210                                  &touch_id_target_for_gestures_); | 175                                  &touch_id_target_for_gestures_); | 
| 211     TransferConsumer(current_consumer, new_consumer, &event_queue_); |  | 
| 212     TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); | 176     TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); | 
| 213   } | 177   } | 
| 214 } | 178 } | 
| 215 | 179 | 
| 216 bool GestureRecognizerImpl::GetLastTouchPointForTarget( | 180 bool GestureRecognizerImpl::GetLastTouchPointForTarget( | 
| 217     GestureConsumer* consumer, | 181     GestureConsumer* consumer, | 
| 218     gfx::Point* point) { | 182     gfx::Point* point) { | 
| 219   if (consumer_sequence_.count(consumer) == 0) | 183   if (consumer_sequence_.count(consumer) == 0) | 
| 220     return false; | 184     return false; | 
| 221 | 185 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 249   if (event.type() == ui::ET_TOUCH_RELEASED || | 213   if (event.type() == ui::ET_TOUCH_RELEASED || | 
| 250       event.type() == ui::ET_TOUCH_CANCELLED) { | 214       event.type() == ui::ET_TOUCH_CANCELLED) { | 
| 251     touch_id_target_[event.touch_id()] = NULL; | 215     touch_id_target_[event.touch_id()] = NULL; | 
| 252   } else { | 216   } else { | 
| 253     touch_id_target_[event.touch_id()] = target; | 217     touch_id_target_[event.touch_id()] = target; | 
| 254     if (target) | 218     if (target) | 
| 255       touch_id_target_for_gestures_[event.touch_id()] = target; | 219       touch_id_target_for_gestures_[event.touch_id()] = target; | 
| 256   } | 220   } | 
| 257 } | 221 } | 
| 258 | 222 | 
| 259 GestureSequence::Gestures* GestureRecognizerImpl::AdvanceTouchQueueByOne( |  | 
| 260     GestureConsumer* consumer, |  | 
| 261     ui::EventResult result) { |  | 
| 262   CHECK(event_queue_[consumer]); |  | 
| 263   CHECK(!event_queue_[consumer]->empty()); |  | 
| 264 |  | 
| 265   ScopedPop pop(event_queue_[consumer]); |  | 
| 266   TouchEvent* event = event_queue_[consumer]->front(); |  | 
| 267   GestureSequence* sequence = GetGestureSequenceForConsumer(consumer); |  | 
| 268   if (result != ER_UNHANDLED && |  | 
| 269       event->type() == ET_TOUCH_RELEASED) { |  | 
| 270     // A touch release was was processed (e.g. preventDefault()ed by a |  | 
| 271     // web-page), but we still need to process a touch cancel. |  | 
| 272     CancelledTouchEvent cancelled(event); |  | 
| 273     return sequence->ProcessTouchEventForGesture(cancelled, |  | 
| 274                                                  ER_UNHANDLED); |  | 
| 275   } |  | 
| 276   return sequence->ProcessTouchEventForGesture(*event, result); |  | 
| 277 } |  | 
| 278 |  | 
| 279 GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture( | 223 GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture( | 
| 280     const TouchEvent& event, | 224     const TouchEvent& event, | 
| 281     ui::EventResult result, | 225     ui::EventResult result, | 
| 282     GestureConsumer* target) { | 226     GestureConsumer* target) { | 
| 283   if (event_queue_[target] && event_queue_[target]->size() > 0) { |  | 
| 284     // There are some queued touch-events for this target. Processing |event| |  | 
| 285     // before those queued events will result in unexpected gestures. So |  | 
| 286     // postpone the processing of the events until the queued events have been |  | 
| 287     // processed. |  | 
| 288     event_queue_[target]->push(new QueuedTouchEvent(&event, result)); |  | 
| 289     return NULL; |  | 
| 290   } |  | 
| 291 |  | 
| 292   SetupTargets(event, target); | 227   SetupTargets(event, target); | 
| 293 |  | 
| 294   GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target); | 228   GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target); | 
| 295   return gesture_sequence->ProcessTouchEventForGesture(event, result); | 229   return gesture_sequence->ProcessTouchEventForGesture(event, result); | 
| 296 } | 230 } | 
| 297 | 231 | 
| 298 void GestureRecognizerImpl::QueueTouchEventForGesture(GestureConsumer* consumer, | 232 void GestureRecognizerImpl::CleanupStateForConsumer(GestureConsumer* consumer) { | 
| 299                                                       const TouchEvent& event) { |  | 
| 300   if (!event_queue_[consumer]) |  | 
| 301     event_queue_[consumer] = new std::queue<TouchEvent*>(); |  | 
| 302   event_queue_[consumer]->push( |  | 
| 303       new QueuedTouchEvent(&event, ER_ASYNC)); |  | 
| 304 |  | 
| 305   SetupTargets(event, consumer); |  | 
| 306 } |  | 
| 307 |  | 
| 308 GestureSequence::Gestures* GestureRecognizerImpl::AdvanceTouchQueue( |  | 
| 309     GestureConsumer* consumer, |  | 
| 310     bool processed) { |  | 
| 311   if (!event_queue_[consumer] || event_queue_[consumer]->empty()) { |  | 
| 312     LOG(ERROR) << "Trying to advance an empty gesture queue for " << consumer; |  | 
| 313     return NULL; |  | 
| 314   } |  | 
| 315 |  | 
| 316   scoped_ptr<GestureSequence::Gestures> gestures( |  | 
| 317       AdvanceTouchQueueByOne(consumer, processed ? ER_HANDLED : |  | 
| 318                                                    ER_UNHANDLED)); |  | 
| 319 |  | 
| 320   // Are there any queued touch-events that should be auto-dequeued? |  | 
| 321   while (!event_queue_[consumer]->empty()) { |  | 
| 322     QueuedTouchEvent* event = |  | 
| 323       static_cast<QueuedTouchEvent*>(event_queue_[consumer]->front()); |  | 
| 324     if (event->result() == ER_ASYNC) |  | 
| 325       break; |  | 
| 326 |  | 
| 327     scoped_ptr<GestureSequence::Gestures> current_gestures( |  | 
| 328         AdvanceTouchQueueByOne(consumer, event->result())); |  | 
| 329     if (current_gestures.get()) { |  | 
| 330       if (!gestures.get()) { |  | 
| 331         gestures.reset(current_gestures.release()); |  | 
| 332       } else { |  | 
| 333         gestures->insert(gestures->end(), current_gestures->begin(), |  | 
| 334                                           current_gestures->end()); |  | 
| 335         // The gestures in |current_gestures| are now owned by |gestures|. Make |  | 
| 336         // sure they don't get freed with |current_gestures|. |  | 
| 337         current_gestures->weak_clear(); |  | 
| 338       } |  | 
| 339     } |  | 
| 340   } |  | 
| 341 |  | 
| 342   return gestures.release(); |  | 
| 343 } |  | 
| 344 |  | 
| 345 void GestureRecognizerImpl::FlushTouchQueue(GestureConsumer* consumer) { |  | 
| 346   if (consumer_sequence_.count(consumer)) { | 233   if (consumer_sequence_.count(consumer)) { | 
| 347     delete consumer_sequence_[consumer]; | 234     delete consumer_sequence_[consumer]; | 
| 348     consumer_sequence_.erase(consumer); | 235     consumer_sequence_.erase(consumer); | 
| 349   } | 236   } | 
| 350 | 237 | 
| 351   if (event_queue_.count(consumer)) { |  | 
| 352     delete event_queue_[consumer]; |  | 
| 353     event_queue_.erase(consumer); |  | 
| 354   } |  | 
| 355 |  | 
| 356   RemoveConsumerFromMap(consumer, &touch_id_target_); | 238   RemoveConsumerFromMap(consumer, &touch_id_target_); | 
| 357   RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_); | 239   RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_); | 
| 358 } | 240 } | 
| 359 | 241 | 
| 360 // GestureRecognizer, static | 242 // GestureRecognizer, static | 
| 361 GestureRecognizer* GestureRecognizer::Create(GestureEventHelper* helper) { | 243 GestureRecognizer* GestureRecognizer::Create(GestureEventHelper* helper) { | 
| 362   return new GestureRecognizerImpl(helper); | 244   return new GestureRecognizerImpl(helper); | 
| 363 } | 245 } | 
| 364 | 246 | 
| 365 }  // namespace ui | 247 }  // namespace ui | 
| OLD | NEW | 
|---|