| 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 "services/view_manager/gesture_manager.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "mojo/services/input_events/interfaces/input_events.mojom.h" |
| 10 #include "mojo/services/view_manager/cpp/keys.h" |
| 11 #include "services/view_manager/gesture_manager_delegate.h" |
| 12 #include "services/view_manager/server_view.h" |
| 13 #include "services/view_manager/view_coordinate_conversions.h" |
| 14 #include "services/view_manager/view_locator.h" |
| 15 #include "ui/gfx/geometry/point_f.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; |
| 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::EventType::POINTER_UP || |
| 486 current_event_->action == mojo::EventType::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::EventType::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::EventType::POINTER_CANCEL: |
| 570 case mojo::EventType::POINTER_MOVE: |
| 571 case mojo::EventType::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 |