OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "components/view_manager/gesture_manager.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "components/view_manager/gesture_manager_delegate.h" | |
10 #include "components/view_manager/public/cpp/keys.h" | |
11 #include "components/view_manager/server_view.h" | |
12 #include "components/view_manager/view_coordinate_conversions.h" | |
13 #include "components/view_manager/view_locator.h" | |
14 #include "ui/gfx/geometry/point_f.h" | |
15 #include "ui/mojo/events/input_events.mojom.h" | |
16 | |
17 namespace view_manager { | |
18 | |
19 using Views = std::vector<const ServerView*>; | |
20 | |
21 namespace { | |
22 | |
23 GestureManager::GestureAndConnectionId MakeGestureAndConnectionId( | |
24 const ServerView* view, | |
25 uint32_t gesture_id) { | |
26 return (static_cast<GestureManager::GestureAndConnectionId>( | |
27 view->id().connection_id) | |
28 << 32) | | |
29 gesture_id; | |
30 } | |
31 | |
32 // Returns the views (deepest first) that should receive touch events. This only | |
33 // returns one view per connection. If multiple views from the same connection | |
34 // are interested in touch events the shallowest view is returned. | |
35 Views GetTouchTargets(const ServerView* deepest) { | |
36 Views result; | |
37 const ServerView* view = deepest; | |
38 while (view) { | |
39 if (view->properties().count(mojo::kViewManagerKeyWantsTouchEvents)) { | |
40 if (!result.empty() && | |
41 result.back()->id().connection_id == view->id().connection_id) { | |
42 result.pop_back(); | |
43 } | |
44 result.push_back(view); | |
45 } | |
46 view = view->parent(); | |
47 } | |
48 // TODO(sky): I'm doing this until things are converted. Seems as though we | |
49 // shouldn't do this long term. | |
50 if (result.empty()) | |
51 result.push_back(deepest); | |
52 return result; | |
53 } | |
54 | |
55 mojo::EventPtr CloneEventForView(const mojo::Event& event, | |
56 const ServerView* view) { | |
57 mojo::EventPtr result(event.Clone()); | |
58 const gfx::PointF location(event.pointer_data->x, event.pointer_data->y); | |
59 const gfx::PointF target_location( | |
60 ConvertPointFBetweenViews(view->GetRoot(), view, location)); | |
61 result->pointer_data->x = target_location.x(); | |
62 result->pointer_data->y = target_location.y(); | |
63 return result.Pass(); | |
64 } | |
65 | |
66 } // namespace | |
67 | |
68 // GestureStateChange ---------------------------------------------------------- | |
69 | |
70 GestureStateChange::GestureStateChange() | |
71 : chosen_gesture(GestureManager::kInvalidGestureId) { | |
72 } | |
73 | |
74 GestureStateChange::~GestureStateChange() { | |
75 } | |
76 | |
77 // ViewIterator ---------------------------------------------------------------- | |
78 | |
79 // Used to iterate over a set of views. | |
80 class ViewIterator { | |
81 public: | |
82 explicit ViewIterator(const Views& views) | |
83 : views_(views), current_(views_.begin()) {} | |
84 | |
85 // Advances to the next view. Returns true if there are no more views (at | |
86 // the end). | |
87 bool advance() { return ++current_ != views_.end(); } | |
88 | |
89 bool at_end() const { return current_ == views_.end(); } | |
90 | |
91 bool empty() const { return views_.empty(); } | |
92 | |
93 const ServerView* current() const { return *current_; } | |
94 | |
95 void reset_to_beginning() { current_ = views_.begin(); } | |
96 | |
97 void remove(const ServerView* view) { | |
98 Views::iterator iter = std::find(views_.begin(), views_.end(), view); | |
99 DCHECK(iter != views_.end()); | |
100 if (iter == current_) { | |
101 current_ = views_.erase(current_); | |
102 } else if (!at_end()) { | |
103 size_t index = current_ - views_.begin(); | |
104 if (current_ > iter) | |
105 index--; | |
106 views_.erase(iter); | |
107 current_ = views_.begin() + index; | |
108 } else { | |
109 views_.erase(iter); | |
110 current_ = views_.end(); | |
111 } | |
112 } | |
113 | |
114 bool contains(const ServerView* view) const { | |
115 return std::find(views_.begin(), views_.end(), view) != views_.end(); | |
116 } | |
117 | |
118 private: | |
119 Views views_; | |
120 Views::iterator current_; | |
121 | |
122 DISALLOW_COPY_AND_ASSIGN(ViewIterator); | |
123 }; | |
124 | |
125 // PointerAndView -------------------------------------------------------------- | |
126 | |
127 struct GestureManager::PointerAndView { | |
128 PointerAndView(); | |
129 PointerAndView(Pointer* pointer, const ServerView* view); | |
130 | |
131 // Compares two PointerAndView instances based on pointer id, then view id. | |
132 // This is really only interesting for unit tests so that they get a known | |
133 // order of events. | |
134 bool operator<(const PointerAndView& other) const; | |
135 | |
136 Pointer* pointer; | |
137 const ServerView* view; | |
138 }; | |
139 | |
140 // Gesture --------------------------------------------------------------------- | |
141 | |
142 // Gesture maintains the set of pointers and views it is attached to. | |
143 class GestureManager::Gesture { | |
144 public: | |
145 enum State { STATE_INITIAL, STATE_CANCELED, STATE_CHOSEN }; | |
146 | |
147 explicit Gesture(uint32_t id); | |
148 ~Gesture(); | |
149 | |
150 uint32_t id() const { return id_; } | |
151 | |
152 void Attach(Pointer* pointer, const ServerView* view); | |
153 void Detach(Pointer* pointer, const ServerView* view); | |
154 | |
155 void set_state(State state) { state_ = state; } | |
156 State state() const { return state_; } | |
157 | |
158 const std::set<PointerAndView>& pointers_and_views() const { | |
159 return pointers_and_views_; | |
160 } | |
161 | |
162 private: | |
163 const uint32_t id_; | |
164 State state_; | |
165 std::set<PointerAndView> pointers_and_views_; | |
166 | |
167 DISALLOW_COPY_AND_ASSIGN(Gesture); | |
168 }; | |
169 | |
170 GestureManager::Gesture::Gesture(uint32_t id) : id_(id), state_(STATE_INITIAL) { | |
171 } | |
172 | |
173 GestureManager::Gesture::~Gesture() { | |
174 } | |
175 | |
176 void GestureManager::Gesture::Attach(Pointer* pointer, const ServerView* view) { | |
177 pointers_and_views_.insert(PointerAndView(pointer, view)); | |
178 } | |
179 | |
180 void GestureManager::Gesture::Detach(Pointer* pointer, const ServerView* view) { | |
181 pointers_and_views_.erase(PointerAndView(pointer, view)); | |
182 } | |
183 | |
184 // Pointer --------------------------------------------------------------------- | |
185 | |
186 // Pointer manages the state associated with a particular pointer from the time | |
187 // of the POINTER_DOWN to the time of the POINTER_UP (or POINTER_CANCEL). This | |
188 // state includes a mapping from view to the set of gestures the view is | |
189 // interested in. It also manages choosing gestures at the appropriate point as | |
190 // well as which view to dispatch to and the events to dispatch. | |
191 // See description in GestureManager for more. | |
192 class GestureManager::Pointer { | |
193 public: | |
194 Pointer(GestureManager* gesture_manager, | |
195 int32_t pointer_id, | |
196 const mojo::Event& event, | |
197 const Views& views); | |
198 ~Pointer(); | |
199 | |
200 int32_t pointer_id() const { return pointer_id_; } | |
201 bool was_chosen_or_canceled() const { return was_chosen_or_canceled_; } | |
202 | |
203 // Sets the set of gestures for this pointer. | |
204 void SetGestures(const ServerView* view, | |
205 uint32_t chosen_gesture_id, | |
206 const std::set<uint32_t>& possible_gesture_ids, | |
207 const std::set<uint32_t>& canceled_ids); | |
208 | |
209 // Called when a Gesture we contain has been canceled. | |
210 void GestureCanceled(Gesture* gesture); | |
211 | |
212 // Called when a Gesture we contain has been chosen. | |
213 void GestureChosen(Gesture* gesture, const ServerView* view); | |
214 | |
215 // Process a move or up event. This may delay processing if we're waiting for | |
216 // previous results. | |
217 void ProcessEvent(const mojo::Event& event); | |
218 | |
219 private: | |
220 // Corresponds to the type of event we're dispatching. | |
221 enum Phase { | |
222 // We're dispatching the initial down. | |
223 PHASE_DOWN, | |
224 | |
225 // We're dispatching a move. | |
226 PHASE_MOVE, | |
227 }; | |
228 | |
229 // Sends the event for the current phase to the delegate. | |
230 void ForwardCurrentEvent(); | |
231 | |
232 // Moves |pending_event_| to |current_event_| and notifies the delegate. | |
233 void MovePendingToCurrentAndProcess(); | |
234 | |
235 // If |was_chosen_or_canceled_| is false and there is only one possible | |
236 // gesture and it is in the initial state, choose it. Otherwise do nothing. | |
237 void ChooseGestureIfPossible(); | |
238 | |
239 bool ScheduleDeleteIfNecessary(); | |
240 | |
241 GestureManager* gesture_manager_; | |
242 const int32_t pointer_id_; | |
243 Phase phase_; | |
244 | |
245 // Used to iterate over the set of views that potentially have gestures. | |
246 ViewIterator view_iter_; | |
247 | |
248 // Maps from the view to the set of possible gestures for the view. | |
249 std::map<const ServerView*, std::set<Gesture*>> view_to_gestures_; | |
250 | |
251 Gesture* chosen_gesture_; | |
252 | |
253 bool was_chosen_or_canceled_; | |
254 | |
255 // The event we're processing. When initially created this is the supplied | |
256 // down event. When in PHASE_MOVE this is a move event. | |
257 mojo::EventPtr current_event_; | |
258 | |
259 // Incoming events (move or up) are added here while while waiting for | |
260 // responses. | |
261 mojo::EventPtr pending_event_; | |
262 | |
263 DISALLOW_COPY_AND_ASSIGN(Pointer); | |
264 }; | |
265 | |
266 GestureManager::Pointer::Pointer(GestureManager* gesture_manager, | |
267 int32_t pointer_id, | |
268 const mojo::Event& event, | |
269 const Views& views) | |
270 : gesture_manager_(gesture_manager), | |
271 pointer_id_(pointer_id), | |
272 phase_(PHASE_DOWN), | |
273 view_iter_(views), | |
274 chosen_gesture_(nullptr), | |
275 was_chosen_or_canceled_(false), | |
276 current_event_(event.Clone()) { | |
277 ForwardCurrentEvent(); | |
278 } | |
279 | |
280 GestureManager::Pointer::~Pointer() { | |
281 for (auto& pair : view_to_gestures_) { | |
282 for (Gesture* gesture : pair.second) | |
283 gesture_manager_->DetachGesture(gesture, this, pair.first); | |
284 } | |
285 } | |
286 | |
287 void GestureManager::Pointer::SetGestures( | |
288 const ServerView* view, | |
289 uint32_t chosen_gesture_id, | |
290 const std::set<uint32_t>& possible_gesture_ids, | |
291 const std::set<uint32_t>& canceled_gesture_ids) { | |
292 if (!view_iter_.contains(view)) { | |
293 // We don't know about this view. | |
294 return; | |
295 } | |
296 | |
297 // True if this is the view we're waiting for a response from. | |
298 const bool was_waiting_on = | |
299 (!was_chosen_or_canceled_ && | |
300 (!view_iter_.at_end() && view_iter_.current() == view)); | |
301 | |
302 if (possible_gesture_ids.empty()) { | |
303 // The view no longer wants to be notified. | |
304 for (Gesture* gesture : view_to_gestures_[view]) | |
305 gesture_manager_->DetachGesture(gesture, this, view); | |
306 view_to_gestures_.erase(view); | |
307 view_iter_.remove(view); | |
308 if (view_iter_.empty()) { | |
309 gesture_manager_->PointerHasNoGestures(this); | |
310 // WARNING: we've been deleted. | |
311 return; | |
312 } | |
313 } else { | |
314 if (was_waiting_on) | |
315 view_iter_.advance(); | |
316 | |
317 Gesture* to_choose = nullptr; | |
318 std::set<Gesture*> gestures; | |
319 for (auto gesture_id : possible_gesture_ids) { | |
320 Gesture* gesture = gesture_manager_->GetGesture(view, gesture_id); | |
321 gesture_manager_->AttachGesture(gesture, this, view); | |
322 gestures.insert(gesture); | |
323 if (gesture->state() == Gesture::STATE_CHOSEN && | |
324 !was_chosen_or_canceled_) { | |
325 to_choose = gesture; | |
326 } | |
327 } | |
328 | |
329 // Give preference to the supplied |chosen_gesture_id|. | |
330 if (!was_chosen_or_canceled_ && chosen_gesture_id != kInvalidGestureId) { | |
331 Gesture* gesture = gesture_manager_->GetGesture(view, chosen_gesture_id); | |
332 if (gesture->state() != Gesture::STATE_CANCELED) | |
333 to_choose = gesture; | |
334 | |
335 DCHECK(possible_gesture_ids.count(gesture->id())); | |
336 gesture_manager_->AttachGesture(gesture, this, view); | |
337 } | |
338 | |
339 // Tell GestureManager of any Gestures we're no longer associated with. | |
340 std::set<Gesture*> removed_gestures; | |
341 std::set_difference( | |
342 view_to_gestures_[view].begin(), view_to_gestures_[view].end(), | |
343 gestures.begin(), gestures.end(), | |
344 std::inserter(removed_gestures, removed_gestures.begin())); | |
345 view_to_gestures_[view].swap(gestures); | |
346 for (Gesture* gesture : removed_gestures) | |
347 gesture_manager_->DetachGesture(gesture, this, view); | |
348 | |
349 if (chosen_gesture_ && removed_gestures.count(chosen_gesture_)) | |
350 chosen_gesture_ = nullptr; | |
351 | |
352 if (to_choose) { | |
353 gesture_manager_->ChooseGesture(to_choose, this, view); | |
354 } else { | |
355 // Choosing a gesture implicitly cancels all other gestures. If we didn't | |
356 // choose a gesture we need to update the state of any newly added | |
357 // gestures. | |
358 for (Gesture* gesture : gestures) { | |
359 if (gesture != chosen_gesture_ && | |
360 (was_chosen_or_canceled_ || | |
361 canceled_gesture_ids.count(gesture->id()))) { | |
362 gesture_manager_->CancelGesture(gesture, this, view); | |
363 } | |
364 } | |
365 } | |
366 } | |
367 | |
368 if (was_waiting_on && !was_chosen_or_canceled_) { | |
369 if (view_iter_.at_end()) { | |
370 if (ScheduleDeleteIfNecessary()) | |
371 return; | |
372 // If we're got all the responses, check if there is only one valid | |
373 // gesture. | |
374 ChooseGestureIfPossible(); | |
375 if (!was_chosen_or_canceled_) { | |
376 // There is more than one valid gesture and none chosen. Continue | |
377 // synchronous dispatch of move events. | |
378 phase_ = PHASE_MOVE; | |
379 MovePendingToCurrentAndProcess(); | |
380 } | |
381 } else { | |
382 ForwardCurrentEvent(); | |
383 } | |
384 } else if (!was_chosen_or_canceled_ && phase_ != PHASE_DOWN) { | |
385 // We weren't waiting on this view but we're in the move phase. The set of | |
386 // gestures may have changed such that we only have one valid gesture. Check | |
387 // for that. | |
388 ChooseGestureIfPossible(); | |
389 } | |
390 } | |
391 | |
392 void GestureManager::Pointer::GestureCanceled(Gesture* gesture) { | |
393 if (was_chosen_or_canceled_ && gesture == chosen_gesture_) { | |
394 chosen_gesture_ = nullptr; | |
395 // No need to cancel other gestures as they are already canceled by virtue | |
396 // of us having been chosen. | |
397 } else if (!was_chosen_or_canceled_ && phase_ == PHASE_MOVE) { | |
398 ChooseGestureIfPossible(); | |
399 } | |
400 } | |
401 | |
402 void GestureManager::Pointer::GestureChosen(Gesture* gesture, | |
403 const ServerView* view) { | |
404 DCHECK(!was_chosen_or_canceled_); | |
405 was_chosen_or_canceled_ = true; | |
406 chosen_gesture_ = gesture; | |
407 for (auto& pair : view_to_gestures_) { | |
408 for (Gesture* g : pair.second) { | |
409 if (g != gesture) | |
410 gesture_manager_->CancelGesture(g, this, pair.first); | |
411 } | |
412 } | |
413 | |
414 while (!view_iter_.at_end()) { | |
415 ForwardCurrentEvent(); | |
416 view_iter_.advance(); | |
417 } | |
418 if (ScheduleDeleteIfNecessary()) | |
419 return; | |
420 phase_ = PHASE_MOVE; | |
421 MovePendingToCurrentAndProcess(); | |
422 } | |
423 | |
424 void GestureManager::Pointer::ProcessEvent(const mojo::Event& event) { | |
425 // |event| is either a move or up. In either case it has the new coordinates | |
426 // and is safe to replace the existing one with. | |
427 pending_event_ = event.Clone(); | |
428 if (was_chosen_or_canceled_) { | |
429 MovePendingToCurrentAndProcess(); | |
430 } else if (view_iter_.at_end()) { | |
431 view_iter_.reset_to_beginning(); | |
432 MovePendingToCurrentAndProcess(); | |
433 } | |
434 // The else case is we are waiting on a response from a view before we | |
435 // continue dispatching. When we get the response for the last view in the | |
436 // stack we'll move pending to current and start dispatching it. | |
437 } | |
438 | |
439 void GestureManager::Pointer::ForwardCurrentEvent() { | |
440 DCHECK(!view_iter_.at_end()); | |
441 const ServerView* view = view_iter_.current(); | |
442 gesture_manager_->delegate_->ProcessEvent( | |
443 view, CloneEventForView(*current_event_, view), was_chosen_or_canceled_); | |
444 } | |
445 | |
446 void GestureManager::Pointer::MovePendingToCurrentAndProcess() { | |
447 if (!pending_event_.get()) { | |
448 current_event_ = nullptr; | |
449 return; | |
450 } | |
451 current_event_ = pending_event_.Pass(); | |
452 view_iter_.reset_to_beginning(); | |
453 ForwardCurrentEvent(); | |
454 if (was_chosen_or_canceled_) { | |
455 while (view_iter_.advance()) | |
456 ForwardCurrentEvent(); | |
457 if (ScheduleDeleteIfNecessary()) | |
458 return; | |
459 current_event_ = nullptr; | |
460 } | |
461 } | |
462 | |
463 void GestureManager::Pointer::ChooseGestureIfPossible() { | |
464 if (was_chosen_or_canceled_) | |
465 return; | |
466 | |
467 Gesture* gesture_to_choose = nullptr; | |
468 const ServerView* view = nullptr; | |
469 for (auto& pair : view_to_gestures_) { | |
470 for (Gesture* gesture : pair.second) { | |
471 if (gesture->state() == Gesture::STATE_INITIAL) { | |
472 if (gesture_to_choose) | |
473 return; | |
474 view = pair.first; | |
475 gesture_to_choose = gesture; | |
476 } | |
477 } | |
478 } | |
479 if (view) | |
480 gesture_manager_->ChooseGesture(gesture_to_choose, this, view); | |
481 } | |
482 | |
483 bool GestureManager::Pointer::ScheduleDeleteIfNecessary() { | |
484 if (current_event_ && | |
485 (current_event_->action == mojo::EVENT_TYPE_POINTER_UP || | |
486 current_event_->action == mojo::EVENT_TYPE_POINTER_CANCEL)) { | |
487 gesture_manager_->ScheduleDelete(this); | |
488 return true; | |
489 } | |
490 return false; | |
491 } | |
492 | |
493 // ScheduledDeleteProcessor --------------------------------------------------- | |
494 | |
495 class GestureManager::ScheduledDeleteProcessor { | |
496 public: | |
497 explicit ScheduledDeleteProcessor(GestureManager* manager) | |
498 : manager_(manager) {} | |
499 | |
500 ~ScheduledDeleteProcessor() { manager_->pointers_to_delete_.clear(); } | |
501 | |
502 private: | |
503 GestureManager* manager_; | |
504 | |
505 DISALLOW_COPY_AND_ASSIGN(ScheduledDeleteProcessor); | |
506 }; | |
507 | |
508 // PointerAndView -------------------------------------------------------------- | |
509 | |
510 GestureManager::PointerAndView::PointerAndView() | |
511 : pointer(nullptr), view(nullptr) { | |
512 } | |
513 | |
514 GestureManager::PointerAndView::PointerAndView(Pointer* pointer, | |
515 const ServerView* view) | |
516 : pointer(pointer), view(view) { | |
517 } | |
518 | |
519 bool GestureManager::PointerAndView::operator<( | |
520 const PointerAndView& other) const { | |
521 if (other.pointer->pointer_id() == pointer->pointer_id()) | |
522 return view->id().connection_id < other.view->id().connection_id; | |
523 return pointer->pointer_id() < other.pointer->pointer_id(); | |
524 } | |
525 | |
526 // GestureManager -------------------------------------------------------------- | |
527 | |
528 // static | |
529 const uint32_t GestureManager::kInvalidGestureId = 0u; | |
530 | |
531 GestureManager::GestureManager(GestureManagerDelegate* delegate, | |
532 const ServerView* root) | |
533 : delegate_(delegate), root_view_(root) { | |
534 } | |
535 | |
536 GestureManager::~GestureManager() { | |
537 // Explicitly delete the pointers first as this may result in calling back to | |
538 // us to cleanup and delete gestures. | |
539 active_pointers_.clear(); | |
540 } | |
541 | |
542 bool GestureManager::ProcessEvent(const mojo::Event& event) { | |
543 if (!event.pointer_data) | |
544 return false; | |
545 | |
546 ScheduledDeleteProcessor delete_processor(this); | |
547 const gfx::Point location(static_cast<int>(event.pointer_data->x), | |
548 static_cast<int>(event.pointer_data->y)); | |
549 switch (event.action) { | |
550 case mojo::EVENT_TYPE_POINTER_DOWN: { | |
551 if (GetPointerById(event.pointer_data->pointer_id)) { | |
552 DVLOG(1) << "received more than one down for a pointer without a " | |
553 << "corresponding up, id=" << event.pointer_data->pointer_id; | |
554 NOTREACHED(); | |
555 return true; | |
556 } | |
557 | |
558 const ServerView* deepest = FindDeepestVisibleView(root_view_, location); | |
559 Views targets(GetTouchTargets(deepest)); | |
560 if (targets.empty()) | |
561 return true; | |
562 | |
563 scoped_ptr<Pointer> pointer( | |
564 new Pointer(this, event.pointer_data->pointer_id, event, targets)); | |
565 active_pointers_.push_back(pointer.Pass()); | |
566 return true; | |
567 } | |
568 | |
569 case mojo::EVENT_TYPE_POINTER_CANCEL: | |
570 case mojo::EVENT_TYPE_POINTER_MOVE: | |
571 case mojo::EVENT_TYPE_POINTER_UP: { | |
572 Pointer* pointer = GetPointerById(event.pointer_data->pointer_id); | |
573 // We delete a pointer when it has no gestures, so it's possible to get | |
574 // here with no gestures. Additionally there is no need to explicitly | |
575 // delete |pointer| as it'll tell us when it's ready to be deleted. | |
576 if (pointer) | |
577 pointer->ProcessEvent(event); | |
578 return true; | |
579 } | |
580 | |
581 default: | |
582 break; | |
583 } | |
584 return false; | |
585 } | |
586 | |
587 scoped_ptr<ChangeMap> GestureManager::SetGestures( | |
588 const ServerView* view, | |
589 int32_t pointer_id, | |
590 uint32_t chosen_gesture_id, | |
591 const std::set<uint32_t>& possible_gesture_ids, | |
592 const std::set<uint32_t>& canceled_gesture_ids) { | |
593 // TODO(sky): caller should validate ids and make sure possible contains | |
594 // canceled and chosen. | |
595 DCHECK(!canceled_gesture_ids.count(kInvalidGestureId)); | |
596 DCHECK(!possible_gesture_ids.count(kInvalidGestureId)); | |
597 DCHECK(chosen_gesture_id == kInvalidGestureId || | |
598 possible_gesture_ids.count(chosen_gesture_id)); | |
599 DCHECK(chosen_gesture_id == kInvalidGestureId || | |
600 !canceled_gesture_ids.count(chosen_gesture_id)); | |
601 ScheduledDeleteProcessor delete_processor(this); | |
602 Pointer* pointer = GetPointerById(pointer_id); | |
603 current_change_.reset(new ChangeMap); | |
604 if (pointer) { | |
605 pointer->SetGestures(view, chosen_gesture_id, possible_gesture_ids, | |
606 canceled_gesture_ids); | |
607 } | |
608 return current_change_.Pass(); | |
609 } | |
610 | |
611 GestureManager::Pointer* GestureManager::GetPointerById(int32_t pointer_id) { | |
612 for (Pointer* pointer : active_pointers_) { | |
613 if (pointer->pointer_id() == pointer_id) | |
614 return pointer; | |
615 } | |
616 return nullptr; | |
617 } | |
618 | |
619 void GestureManager::PointerHasNoGestures(Pointer* pointer) { | |
620 auto iter = | |
621 std::find(active_pointers_.begin(), active_pointers_.end(), pointer); | |
622 CHECK(iter != active_pointers_.end()); | |
623 active_pointers_.erase(iter); | |
624 } | |
625 | |
626 GestureManager::Gesture* GestureManager::GetGesture(const ServerView* view, | |
627 uint32_t gesture_id) { | |
628 GestureAndConnectionId gesture_and_connection_id = | |
629 MakeGestureAndConnectionId(view, gesture_id); | |
630 Gesture* gesture = gesture_map_[gesture_and_connection_id]; | |
631 if (!gesture) { | |
632 gesture = new Gesture(gesture_id); | |
633 gesture_map_[gesture_and_connection_id] = gesture; | |
634 } | |
635 return gesture; | |
636 } | |
637 | |
638 void GestureManager::AttachGesture(Gesture* gesture, | |
639 Pointer* pointer, | |
640 const ServerView* view) { | |
641 gesture->Attach(pointer, view); | |
642 } | |
643 | |
644 void GestureManager::DetachGesture(Gesture* gesture, | |
645 Pointer* pointer, | |
646 const ServerView* view) { | |
647 gesture->Detach(pointer, view); | |
648 if (gesture->pointers_and_views().empty()) { | |
649 gesture_map_.erase(MakeGestureAndConnectionId(view, gesture->id())); | |
650 delete gesture; | |
651 } | |
652 } | |
653 | |
654 void GestureManager::CancelGesture(Gesture* gesture, | |
655 Pointer* pointer, | |
656 const ServerView* view) { | |
657 if (gesture->state() == Gesture::STATE_CANCELED) | |
658 return; | |
659 | |
660 gesture->set_state(Gesture::STATE_CANCELED); | |
661 for (auto& pointer_and_view : gesture->pointers_and_views()) { | |
662 (*current_change_)[pointer_and_view.view].canceled_gestures.insert( | |
663 gesture->id()); | |
664 if (pointer_and_view.pointer != pointer) | |
665 pointer_and_view.pointer->GestureCanceled(gesture); | |
666 } | |
667 } | |
668 | |
669 void GestureManager::ChooseGesture(Gesture* gesture, | |
670 Pointer* pointer, | |
671 const ServerView* view) { | |
672 if (gesture->state() == Gesture::STATE_CHOSEN) { | |
673 // This happens when |pointer| is supplied a gesture that is already | |
674 // chosen. | |
675 DCHECK((*current_change_)[view].chosen_gesture == kInvalidGestureId || | |
676 (*current_change_)[view].chosen_gesture == gesture->id()); | |
677 (*current_change_)[view].chosen_gesture = gesture->id(); | |
678 pointer->GestureChosen(gesture, view); | |
679 } else { | |
680 gesture->set_state(Gesture::STATE_CHOSEN); | |
681 for (auto& pointer_and_view : gesture->pointers_and_views()) { | |
682 DCHECK((*current_change_)[pointer_and_view.view].chosen_gesture == | |
683 kInvalidGestureId || | |
684 (*current_change_)[pointer_and_view.view].chosen_gesture == | |
685 gesture->id()); | |
686 (*current_change_)[pointer_and_view.view].chosen_gesture = gesture->id(); | |
687 pointer_and_view.pointer->GestureChosen(gesture, view); | |
688 } | |
689 } | |
690 } | |
691 | |
692 void GestureManager::ScheduleDelete(Pointer* pointer) { | |
693 auto iter = | |
694 std::find(active_pointers_.begin(), active_pointers_.end(), pointer); | |
695 if (iter != active_pointers_.end()) { | |
696 active_pointers_.weak_erase(iter); | |
697 pointers_to_delete_.push_back(pointer); | |
698 } | |
699 } | |
700 | |
701 } // namespace view_manager | |
OLD | NEW |