OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/events/gestures/gesture_event_queue.h" |
| 6 #include "ui/events/gestures/gesture_sequence.h" |
| 7 |
| 8 namespace ui { |
| 9 |
| 10 GestureEventQueue::GestureWithState::GestureWithState( |
| 11 GestureEvent* event, |
| 12 std::vector<TouchPointState*>& touch_point_states) |
| 13 : event_(event) { |
| 14 touch_point_states_.swap(touch_point_states); |
| 15 } |
| 16 |
| 17 GestureEventQueue::GestureWithState::~GestureWithState() { |
| 18 CHECK(event_->IsGestureEvent()); |
| 19 } |
| 20 |
| 21 GestureEventQueue::GestureEventQueue(GestureEventQueueDelegate* geqd) |
| 22 : gesture_event_queue_delegate_(geqd) { |
| 23 touch_point_states_.resize(GestureSequence::kMaxGesturePoints); |
| 24 acked_touch_point_states_.resize(GestureSequence::kMaxGesturePoints); |
| 25 consumed_touch_point_states_.resize(GestureSequence::kMaxGesturePoints); |
| 26 |
| 27 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) { |
| 28 touch_point_states_[i] = new TouchPointState(i); |
| 29 acked_touch_point_states_[i] = new TouchPointState(i); |
| 30 consumed_touch_point_states_[i] = new TouchPointState(i); |
| 31 } |
| 32 } |
| 33 |
| 34 GestureEventQueue::~GestureEventQueue() { |
| 35 while (!sequences_.empty()) { |
| 36 delete sequences_.front(); |
| 37 sequences_.pop_front(); |
| 38 } |
| 39 } |
| 40 |
| 41 void GestureEventQueue::OnTouchEvent(const TouchEvent& event) { |
| 42 touch_point_states_[event.touch_id()]->Update(event); |
| 43 |
| 44 // TODO - remove this |
| 45 if (!sequences_.empty() && !(*sequences_.begin())->empty()) { |
| 46 LOG(ERROR) << "length of first sequence is " |
| 47 << (*sequences_.begin())->size(); |
| 48 } |
| 49 } |
| 50 |
| 51 void GestureEventQueue::OnTouchEventAck( |
| 52 const TouchEvent& event, |
| 53 EventResult result) { |
| 54 if (result == ER_CONSUMED) |
| 55 consumed_touch_point_states_[event.touch_id()]->Update(event); |
| 56 else |
| 57 acked_touch_point_states_[event.touch_id()]->Update(event); |
| 58 |
| 59 DeleteConsumedEvents(); |
| 60 SendAckedEvents(); |
| 61 |
| 62 if (event.type() == ET_TOUCH_RELEASED || |
| 63 event.type() == ET_TOUCH_CANCELLED) { |
| 64 touch_point_states_[event.touch_id()]->Reset(); |
| 65 consumed_touch_point_states_[event.touch_id()]->Reset(); |
| 66 acked_touch_point_states_[event.touch_id()]->Reset(); |
| 67 } |
| 68 } |
| 69 |
| 70 void GestureEventQueue::QueueGestureEvent( |
| 71 GestureEvent* event, |
| 72 TouchPointState::RequiresAck requires_ack) { |
| 73 std::vector<TouchPointState*> tps; |
| 74 |
| 75 for (ScopedVector<TouchPointState>::iterator it = touch_point_states_.begin(); |
| 76 it != touch_point_states_.end(); |
| 77 ++it) { |
| 78 if ((*it)->has_press()) |
| 79 tps.push_back((*it)->CopyForGestureType(event->type(), requires_ack)); |
| 80 } |
| 81 // Takes ownership of entries in tps. |
| 82 QueueGestureEvent(event, tps); |
| 83 } |
| 84 |
| 85 void GestureEventQueue::TimerFired() { |
| 86 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) { |
| 87 if (touch_point_states_[i]->has_press()) |
| 88 acked_touch_point_states_[i]->TimerFired(); |
| 89 } |
| 90 SendAckedEvents(); |
| 91 } |
| 92 |
| 93 void GestureEventQueue::TimerCancelled() { |
| 94 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) { |
| 95 if (touch_point_states_[i]->has_press()) |
| 96 consumed_touch_point_states_[i]->TimerFired(); |
| 97 } |
| 98 DeleteConsumedEvents(); |
| 99 SendAckedEvents(); |
| 100 } |
| 101 |
| 102 void GestureEventQueue::QueueGestureEvent( |
| 103 GestureEvent* event, |
| 104 std::vector<TouchPointState*>& touch_point_states) { |
| 105 CHECK(event->IsGestureEvent()) << "Event of type " << event->type(); |
| 106 // If this marks the beginning of a new sequence, construct a new |
| 107 // |Sequence|. Deleted in |OnTouchEventAck|, and |~GestureEventQueue|. |
| 108 if (event->type() == ET_GESTURE_BEGIN && event->details().touch_points() == 1) |
| 109 sequences_.push_back(new Sequence()); |
| 110 |
| 111 DCHECK(!sequences_.empty()) << "Possibly missing a gesture begin"; |
| 112 |
| 113 if (sequences_.empty()) |
| 114 LOG(ERROR) << "Missing a gesture begin?"; |
| 115 // TODO - this shouldn't be necessary... |
| 116 if (sequences_.empty()) |
| 117 sequences_.push_back(new Sequence()); |
| 118 |
| 119 Sequence* sequence = sequences_.back(); |
| 120 |
| 121 // The GestureWithState takes ownership of the elements of touch_point_states. |
| 122 sequence->push_back(new GestureWithState(event, touch_point_states)); |
| 123 |
| 124 if (sequences_.empty()) { |
| 125 LOG(ERROR) << "No sequence"; |
| 126 } else if ((*sequences_.begin())->empty()) |
| 127 LOG(ERROR) << "First sequence empty"; |
| 128 else { |
| 129 LOG(ERROR) << "length of first sequence is " |
| 130 << (*sequences_.begin())->size(); |
| 131 LOG(ERROR) << "First element is " |
| 132 << (*(*sequences_.begin())->begin())->event()->type(); |
| 133 } |
| 134 |
| 135 DeleteConsumedEvents(); |
| 136 SendAckedEvents(); |
| 137 } |
| 138 |
| 139 void GestureEventQueue::SendGestureEvent(GestureEvent* event) { |
| 140 gesture_event_queue_delegate_->DispatchGestureEvent(event); |
| 141 } |
| 142 |
| 143 bool GestureEventQueue::CanSend( |
| 144 const std::vector<TouchPointState*>& gesture_touches) const { |
| 145 if (gesture_touches.empty()) |
| 146 return true; |
| 147 std::vector<TouchPointState*>::const_iterator it; |
| 148 for (it = gesture_touches.begin(); |
| 149 it != gesture_touches.end(); |
| 150 ++it) { |
| 151 const TouchPointState& current = |
| 152 *acked_touch_point_states_[(*it)->touch_id()]; |
| 153 |
| 154 if (!current.Contains(*(*it))) |
| 155 return false; |
| 156 } |
| 157 return true; |
| 158 } |
| 159 |
| 160 bool GestureEventQueue::CanDelete( |
| 161 const std::vector<TouchPointState*>& gesture_touches) const { |
| 162 if (gesture_touches.empty()) |
| 163 return false; |
| 164 std::vector<TouchPointState*>::const_iterator it; |
| 165 for (it = gesture_touches.begin(); |
| 166 it != gesture_touches.end(); |
| 167 ++it) { |
| 168 const TouchPointState& current = |
| 169 *consumed_touch_point_states_[(*it)->touch_id()]; |
| 170 if (!current.HasEmptyIntersection(*(*it))) |
| 171 return true; |
| 172 } |
| 173 return false; |
| 174 } |
| 175 |
| 176 void GestureEventQueue::SendAckedEvents() { |
| 177 RemoveEmptyFirstSequence(); |
| 178 LOG(ERROR) << "SendAckedEvents"; |
| 179 // TODO - should these be DCHECKs? |
| 180 if (sequences_.empty()) { |
| 181 LOG(ERROR) << "sequences_ is empty, bailing"; |
| 182 return; |
| 183 } |
| 184 Sequence* sequence = sequences_.front(); |
| 185 if (sequence->empty()) { |
| 186 LOG(ERROR) << "sequence is empty, bailing"; |
| 187 return; |
| 188 } |
| 189 DCHECK(!sequence->empty()); |
| 190 for (Sequence::iterator it = sequence->begin(); |
| 191 it != sequence->end();) { |
| 192 GestureEvent* event = (*it)->event(); |
| 193 CHECK(event->IsGestureEvent()) << "Event of type " << event->type(); |
| 194 if (CanSend((*it)->touch_point_states())) { |
| 195 SendGestureEvent(event); |
| 196 LOG(ERROR) << "SENT! " << event->type(); |
| 197 it = sequence->erase(it); |
| 198 LOG(ERROR) << "ERASED!"; |
| 199 } else if (event->type() == ET_GESTURE_LONG_PRESS || |
| 200 event->type() == ET_GESTURE_SHOW_PRESS) { |
| 201 // We don't need to respect the ordering of timed events. |
| 202 ++it; |
| 203 } else { |
| 204 break; |
| 205 } |
| 206 } |
| 207 } |
| 208 |
| 209 void GestureEventQueue::DeleteConsumedEvents() { |
| 210 RemoveEmptyFirstSequence(); |
| 211 // TODO - should this be a CHECK? |
| 212 if (sequences_.empty()) |
| 213 return; |
| 214 Sequence* sequence = sequences_.front(); |
| 215 if (sequence->empty()) |
| 216 return; |
| 217 DCHECK(!sequence->empty()); |
| 218 for (Sequence::iterator it = sequence->begin(); |
| 219 it != sequence->end();) { |
| 220 GestureEvent* event = (*it)->event(); |
| 221 CHECK(event->IsGestureEvent()) << "Event of type " << event->type(); |
| 222 if (CanDelete((*it)->touch_point_states())) { |
| 223 it = sequence->erase(it); |
| 224 } else |
| 225 ++it; |
| 226 } |
| 227 } |
| 228 |
| 229 void GestureEventQueue::RemoveEmptyFirstSequence() { |
| 230 // If we've sent or deleted everything in the current sequence, and a new |
| 231 // sequence has started, get rid of the current sequence. |
| 232 if (sequences_.size() > 1 && sequences_.front()->empty()) { |
| 233 delete sequences_.front(); |
| 234 sequences_.pop_front(); |
| 235 } |
| 236 } |
| 237 |
| 238 } // namespace ui |
OLD | NEW |