| 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/views/widget/root_view.h" | 5 #include "ui/views/widget/root_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "ui/base/accessibility/accessible_view_state.h" | 11 #include "ui/base/accessibility/accessible_view_state.h" |
| 12 #include "ui/base/dragdrop/drag_drop_types.h" | 12 #include "ui/base/dragdrop/drag_drop_types.h" |
| 13 #include "ui/base/keycodes/keyboard_codes.h" | 13 #include "ui/base/keycodes/keyboard_codes.h" |
| 14 #include "ui/gfx/canvas_skia.h" | 14 #include "ui/gfx/canvas_skia.h" |
| 15 #include "ui/gfx/compositor/layer.h" | 15 #include "ui/gfx/compositor/layer.h" |
| 16 #include "ui/views/focus/view_storage.h" | 16 #include "ui/views/focus/view_storage.h" |
| 17 #include "ui/views/layout/fill_layout.h" | 17 #include "ui/views/layout/fill_layout.h" |
| 18 #include "ui/views/touchui/gesture_manager.h" | 18 #include "ui/views/touchui/gesture_manager.h" |
| 19 #include "ui/views/touchui/gesture_recognizer.h" |
| 19 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
| 20 | 21 |
| 21 namespace views { | 22 namespace views { |
| 22 namespace internal { | 23 namespace internal { |
| 23 | 24 |
| 24 // static | 25 // static |
| 25 const char RootView::kViewClassName[] = "views/RootView"; | 26 const char RootView::kViewClassName[] = "views/RootView"; |
| 26 | 27 |
| 27 //////////////////////////////////////////////////////////////////////////////// | 28 //////////////////////////////////////////////////////////////////////////////// |
| 28 // RootView, public: | 29 // RootView, public: |
| 29 | 30 |
| 30 // Creation and lifetime ------------------------------------------------------- | 31 // Creation and lifetime ------------------------------------------------------- |
| 31 | 32 |
| 32 RootView::RootView(Widget* widget) | 33 RootView::RootView(Widget* widget) |
| 33 : widget_(widget), | 34 : widget_(widget), |
| 34 mouse_pressed_handler_(NULL), | 35 mouse_pressed_handler_(NULL), |
| 35 mouse_move_handler_(NULL), | 36 mouse_move_handler_(NULL), |
| 36 last_click_handler_(NULL), | 37 last_click_handler_(NULL), |
| 37 explicit_mouse_handler_(false), | 38 explicit_mouse_handler_(false), |
| 38 last_mouse_event_flags_(0), | 39 last_mouse_event_flags_(0), |
| 39 last_mouse_event_x_(-1), | 40 last_mouse_event_x_(-1), |
| 40 last_mouse_event_y_(-1), | 41 last_mouse_event_y_(-1), |
| 41 gesture_manager_(GestureManager::GetInstance()), | 42 gesture_manager_(GestureManager::GetInstance()), |
| 42 touch_pressed_handler_(NULL), | 43 touch_pressed_handler_(NULL), |
| 44 gesture_recognizer_(GestureRecognizer::GetInstance()), |
| 45 gesture_handling_view_(NULL), |
| 43 ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)), | 46 ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)), |
| 44 focus_traversable_parent_(NULL), | 47 focus_traversable_parent_(NULL), |
| 45 focus_traversable_parent_view_(NULL) { | 48 focus_traversable_parent_view_(NULL) { |
| 46 } | 49 } |
| 47 | 50 |
| 48 RootView::~RootView() { | 51 RootView::~RootView() { |
| 49 // If we have children remove them explicitly so to make sure a remove | 52 // If we have children remove them explicitly so to make sure a remove |
| 50 // notification is sent for each one of them. | 53 // notification is sent for each one of them. |
| 51 if (has_children()) | 54 if (has_children()) |
| 52 RemoveAllChildViews(true); | 55 RemoveAllChildViews(true); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 TouchEvent e(event, this); | 333 TouchEvent e(event, this); |
| 331 | 334 |
| 332 // If touch_pressed_handler_ is non null, we are currently processing | 335 // If touch_pressed_handler_ is non null, we are currently processing |
| 333 // a touch down on the screen situation. In that case we send the | 336 // a touch down on the screen situation. In that case we send the |
| 334 // event to touch_pressed_handler_ | 337 // event to touch_pressed_handler_ |
| 335 ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; | 338 ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; |
| 336 | 339 |
| 337 if (touch_pressed_handler_) { | 340 if (touch_pressed_handler_) { |
| 338 TouchEvent touch_event(e, this, touch_pressed_handler_); | 341 TouchEvent touch_event(e, this, touch_pressed_handler_); |
| 339 status = touch_pressed_handler_->ProcessTouchEvent(touch_event); | 342 status = touch_pressed_handler_->ProcessTouchEvent(touch_event); |
| 340 if (gesture_manager_->ProcessTouchEventForGesture(e, this, status)) | 343 if (DoGestureProcessing(e, status)) |
| 341 status = ui::TOUCH_STATUS_SYNTH_MOUSE; | 344 status = ui::TOUCH_STATUS_SYNTH_MOUSE; |
| 342 if (status == ui::TOUCH_STATUS_END) | 345 if (status == ui::TOUCH_STATUS_END) |
| 343 touch_pressed_handler_ = NULL; | 346 touch_pressed_handler_ = NULL; |
| 344 return status; | 347 return status; |
| 345 } | 348 } |
| 346 | 349 |
| 347 // Walk up the tree until we find a view that wants the touch event. | 350 // Walk up the tree until we find a view that wants the touch event. |
| 348 for (touch_pressed_handler_ = GetEventHandlerForPoint(e.location()); | 351 for (touch_pressed_handler_ = GetEventHandlerForPoint(e.location()); |
| 349 touch_pressed_handler_ && (touch_pressed_handler_ != this); | 352 touch_pressed_handler_ && (touch_pressed_handler_ != this); |
| 350 touch_pressed_handler_ = touch_pressed_handler_->parent()) { | 353 touch_pressed_handler_ = touch_pressed_handler_->parent()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 369 // the touch event. | 372 // the touch event. |
| 370 if (status == ui::TOUCH_STATUS_UNKNOWN) | 373 if (status == ui::TOUCH_STATUS_UNKNOWN) |
| 371 continue; | 374 continue; |
| 372 | 375 |
| 373 // If the touch didn't initiate a touch-sequence, then reset the touch event | 376 // If the touch didn't initiate a touch-sequence, then reset the touch event |
| 374 // handler. Otherwise, leave it set so that subsequent touch events are | 377 // handler. Otherwise, leave it set so that subsequent touch events are |
| 375 // dispatched to the same handler. | 378 // dispatched to the same handler. |
| 376 if (status != ui::TOUCH_STATUS_START) | 379 if (status != ui::TOUCH_STATUS_START) |
| 377 touch_pressed_handler_ = NULL; | 380 touch_pressed_handler_ = NULL; |
| 378 | 381 |
| 379 if (gesture_manager_->ProcessTouchEventForGesture(e, this, status)) | 382 if (DoGestureProcessing(e, status)) |
| 380 status = ui::TOUCH_STATUS_SYNTH_MOUSE; | 383 status = ui::TOUCH_STATUS_SYNTH_MOUSE; |
| 381 return status; | 384 return status; |
| 382 } | 385 } |
| 383 | 386 |
| 384 // Reset touch_pressed_handler_ to indicate that no processing is occurring. | 387 // Reset touch_pressed_handler_ to indicate that no processing is occurring. |
| 385 touch_pressed_handler_ = NULL; | 388 touch_pressed_handler_ = NULL; |
| 386 | 389 |
| 387 // Give the touch event to the gesture manager. | 390 // Give the touch event to the gesture manager. |
| 388 if (gesture_manager_->ProcessTouchEventForGesture(e, this, status)) | 391 if (gesture_manager_->ProcessTouchEventForGesture(e, this, status)) |
| 389 status = ui::TOUCH_STATUS_SYNTH_MOUSE; | 392 status = ui::TOUCH_STATUS_SYNTH_MOUSE; |
| 390 return status; | 393 return status; |
| 391 } | 394 } |
| 392 | 395 |
| 396 ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) { |
| 397 GestureEvent e(event, this); |
| 398 ui::GestureStatus status = ui::GESTURE_STATUS_UNKNOWN; |
| 399 |
| 400 // Walk up the tree until we find a view that wants the gesture event. |
| 401 for (gesture_handling_view_ = GetEventHandlerForPoint(e.location()); |
| 402 gesture_handling_view_ && (gesture_handling_view_ != this); |
| 403 gesture_handling_view_ = gesture_handling_view_->parent()) { |
| 404 if (!gesture_handling_view_->enabled()) { |
| 405 // Disabled views eat events but are treated as not handled by the |
| 406 // the GestureManager. |
| 407 return ui::GESTURE_STATUS_UNKNOWN; |
| 408 } |
| 409 |
| 410 // See if this view wants to handle the Gesture. |
| 411 GestureEvent gesture_event(e, this, gesture_handling_view_); |
| 412 status = gesture_handling_view_->ProcessGestureEvent(gesture_event); |
| 413 |
| 414 // The view could have removed itself from the tree when handling |
| 415 // OnGestureEvent(). So handle as per OnMousePressed. NB: we |
| 416 // assume that the RootView itself cannot be so removed. |
| 417 if (!gesture_handling_view_) return ui::GESTURE_STATUS_UNKNOWN; |
| 418 |
| 419 // The gesture event wasn't processed. Go up the view hierarchy and |
| 420 // dispatch the gesture event. |
| 421 if (status == ui::GESTURE_STATUS_UNKNOWN) { |
| 422 continue; |
| 423 } else if (status == ui::GESTURE_STATUS_CONSUMED) { |
| 424 return status; |
| 425 } else { |
| 426 return ui::GESTURE_STATUS_UNKNOWN; |
| 427 } |
| 428 } |
| 429 return status; |
| 430 } |
| 431 |
| 393 void RootView::SetMouseHandler(View *new_mh) { | 432 void RootView::SetMouseHandler(View *new_mh) { |
| 394 // If we're clearing the mouse handler, clear explicit_mouse_handler_ as well. | 433 // If we're clearing the mouse handler, clear explicit_mouse_handler_ as well. |
| 395 explicit_mouse_handler_ = (new_mh != NULL); | 434 explicit_mouse_handler_ = (new_mh != NULL); |
| 396 mouse_pressed_handler_ = new_mh; | 435 mouse_pressed_handler_ = new_mh; |
| 397 drag_info_.Reset(); | 436 drag_info_.Reset(); |
| 398 } | 437 } |
| 399 | 438 |
| 400 void RootView::GetAccessibleState(ui::AccessibleViewState* state) { | 439 void RootView::GetAccessibleState(ui::AccessibleViewState* state) { |
| 401 state->role = ui::AccessibilityTypes::ROLE_APPLICATION; | 440 state->role = ui::AccessibilityTypes::ROLE_APPLICATION; |
| 402 } | 441 } |
| 403 | 442 |
| 404 void RootView::ReorderChildLayers(ui::Layer* parent_layer) { | 443 void RootView::ReorderChildLayers(ui::Layer* parent_layer) { |
| 405 View::ReorderChildLayers(parent_layer); | 444 View::ReorderChildLayers(parent_layer); |
| 406 } | 445 } |
| 407 | 446 |
| 408 //////////////////////////////////////////////////////////////////////////////// | 447 //////////////////////////////////////////////////////////////////////////////// |
| 409 // RootView, protected: | 448 // RootView, protected: |
| 410 | 449 |
| 411 void RootView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { | 450 void RootView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { |
| 412 widget_->ViewHierarchyChanged(is_add, parent, child); | 451 widget_->ViewHierarchyChanged(is_add, parent, child); |
| 413 | 452 |
| 414 if (!is_add) { | 453 if (!is_add) { |
| 415 if (!explicit_mouse_handler_ && mouse_pressed_handler_ == child) | 454 if (!explicit_mouse_handler_ && mouse_pressed_handler_ == child) |
| 416 mouse_pressed_handler_ = NULL; | 455 mouse_pressed_handler_ = NULL; |
| 417 if (mouse_move_handler_ == child) | 456 if (mouse_move_handler_ == child) |
| 418 mouse_move_handler_ = NULL; | 457 mouse_move_handler_ = NULL; |
| 419 if (touch_pressed_handler_ == child) | 458 if (touch_pressed_handler_ == child) |
| 420 touch_pressed_handler_ = NULL; | 459 touch_pressed_handler_ = NULL; |
| 460 if (gesture_handling_view_ == child) |
| 461 gesture_handling_view_ = NULL; |
| 421 } | 462 } |
| 422 } | 463 } |
| 423 | 464 |
| 424 void RootView::OnPaint(gfx::Canvas* canvas) { | 465 void RootView::OnPaint(gfx::Canvas* canvas) { |
| 425 if (!layer() || !layer()->fills_bounds_opaquely()) | 466 if (!layer() || !layer()->fills_bounds_opaquely()) |
| 426 canvas->GetSkCanvas()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); | 467 canvas->GetSkCanvas()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); |
| 427 | 468 |
| 428 // TODO (pkotwicz): Remove this once we switch over to Aura desktop. | 469 // TODO (pkotwicz): Remove this once we switch over to Aura desktop. |
| 429 // This is needed so that we can set the background behind the RWHV when the | 470 // This is needed so that we can set the background behind the RWHV when the |
| 430 // RWHV is not visible. Not needed once there is a view between the RootView | 471 // RWHV is not visible. Not needed once there is a view between the RootView |
| (...skipping 19 matching lines...) Expand all Loading... |
| 450 widget_->SetCursor(v->GetCursor(MouseEvent(event, this, v))); | 491 widget_->SetCursor(v->GetCursor(MouseEvent(event, this, v))); |
| 451 } | 492 } |
| 452 } | 493 } |
| 453 | 494 |
| 454 void RootView::SetMouseLocationAndFlags(const MouseEvent& event) { | 495 void RootView::SetMouseLocationAndFlags(const MouseEvent& event) { |
| 455 last_mouse_event_flags_ = event.flags(); | 496 last_mouse_event_flags_ = event.flags(); |
| 456 last_mouse_event_x_ = event.x(); | 497 last_mouse_event_x_ = event.x(); |
| 457 last_mouse_event_y_ = event.y(); | 498 last_mouse_event_y_ = event.y(); |
| 458 } | 499 } |
| 459 | 500 |
| 501 bool RootView::DoGestureProcessing(const TouchEvent& event, |
| 502 ui::TouchStatus status) { |
| 503 if (status != ui::TOUCH_STATUS_UNKNOWN) |
| 504 return false; // The event was consumed by a touch sequence. |
| 505 |
| 506 // Get the GestureEvent list processed from GestureRecognizer. |
| 507 scoped_ptr<GestureRecognizer::Gestures> gestures; |
| 508 gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(event, |
| 509 status)); |
| 510 bool synthetic = true; |
| 511 for (unsigned int i = 0; i < gestures->size(); i++) { |
| 512 GestureEvent* event = gestures->at(i).get(); |
| 513 GestureEvent e(*event, this); |
| 514 if (OnGestureEvent(e) == ui::GESTURE_STATUS_CONSUMED) { |
| 515 // All gesture events should be consumed. |
| 516 synthetic = false; |
| 517 } else { |
| 518 synthetic = true; |
| 519 break; |
| 520 } |
| 521 } |
| 522 if (synthetic) { |
| 523 // TODO(Gajen): This should be removed in future once all views are capable |
| 524 // of handling OnGestureEvent. |
| 525 return gesture_manager_->ProcessTouchEventForGesture(event, this, |
| 526 status); |
| 527 } |
| 528 return synthetic; |
| 529 } |
| 530 |
| 460 } // namespace internal | 531 } // namespace internal |
| 461 } // namespace views | 532 } // namespace views |
| OLD | NEW |