Home | History | Annotate | Download | only in views
      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
      3 // found in the LICENSE file.
      4 
      5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first.
      6 
      7 #include "ui/views/view.h"
      8 
      9 #include <algorithm>
     10 #include <cmath>
     11 
     12 #include "base/debug/trace_event.h"
     13 #include "base/logging.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/strings/stringprintf.h"
     17 #include "base/strings/utf_string_conversions.h"
     18 #include "third_party/skia/include/core/SkRect.h"
     19 #include "ui/accessibility/ax_enums.h"
     20 #include "ui/base/cursor/cursor.h"
     21 #include "ui/base/dragdrop/drag_drop_types.h"
     22 #include "ui/compositor/compositor.h"
     23 #include "ui/compositor/layer.h"
     24 #include "ui/compositor/layer_animator.h"
     25 #include "ui/events/event_target_iterator.h"
     26 #include "ui/gfx/canvas.h"
     27 #include "ui/gfx/interpolated_transform.h"
     28 #include "ui/gfx/path.h"
     29 #include "ui/gfx/point3_f.h"
     30 #include "ui/gfx/point_conversions.h"
     31 #include "ui/gfx/rect_conversions.h"
     32 #include "ui/gfx/scoped_canvas.h"
     33 #include "ui/gfx/screen.h"
     34 #include "ui/gfx/skia_util.h"
     35 #include "ui/gfx/transform.h"
     36 #include "ui/native_theme/native_theme.h"
     37 #include "ui/views/accessibility/native_view_accessibility.h"
     38 #include "ui/views/background.h"
     39 #include "ui/views/border.h"
     40 #include "ui/views/context_menu_controller.h"
     41 #include "ui/views/drag_controller.h"
     42 #include "ui/views/focus/view_storage.h"
     43 #include "ui/views/layout/layout_manager.h"
     44 #include "ui/views/rect_based_targeting_utils.h"
     45 #include "ui/views/views_delegate.h"
     46 #include "ui/views/widget/native_widget_private.h"
     47 #include "ui/views/widget/root_view.h"
     48 #include "ui/views/widget/tooltip_manager.h"
     49 #include "ui/views/widget/widget.h"
     50 
     51 #if defined(OS_WIN)
     52 #include "base/win/scoped_gdi_object.h"
     53 #endif
     54 
     55 namespace {
     56 
     57 #if defined(OS_WIN)
     58 const bool kContextMenuOnMousePress = false;
     59 #else
     60 const bool kContextMenuOnMousePress = true;
     61 #endif
     62 
     63 // The minimum percentage of a view's area that needs to be covered by a rect
     64 // representing a touch region in order for that view to be considered by the
     65 // rect-based targeting algorithm.
     66 static const float kRectTargetOverlap = 0.6f;
     67 
     68 // Default horizontal drag threshold in pixels.
     69 // Same as what gtk uses.
     70 const int kDefaultHorizontalDragThreshold = 8;
     71 
     72 // Default vertical drag threshold in pixels.
     73 // Same as what gtk uses.
     74 const int kDefaultVerticalDragThreshold = 8;
     75 
     76 // Returns the top view in |view|'s hierarchy.
     77 const views::View* GetHierarchyRoot(const views::View* view) {
     78   const views::View* root = view;
     79   while (root && root->parent())
     80     root = root->parent();
     81   return root;
     82 }
     83 
     84 }  // namespace
     85 
     86 namespace views {
     87 
     88 namespace internal {
     89 
     90 }  // namespace internal
     91 
     92 // static
     93 ViewsDelegate* ViewsDelegate::views_delegate = NULL;
     94 
     95 // static
     96 const char View::kViewClassName[] = "View";
     97 
     98 ////////////////////////////////////////////////////////////////////////////////
     99 // View, public:
    100 
    101 // Creation and lifetime -------------------------------------------------------
    102 
    103 View::View()
    104     : owned_by_client_(false),
    105       id_(0),
    106       group_(-1),
    107       parent_(NULL),
    108       visible_(true),
    109       enabled_(true),
    110       notify_enter_exit_on_child_(false),
    111       registered_for_visible_bounds_notification_(false),
    112       root_bounds_dirty_(true),
    113       clip_insets_(0, 0, 0, 0),
    114       needs_layout_(true),
    115       flip_canvas_on_paint_for_rtl_ui_(false),
    116       paint_to_layer_(false),
    117       accelerator_focus_manager_(NULL),
    118       registered_accelerator_count_(0),
    119       next_focusable_view_(NULL),
    120       previous_focusable_view_(NULL),
    121       focusable_(false),
    122       accessibility_focusable_(false),
    123       context_menu_controller_(NULL),
    124       drag_controller_(NULL),
    125       native_view_accessibility_(NULL) {
    126 }
    127 
    128 View::~View() {
    129   if (parent_)
    130     parent_->RemoveChildView(this);
    131 
    132   ViewStorage::GetInstance()->ViewRemoved(this);
    133 
    134   for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
    135     (*i)->parent_ = NULL;
    136     if (!(*i)->owned_by_client_)
    137       delete *i;
    138   }
    139 
    140   // Release ownership of the native accessibility object, but it's
    141   // reference-counted on some platforms, so it may not be deleted right away.
    142   if (native_view_accessibility_)
    143     native_view_accessibility_->Destroy();
    144 }
    145 
    146 // Tree operations -------------------------------------------------------------
    147 
    148 const Widget* View::GetWidget() const {
    149   // The root view holds a reference to this view hierarchy's Widget.
    150   return parent_ ? parent_->GetWidget() : NULL;
    151 }
    152 
    153 Widget* View::GetWidget() {
    154   return const_cast<Widget*>(const_cast<const View*>(this)->GetWidget());
    155 }
    156 
    157 void View::AddChildView(View* view) {
    158   if (view->parent_ == this)
    159     return;
    160   AddChildViewAt(view, child_count());
    161 }
    162 
    163 void View::AddChildViewAt(View* view, int index) {
    164   CHECK_NE(view, this) << "You cannot add a view as its own child";
    165   DCHECK_GE(index, 0);
    166   DCHECK_LE(index, child_count());
    167 
    168   // If |view| has a parent, remove it from its parent.
    169   View* parent = view->parent_;
    170   ui::NativeTheme* old_theme = NULL;
    171   if (parent) {
    172     old_theme = view->GetNativeTheme();
    173     if (parent == this) {
    174       ReorderChildView(view, index);
    175       return;
    176     }
    177     parent->DoRemoveChildView(view, true, true, false, this);
    178   }
    179 
    180   // Sets the prev/next focus views.
    181   InitFocusSiblings(view, index);
    182 
    183   // Let's insert the view.
    184   view->parent_ = this;
    185   children_.insert(children_.begin() + index, view);
    186 
    187   // Instruct the view to recompute its root bounds on next Paint().
    188   view->SetRootBoundsDirty(true);
    189 
    190   views::Widget* widget = GetWidget();
    191   if (widget) {
    192     const ui::NativeTheme* new_theme = view->GetNativeTheme();
    193     if (new_theme != old_theme)
    194       view->PropagateNativeThemeChanged(new_theme);
    195   }
    196 
    197   ViewHierarchyChangedDetails details(true, this, view, parent);
    198 
    199   for (View* v = this; v; v = v->parent_)
    200     v->ViewHierarchyChangedImpl(false, details);
    201 
    202   view->PropagateAddNotifications(details);
    203   UpdateTooltip();
    204   if (widget) {
    205     RegisterChildrenForVisibleBoundsNotification(view);
    206     if (view->visible())
    207       view->SchedulePaint();
    208   }
    209 
    210   if (layout_manager_.get())
    211     layout_manager_->ViewAdded(this, view);
    212 
    213   ReorderLayers();
    214 
    215   // Make sure the visibility of the child layers are correct.
    216   // If any of the parent View is hidden, then the layers of the subtree
    217   // rooted at |this| should be hidden. Otherwise, all the child layers should
    218   // inherit the visibility of the owner View.
    219   UpdateLayerVisibility();
    220 }
    221 
    222 void View::ReorderChildView(View* view, int index) {
    223   DCHECK_EQ(view->parent_, this);
    224   if (index < 0)
    225     index = child_count() - 1;
    226   else if (index >= child_count())
    227     return;
    228   if (children_[index] == view)
    229     return;
    230 
    231   const Views::iterator i(std::find(children_.begin(), children_.end(), view));
    232   DCHECK(i != children_.end());
    233   children_.erase(i);
    234 
    235   // Unlink the view first
    236   View* next_focusable = view->next_focusable_view_;
    237   View* prev_focusable = view->previous_focusable_view_;
    238   if (prev_focusable)
    239     prev_focusable->next_focusable_view_ = next_focusable;
    240   if (next_focusable)
    241     next_focusable->previous_focusable_view_ = prev_focusable;
    242 
    243   // Add it in the specified index now.
    244   InitFocusSiblings(view, index);
    245   children_.insert(children_.begin() + index, view);
    246 
    247   ReorderLayers();
    248 }
    249 
    250 void View::RemoveChildView(View* view) {
    251   DoRemoveChildView(view, true, true, false, NULL);
    252 }
    253 
    254 void View::RemoveAllChildViews(bool delete_children) {
    255   while (!children_.empty())
    256     DoRemoveChildView(children_.front(), false, false, delete_children, NULL);
    257   UpdateTooltip();
    258 }
    259 
    260 bool View::Contains(const View* view) const {
    261   for (const View* v = view; v; v = v->parent_) {
    262     if (v == this)
    263       return true;
    264   }
    265   return false;
    266 }
    267 
    268 int View::GetIndexOf(const View* view) const {
    269   Views::const_iterator i(std::find(children_.begin(), children_.end(), view));
    270   return i != children_.end() ? static_cast<int>(i - children_.begin()) : -1;
    271 }
    272 
    273 // Size and disposition --------------------------------------------------------
    274 
    275 void View::SetBounds(int x, int y, int width, int height) {
    276   SetBoundsRect(gfx::Rect(x, y, std::max(0, width), std::max(0, height)));
    277 }
    278 
    279 void View::SetBoundsRect(const gfx::Rect& bounds) {
    280   if (bounds == bounds_) {
    281     if (needs_layout_) {
    282       needs_layout_ = false;
    283       Layout();
    284     }
    285     return;
    286   }
    287 
    288   if (visible_) {
    289     // Paint where the view is currently.
    290     SchedulePaintBoundsChanged(
    291         bounds_.size() == bounds.size() ? SCHEDULE_PAINT_SIZE_SAME :
    292         SCHEDULE_PAINT_SIZE_CHANGED);
    293   }
    294 
    295   gfx::Rect prev = bounds_;
    296   bounds_ = bounds;
    297   BoundsChanged(prev);
    298 }
    299 
    300 void View::SetSize(const gfx::Size& size) {
    301   SetBounds(x(), y(), size.width(), size.height());
    302 }
    303 
    304 void View::SetPosition(const gfx::Point& position) {
    305   SetBounds(position.x(), position.y(), width(), height());
    306 }
    307 
    308 void View::SetX(int x) {
    309   SetBounds(x, y(), width(), height());
    310 }
    311 
    312 void View::SetY(int y) {
    313   SetBounds(x(), y, width(), height());
    314 }
    315 
    316 gfx::Rect View::GetContentsBounds() const {
    317   gfx::Rect contents_bounds(GetLocalBounds());
    318   if (border_.get())
    319     contents_bounds.Inset(border_->GetInsets());
    320   return contents_bounds;
    321 }
    322 
    323 gfx::Rect View::GetLocalBounds() const {
    324   return gfx::Rect(size());
    325 }
    326 
    327 gfx::Rect View::GetLayerBoundsInPixel() const {
    328   return layer()->GetTargetBounds();
    329 }
    330 
    331 gfx::Insets View::GetInsets() const {
    332   return border_.get() ? border_->GetInsets() : gfx::Insets();
    333 }
    334 
    335 gfx::Rect View::GetVisibleBounds() const {
    336   if (!IsDrawn())
    337     return gfx::Rect();
    338   gfx::Rect vis_bounds(GetLocalBounds());
    339   gfx::Rect ancestor_bounds;
    340   const View* view = this;
    341   gfx::Transform transform;
    342 
    343   while (view != NULL && !vis_bounds.IsEmpty()) {
    344     transform.ConcatTransform(view->GetTransform());
    345     gfx::Transform translation;
    346     translation.Translate(static_cast<float>(view->GetMirroredX()),
    347                           static_cast<float>(view->y()));
    348     transform.ConcatTransform(translation);
    349 
    350     vis_bounds = view->ConvertRectToParent(vis_bounds);
    351     const View* ancestor = view->parent_;
    352     if (ancestor != NULL) {
    353       ancestor_bounds.SetRect(0, 0, ancestor->width(), ancestor->height());
    354       vis_bounds.Intersect(ancestor_bounds);
    355     } else if (!view->GetWidget()) {
    356       // If the view has no Widget, we're not visible. Return an empty rect.
    357       return gfx::Rect();
    358     }
    359     view = ancestor;
    360   }
    361   if (vis_bounds.IsEmpty())
    362     return vis_bounds;
    363   // Convert back to this views coordinate system.
    364   gfx::RectF views_vis_bounds(vis_bounds);
    365   transform.TransformRectReverse(&views_vis_bounds);
    366   // Partially visible pixels should be considered visible.
    367   return gfx::ToEnclosingRect(views_vis_bounds);
    368 }
    369 
    370 gfx::Rect View::GetBoundsInScreen() const {
    371   gfx::Point origin;
    372   View::ConvertPointToScreen(this, &origin);
    373   return gfx::Rect(origin, size());
    374 }
    375 
    376 gfx::Size View::GetPreferredSize() const {
    377   if (layout_manager_.get())
    378     return layout_manager_->GetPreferredSize(this);
    379   return gfx::Size();
    380 }
    381 
    382 int View::GetBaseline() const {
    383   return -1;
    384 }
    385 
    386 void View::SizeToPreferredSize() {
    387   gfx::Size prefsize = GetPreferredSize();
    388   if ((prefsize.width() != width()) || (prefsize.height() != height()))
    389     SetBounds(x(), y(), prefsize.width(), prefsize.height());
    390 }
    391 
    392 gfx::Size View::GetMinimumSize() const {
    393   return GetPreferredSize();
    394 }
    395 
    396 gfx::Size View::GetMaximumSize() const {
    397   return gfx::Size();
    398 }
    399 
    400 int View::GetHeightForWidth(int w) const {
    401   if (layout_manager_.get())
    402     return layout_manager_->GetPreferredHeightForWidth(this, w);
    403   return GetPreferredSize().height();
    404 }
    405 
    406 void View::SetVisible(bool visible) {
    407   if (visible != visible_) {
    408     // If the View is currently visible, schedule paint to refresh parent.
    409     // TODO(beng): not sure we should be doing this if we have a layer.
    410     if (visible_)
    411       SchedulePaint();
    412 
    413     visible_ = visible;
    414 
    415     // Notify the parent.
    416     if (parent_)
    417       parent_->ChildVisibilityChanged(this);
    418 
    419     // This notifies all sub-views recursively.
    420     PropagateVisibilityNotifications(this, visible_);
    421     UpdateLayerVisibility();
    422 
    423     // If we are newly visible, schedule paint.
    424     if (visible_)
    425       SchedulePaint();
    426   }
    427 }
    428 
    429 bool View::IsDrawn() const {
    430   return visible_ && parent_ ? parent_->IsDrawn() : false;
    431 }
    432 
    433 void View::SetEnabled(bool enabled) {
    434   if (enabled != enabled_) {
    435     enabled_ = enabled;
    436     OnEnabledChanged();
    437   }
    438 }
    439 
    440 void View::OnEnabledChanged() {
    441   SchedulePaint();
    442 }
    443 
    444 // Transformations -------------------------------------------------------------
    445 
    446 gfx::Transform View::GetTransform() const {
    447   return layer() ? layer()->transform() : gfx::Transform();
    448 }
    449 
    450 void View::SetTransform(const gfx::Transform& transform) {
    451   if (transform.IsIdentity()) {
    452     if (layer()) {
    453       layer()->SetTransform(transform);
    454       if (!paint_to_layer_)
    455         DestroyLayer();
    456     } else {
    457       // Nothing.
    458     }
    459   } else {
    460     if (!layer())
    461       CreateLayer();
    462     layer()->SetTransform(transform);
    463     layer()->ScheduleDraw();
    464   }
    465 }
    466 
    467 void View::SetPaintToLayer(bool paint_to_layer) {
    468   if (paint_to_layer_ == paint_to_layer)
    469     return;
    470 
    471   // If this is a change in state we will also need to update bounds trees.
    472   if (paint_to_layer) {
    473     // Gaining a layer means becoming a paint root. We must remove ourselves
    474     // from our old paint root, if we had one. Traverse up view tree to find old
    475     // paint root.
    476     View* old_paint_root = parent_;
    477     while (old_paint_root && !old_paint_root->IsPaintRoot())
    478       old_paint_root = old_paint_root->parent_;
    479 
    480     // Remove our and our children's bounds from the old tree. This will also
    481     // mark all of our bounds as dirty.
    482     if (old_paint_root && old_paint_root->bounds_tree_)
    483       RemoveRootBounds(old_paint_root->bounds_tree_.get());
    484 
    485   } else {
    486     // Losing a layer means we are no longer a paint root, so delete our
    487     // bounds tree and mark ourselves as dirty for future insertion into our
    488     // new paint root's bounds tree.
    489     bounds_tree_.reset();
    490     SetRootBoundsDirty(true);
    491   }
    492 
    493   paint_to_layer_ = paint_to_layer;
    494   if (paint_to_layer_ && !layer()) {
    495     CreateLayer();
    496   } else if (!paint_to_layer_ && layer()) {
    497     DestroyLayer();
    498   }
    499 }
    500 
    501 // RTL positioning -------------------------------------------------------------
    502 
    503 gfx::Rect View::GetMirroredBounds() const {
    504   gfx::Rect bounds(bounds_);
    505   bounds.set_x(GetMirroredX());
    506   return bounds;
    507 }
    508 
    509 gfx::Point View::GetMirroredPosition() const {
    510   return gfx::Point(GetMirroredX(), y());
    511 }
    512 
    513 int View::GetMirroredX() const {
    514   return parent_ ? parent_->GetMirroredXForRect(bounds_) : x();
    515 }
    516 
    517 int View::GetMirroredXForRect(const gfx::Rect& bounds) const {
    518   return base::i18n::IsRTL() ?
    519       (width() - bounds.x() - bounds.width()) : bounds.x();
    520 }
    521 
    522 int View::GetMirroredXInView(int x) const {
    523   return base::i18n::IsRTL() ? width() - x : x;
    524 }
    525 
    526 int View::GetMirroredXWithWidthInView(int x, int w) const {
    527   return base::i18n::IsRTL() ? width() - x - w : x;
    528 }
    529 
    530 // Layout ----------------------------------------------------------------------
    531 
    532 void View::Layout() {
    533   needs_layout_ = false;
    534 
    535   // If we have a layout manager, let it handle the layout for us.
    536   if (layout_manager_.get())
    537     layout_manager_->Layout(this);
    538 
    539   // Make sure to propagate the Layout() call to any children that haven't
    540   // received it yet through the layout manager and need to be laid out. This
    541   // is needed for the case when the child requires a layout but its bounds
    542   // weren't changed by the layout manager. If there is no layout manager, we
    543   // just propagate the Layout() call down the hierarchy, so whoever receives
    544   // the call can take appropriate action.
    545   for (int i = 0, count = child_count(); i < count; ++i) {
    546     View* child = child_at(i);
    547     if (child->needs_layout_ || !layout_manager_.get()) {
    548       child->needs_layout_ = false;
    549       child->Layout();
    550     }
    551   }
    552 }
    553 
    554 void View::InvalidateLayout() {
    555   // Always invalidate up. This is needed to handle the case of us already being
    556   // valid, but not our parent.
    557   needs_layout_ = true;
    558   if (parent_)
    559     parent_->InvalidateLayout();
    560 }
    561 
    562 LayoutManager* View::GetLayoutManager() const {
    563   return layout_manager_.get();
    564 }
    565 
    566 void View::SetLayoutManager(LayoutManager* layout_manager) {
    567   if (layout_manager_.get())
    568     layout_manager_->Uninstalled(this);
    569 
    570   layout_manager_.reset(layout_manager);
    571   if (layout_manager_.get())
    572     layout_manager_->Installed(this);
    573 }
    574 
    575 // Attributes ------------------------------------------------------------------
    576 
    577 const char* View::GetClassName() const {
    578   return kViewClassName;
    579 }
    580 
    581 const View* View::GetAncestorWithClassName(const std::string& name) const {
    582   for (const View* view = this; view; view = view->parent_) {
    583     if (!strcmp(view->GetClassName(), name.c_str()))
    584       return view;
    585   }
    586   return NULL;
    587 }
    588 
    589 View* View::GetAncestorWithClassName(const std::string& name) {
    590   return const_cast<View*>(const_cast<const View*>(this)->
    591       GetAncestorWithClassName(name));
    592 }
    593 
    594 const View* View::GetViewByID(int id) const {
    595   if (id == id_)
    596     return const_cast<View*>(this);
    597 
    598   for (int i = 0, count = child_count(); i < count; ++i) {
    599     const View* view = child_at(i)->GetViewByID(id);
    600     if (view)
    601       return view;
    602   }
    603   return NULL;
    604 }
    605 
    606 View* View::GetViewByID(int id) {
    607   return const_cast<View*>(const_cast<const View*>(this)->GetViewByID(id));
    608 }
    609 
    610 void View::SetGroup(int gid) {
    611   // Don't change the group id once it's set.
    612   DCHECK(group_ == -1 || group_ == gid);
    613   group_ = gid;
    614 }
    615 
    616 int View::GetGroup() const {
    617   return group_;
    618 }
    619 
    620 bool View::IsGroupFocusTraversable() const {
    621   return true;
    622 }
    623 
    624 void View::GetViewsInGroup(int group, Views* views) {
    625   if (group_ == group)
    626     views->push_back(this);
    627 
    628   for (int i = 0, count = child_count(); i < count; ++i)
    629     child_at(i)->GetViewsInGroup(group, views);
    630 }
    631 
    632 View* View::GetSelectedViewForGroup(int group) {
    633   Views views;
    634   GetWidget()->GetRootView()->GetViewsInGroup(group, &views);
    635   return views.empty() ? NULL : views[0];
    636 }
    637 
    638 // Coordinate conversion -------------------------------------------------------
    639 
    640 // static
    641 void View::ConvertPointToTarget(const View* source,
    642                                 const View* target,
    643                                 gfx::Point* point) {
    644   DCHECK(source);
    645   DCHECK(target);
    646   if (source == target)
    647     return;
    648 
    649   const View* root = GetHierarchyRoot(target);
    650   CHECK_EQ(GetHierarchyRoot(source), root);
    651 
    652   if (source != root)
    653     source->ConvertPointForAncestor(root, point);
    654 
    655   if (target != root)
    656     target->ConvertPointFromAncestor(root, point);
    657 }
    658 
    659 // static
    660 void View::ConvertRectToTarget(const View* source,
    661                                const View* target,
    662                                gfx::RectF* rect) {
    663   DCHECK(source);
    664   DCHECK(target);
    665   if (source == target)
    666     return;
    667 
    668   const View* root = GetHierarchyRoot(target);
    669   CHECK_EQ(GetHierarchyRoot(source), root);
    670 
    671   if (source != root)
    672     source->ConvertRectForAncestor(root, rect);
    673 
    674   if (target != root)
    675     target->ConvertRectFromAncestor(root, rect);
    676 }
    677 
    678 // static
    679 void View::ConvertPointToWidget(const View* src, gfx::Point* p) {
    680   DCHECK(src);
    681   DCHECK(p);
    682 
    683   src->ConvertPointForAncestor(NULL, p);
    684 }
    685 
    686 // static
    687 void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) {
    688   DCHECK(dest);
    689   DCHECK(p);
    690 
    691   dest->ConvertPointFromAncestor(NULL, p);
    692 }
    693 
    694 // static
    695 void View::ConvertPointToScreen(const View* src, gfx::Point* p) {
    696   DCHECK(src);
    697   DCHECK(p);
    698 
    699   // If the view is not connected to a tree, there's nothing we can do.
    700   const Widget* widget = src->GetWidget();
    701   if (widget) {
    702     ConvertPointToWidget(src, p);
    703     *p += widget->GetClientAreaBoundsInScreen().OffsetFromOrigin();
    704   }
    705 }
    706 
    707 // static
    708 void View::ConvertPointFromScreen(const View* dst, gfx::Point* p) {
    709   DCHECK(dst);
    710   DCHECK(p);
    711 
    712   const views::Widget* widget = dst->GetWidget();
    713   if (!widget)
    714     return;
    715   *p -= widget->GetClientAreaBoundsInScreen().OffsetFromOrigin();
    716   views::View::ConvertPointFromWidget(dst, p);
    717 }
    718 
    719 gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
    720   gfx::RectF x_rect = rect;
    721   GetTransform().TransformRect(&x_rect);
    722   x_rect.Offset(GetMirroredPosition().OffsetFromOrigin());
    723   // Pixels we partially occupy in the parent should be included.
    724   return gfx::ToEnclosingRect(x_rect);
    725 }
    726 
    727 gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const {
    728   gfx::Rect x_rect = rect;
    729   for (const View* v = this; v; v = v->parent_)
    730     x_rect = v->ConvertRectToParent(x_rect);
    731   return x_rect;
    732 }
    733 
    734 // Painting --------------------------------------------------------------------
    735 
    736 void View::SchedulePaint() {
    737   SchedulePaintInRect(GetLocalBounds());
    738 }
    739 
    740 void View::SchedulePaintInRect(const gfx::Rect& rect) {
    741   if (!visible_)
    742     return;
    743 
    744   if (layer()) {
    745     layer()->SchedulePaint(rect);
    746   } else if (parent_) {
    747     // Translate the requested paint rect to the parent's coordinate system
    748     // then pass this notification up to the parent.
    749     parent_->SchedulePaintInRect(ConvertRectToParent(rect));
    750   }
    751 }
    752 
    753 void View::Paint(gfx::Canvas* canvas, const CullSet& cull_set) {
    754   // The cull_set may allow us to skip painting without canvas construction or
    755   // even canvas rect intersection.
    756   if (cull_set.ShouldPaint(this)) {
    757     TRACE_EVENT1("views", "View::Paint", "class", GetClassName());
    758 
    759     gfx::ScopedCanvas scoped_canvas(canvas);
    760 
    761     // Paint this View and its children, setting the clip rect to the bounds
    762     // of this View and translating the origin to the local bounds' top left
    763     // point.
    764     //
    765     // Note that the X (or left) position we pass to ClipRectInt takes into
    766     // consideration whether or not the view uses a right-to-left layout so that
    767     // we paint our view in its mirrored position if need be.
    768     gfx::Rect clip_rect = bounds();
    769     clip_rect.Inset(clip_insets_);
    770     if (parent_)
    771       clip_rect.set_x(parent_->GetMirroredXForRect(clip_rect));
    772     canvas->ClipRect(clip_rect);
    773     if (canvas->IsClipEmpty())
    774       return;
    775 
    776     // Non-empty clip, translate the graphics such that 0,0 corresponds to where
    777     // this view is located (related to its parent).
    778     canvas->Translate(GetMirroredPosition().OffsetFromOrigin());
    779     canvas->Transform(GetTransform());
    780 
    781     // If we are a paint root, we need to construct our own CullSet object for
    782     // propagation to our children.
    783     if (IsPaintRoot()) {
    784       if (!bounds_tree_)
    785         bounds_tree_.reset(new BoundsTree(2, 5));
    786 
    787       // Recompute our bounds tree as needed.
    788       UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d());
    789 
    790       // Grab the clip rect from the supplied canvas to use as the query rect.
    791       gfx::Rect canvas_bounds;
    792       if (!canvas->GetClipBounds(&canvas_bounds)) {
    793         NOTREACHED() << "Failed to get clip bounds from the canvas!";
    794         return;
    795       }
    796 
    797       // Now query our bounds_tree_ for a set of damaged views that intersect
    798       // our canvas bounds.
    799       scoped_ptr<base::hash_set<intptr_t> > damaged_views(
    800           new base::hash_set<intptr_t>());
    801       bounds_tree_->AppendIntersectingRecords(
    802           canvas_bounds, damaged_views.get());
    803       // Construct a CullSet to wrap the damaged views set, it will delete it
    804       // for us on scope exit.
    805       CullSet paint_root_cull_set(damaged_views.Pass());
    806       // Paint all descendents using our new cull set.
    807       PaintCommon(canvas, paint_root_cull_set);
    808     } else {
    809       // Not a paint root, so we can proceed as normal.
    810       PaintCommon(canvas, cull_set);
    811     }
    812   }
    813 }
    814 
    815 void View::set_background(Background* b) {
    816   background_.reset(b);
    817 }
    818 
    819 void View::SetBorder(scoped_ptr<Border> b) { border_ = b.Pass(); }
    820 
    821 ui::ThemeProvider* View::GetThemeProvider() const {
    822   const Widget* widget = GetWidget();
    823   return widget ? widget->GetThemeProvider() : NULL;
    824 }
    825 
    826 const ui::NativeTheme* View::GetNativeTheme() const {
    827   const Widget* widget = GetWidget();
    828   return widget ? widget->GetNativeTheme() : ui::NativeTheme::instance();
    829 }
    830 
    831 // Input -----------------------------------------------------------------------
    832 
    833 View* View::GetEventHandlerForPoint(const gfx::Point& point) {
    834   return GetEventHandlerForRect(gfx::Rect(point, gfx::Size(1, 1)));
    835 }
    836 
    837 View* View::GetEventHandlerForRect(const gfx::Rect& rect) {
    838   // |rect_view| represents the current best candidate to return
    839   // if rect-based targeting (i.e., fuzzing) is used.
    840   // |rect_view_distance| is used to keep track of the distance
    841   // between the center point of |rect_view| and the center
    842   // point of |rect|.
    843   View* rect_view = NULL;
    844   int rect_view_distance = INT_MAX;
    845 
    846   // |point_view| represents the view that would have been returned
    847   // from this function call if point-based targeting were used.
    848   View* point_view = NULL;
    849 
    850   for (int i = child_count() - 1; i >= 0; --i) {
    851     View* child = child_at(i);
    852 
    853     if (!child->CanProcessEventsWithinSubtree())
    854       continue;
    855 
    856     // Ignore any children which are invisible or do not intersect |rect|.
    857     if (!child->visible())
    858       continue;
    859     gfx::RectF rect_in_child_coords_f(rect);
    860     ConvertRectToTarget(this, child, &rect_in_child_coords_f);
    861     gfx::Rect rect_in_child_coords = gfx::ToEnclosingRect(
    862         rect_in_child_coords_f);
    863     if (!child->HitTestRect(rect_in_child_coords))
    864       continue;
    865 
    866     View* cur_view = child->GetEventHandlerForRect(rect_in_child_coords);
    867 
    868     if (views::UsePointBasedTargeting(rect))
    869       return cur_view;
    870 
    871     gfx::RectF cur_view_bounds_f(cur_view->GetLocalBounds());
    872     ConvertRectToTarget(cur_view, this, &cur_view_bounds_f);
    873     gfx::Rect cur_view_bounds = gfx::ToEnclosingRect(
    874         cur_view_bounds_f);
    875     if (views::PercentCoveredBy(cur_view_bounds, rect) >= kRectTargetOverlap) {
    876       // |cur_view| is a suitable candidate for rect-based targeting.
    877       // Check to see if it is the closest suitable candidate so far.
    878       gfx::Point touch_center(rect.CenterPoint());
    879       int cur_dist = views::DistanceSquaredFromCenterToPoint(touch_center,
    880                                                              cur_view_bounds);
    881       if (!rect_view || cur_dist < rect_view_distance) {
    882         rect_view = cur_view;
    883         rect_view_distance = cur_dist;
    884       }
    885     } else if (!rect_view && !point_view) {
    886       // Rect-based targeting has not yielded any candidates so far. Check
    887       // if point-based targeting would have selected |cur_view|.
    888       gfx::Point point_in_child_coords(rect_in_child_coords.CenterPoint());
    889       if (child->HitTestPoint(point_in_child_coords))
    890         point_view = child->GetEventHandlerForPoint(point_in_child_coords);
    891     }
    892   }
    893 
    894   if (views::UsePointBasedTargeting(rect) || (!rect_view && !point_view))
    895     return this;
    896 
    897   // If |this| is a suitable candidate for rect-based targeting, check to
    898   // see if it is closer than the current best suitable candidate so far.
    899   gfx::Rect local_bounds(GetLocalBounds());
    900   if (views::PercentCoveredBy(local_bounds, rect) >= kRectTargetOverlap) {
    901     gfx::Point touch_center(rect.CenterPoint());
    902     int cur_dist = views::DistanceSquaredFromCenterToPoint(touch_center,
    903                                                            local_bounds);
    904     if (!rect_view || cur_dist < rect_view_distance)
    905       rect_view = this;
    906   }
    907 
    908   return rect_view ? rect_view : point_view;
    909 }
    910 
    911 bool View::CanProcessEventsWithinSubtree() const {
    912   return true;
    913 }
    914 
    915 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) {
    916   if (!HitTestPoint(point) || !CanProcessEventsWithinSubtree())
    917     return NULL;
    918 
    919   // Walk the child Views recursively looking for the View that most
    920   // tightly encloses the specified point.
    921   for (int i = child_count() - 1; i >= 0; --i) {
    922     View* child = child_at(i);
    923     if (!child->visible())
    924       continue;
    925 
    926     gfx::Point point_in_child_coords(point);
    927     ConvertPointToTarget(this, child, &point_in_child_coords);
    928     View* handler = child->GetTooltipHandlerForPoint(point_in_child_coords);
    929     if (handler)
    930       return handler;
    931   }
    932   return this;
    933 }
    934 
    935 gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) {
    936 #if defined(OS_WIN)
    937   static ui::Cursor arrow;
    938   if (!arrow.platform())
    939     arrow.SetPlatformCursor(LoadCursor(NULL, IDC_ARROW));
    940   return arrow;
    941 #else
    942   return gfx::kNullCursor;
    943 #endif
    944 }
    945 
    946 bool View::HitTestPoint(const gfx::Point& point) const {
    947   return HitTestRect(gfx::Rect(point, gfx::Size(1, 1)));
    948 }
    949 
    950 bool View::HitTestRect(const gfx::Rect& rect) const {
    951   if (GetLocalBounds().Intersects(rect)) {
    952     if (HasHitTestMask()) {
    953       gfx::Path mask;
    954       HitTestSource source = HIT_TEST_SOURCE_MOUSE;
    955       if (!views::UsePointBasedTargeting(rect))
    956         source = HIT_TEST_SOURCE_TOUCH;
    957       GetHitTestMask(source, &mask);
    958       SkRegion clip_region;
    959       clip_region.setRect(0, 0, width(), height());
    960       SkRegion mask_region;
    961       return mask_region.setPath(mask, clip_region) &&
    962              mask_region.intersects(RectToSkIRect(rect));
    963     }
    964     // No mask, but inside our bounds.
    965     return true;
    966   }
    967   // Outside our bounds.
    968   return false;
    969 }
    970 
    971 bool View::IsMouseHovered() {
    972   // If we haven't yet been placed in an onscreen view hierarchy, we can't be
    973   // hovered.
    974   if (!GetWidget())
    975     return false;
    976 
    977   // If mouse events are disabled, then the mouse cursor is invisible and
    978   // is therefore not hovering over this button.
    979   if (!GetWidget()->IsMouseEventsEnabled())
    980     return false;
    981 
    982   gfx::Point cursor_pos(gfx::Screen::GetScreenFor(
    983       GetWidget()->GetNativeView())->GetCursorScreenPoint());
    984   ConvertPointFromScreen(this, &cursor_pos);
    985   return HitTestPoint(cursor_pos);
    986 }
    987 
    988 bool View::OnMousePressed(const ui::MouseEvent& event) {
    989   return false;
    990 }
    991 
    992 bool View::OnMouseDragged(const ui::MouseEvent& event) {
    993   return false;
    994 }
    995 
    996 void View::OnMouseReleased(const ui::MouseEvent& event) {
    997 }
    998 
    999 void View::OnMouseCaptureLost() {
   1000 }
   1001 
   1002 void View::OnMouseMoved(const ui::MouseEvent& event) {
   1003 }
   1004 
   1005 void View::OnMouseEntered(const ui::MouseEvent& event) {
   1006 }
   1007 
   1008 void View::OnMouseExited(const ui::MouseEvent& event) {
   1009 }
   1010 
   1011 void View::SetMouseHandler(View* new_mouse_handler) {
   1012   // |new_mouse_handler| may be NULL.
   1013   if (parent_)
   1014     parent_->SetMouseHandler(new_mouse_handler);
   1015 }
   1016 
   1017 bool View::OnKeyPressed(const ui::KeyEvent& event) {
   1018   return false;
   1019 }
   1020 
   1021 bool View::OnKeyReleased(const ui::KeyEvent& event) {
   1022   return false;
   1023 }
   1024 
   1025 bool View::OnMouseWheel(const ui::MouseWheelEvent& event) {
   1026   return false;
   1027 }
   1028 
   1029 void View::OnKeyEvent(ui::KeyEvent* event) {
   1030   bool consumed = (event->type() == ui::ET_KEY_PRESSED) ? OnKeyPressed(*event) :
   1031                                                           OnKeyReleased(*event);
   1032   if (consumed)
   1033     event->StopPropagation();
   1034 }
   1035 
   1036 void View::OnMouseEvent(ui::MouseEvent* event) {
   1037   switch (event->type()) {
   1038     case ui::ET_MOUSE_PRESSED:
   1039       if (ProcessMousePressed(*event))
   1040         event->SetHandled();
   1041       return;
   1042 
   1043     case ui::ET_MOUSE_MOVED:
   1044       if ((event->flags() & (ui::EF_LEFT_MOUSE_BUTTON |
   1045                              ui::EF_RIGHT_MOUSE_BUTTON |
   1046                              ui::EF_MIDDLE_MOUSE_BUTTON)) == 0) {
   1047         OnMouseMoved(*event);
   1048         return;
   1049       }
   1050       // FALL-THROUGH
   1051     case ui::ET_MOUSE_DRAGGED:
   1052       if (ProcessMouseDragged(*event))
   1053         event->SetHandled();
   1054       return;
   1055 
   1056     case ui::ET_MOUSE_RELEASED:
   1057       ProcessMouseReleased(*event);
   1058       return;
   1059 
   1060     case ui::ET_MOUSEWHEEL:
   1061       if (OnMouseWheel(*static_cast<ui::MouseWheelEvent*>(event)))
   1062         event->SetHandled();
   1063       break;
   1064 
   1065     case ui::ET_MOUSE_ENTERED:
   1066       if (event->flags() & ui::EF_TOUCH_ACCESSIBILITY)
   1067         NotifyAccessibilityEvent(ui::AX_EVENT_HOVER, true);
   1068       OnMouseEntered(*event);
   1069       break;
   1070 
   1071     case ui::ET_MOUSE_EXITED:
   1072       OnMouseExited(*event);
   1073       break;
   1074 
   1075     default:
   1076       return;
   1077   }
   1078 }
   1079 
   1080 void View::OnScrollEvent(ui::ScrollEvent* event) {
   1081 }
   1082 
   1083 void View::OnTouchEvent(ui::TouchEvent* event) {
   1084   NOTREACHED() << "Views should not receive touch events.";
   1085 }
   1086 
   1087 void View::OnGestureEvent(ui::GestureEvent* event) {
   1088 }
   1089 
   1090 ui::TextInputClient* View::GetTextInputClient() {
   1091   return NULL;
   1092 }
   1093 
   1094 InputMethod* View::GetInputMethod() {
   1095   Widget* widget = GetWidget();
   1096   return widget ? widget->GetInputMethod() : NULL;
   1097 }
   1098 
   1099 const InputMethod* View::GetInputMethod() const {
   1100   const Widget* widget = GetWidget();
   1101   return widget ? widget->GetInputMethod() : NULL;
   1102 }
   1103 
   1104 scoped_ptr<ui::EventTargeter>
   1105 View::SetEventTargeter(scoped_ptr<ui::EventTargeter> targeter) {
   1106   scoped_ptr<ui::EventTargeter> old_targeter = targeter_.Pass();
   1107   targeter_ = targeter.Pass();
   1108   return old_targeter.Pass();
   1109 }
   1110 
   1111 bool View::CanAcceptEvent(const ui::Event& event) {
   1112   return IsDrawn();
   1113 }
   1114 
   1115 ui::EventTarget* View::GetParentTarget() {
   1116   return parent_;
   1117 }
   1118 
   1119 scoped_ptr<ui::EventTargetIterator> View::GetChildIterator() const {
   1120   return scoped_ptr<ui::EventTargetIterator>(
   1121       new ui::EventTargetIteratorImpl<View>(children_));
   1122 }
   1123 
   1124 ui::EventTargeter* View::GetEventTargeter() {
   1125   return targeter_.get();
   1126 }
   1127 
   1128 const ui::EventTargeter* View::GetEventTargeter() const {
   1129   return targeter_.get();
   1130 }
   1131 
   1132 void View::ConvertEventToTarget(ui::EventTarget* target,
   1133                                 ui::LocatedEvent* event) {
   1134   event->ConvertLocationToTarget(this, static_cast<View*>(target));
   1135 }
   1136 
   1137 // Accelerators ----------------------------------------------------------------
   1138 
   1139 void View::AddAccelerator(const ui::Accelerator& accelerator) {
   1140   if (!accelerators_.get())
   1141     accelerators_.reset(new std::vector<ui::Accelerator>());
   1142 
   1143   if (std::find(accelerators_->begin(), accelerators_->end(), accelerator) ==
   1144       accelerators_->end()) {
   1145     accelerators_->push_back(accelerator);
   1146   }
   1147   RegisterPendingAccelerators();
   1148 }
   1149 
   1150 void View::RemoveAccelerator(const ui::Accelerator& accelerator) {
   1151   if (!accelerators_.get()) {
   1152     NOTREACHED() << "Removing non-existing accelerator";
   1153     return;
   1154   }
   1155 
   1156   std::vector<ui::Accelerator>::iterator i(
   1157       std::find(accelerators_->begin(), accelerators_->end(), accelerator));
   1158   if (i == accelerators_->end()) {
   1159     NOTREACHED() << "Removing non-existing accelerator";
   1160     return;
   1161   }
   1162 
   1163   size_t index = i - accelerators_->begin();
   1164   accelerators_->erase(i);
   1165   if (index >= registered_accelerator_count_) {
   1166     // The accelerator is not registered to FocusManager.
   1167     return;
   1168   }
   1169   --registered_accelerator_count_;
   1170 
   1171   // Providing we are attached to a Widget and registered with a focus manager,
   1172   // we should de-register from that focus manager now.
   1173   if (GetWidget() && accelerator_focus_manager_)
   1174     accelerator_focus_manager_->UnregisterAccelerator(accelerator, this);
   1175 }
   1176 
   1177 void View::ResetAccelerators() {
   1178   if (accelerators_.get())
   1179     UnregisterAccelerators(false);
   1180 }
   1181 
   1182 bool View::AcceleratorPressed(const ui::Accelerator& accelerator) {
   1183   return false;
   1184 }
   1185 
   1186 bool View::CanHandleAccelerators() const {
   1187   return enabled() && IsDrawn() && GetWidget() && GetWidget()->IsVisible();
   1188 }
   1189 
   1190 // Focus -----------------------------------------------------------------------
   1191 
   1192 bool View::HasFocus() const {
   1193   const FocusManager* focus_manager = GetFocusManager();
   1194   return focus_manager && (focus_manager->GetFocusedView() == this);
   1195 }
   1196 
   1197 View* View::GetNextFocusableView() {
   1198   return next_focusable_view_;
   1199 }
   1200 
   1201 const View* View::GetNextFocusableView() const {
   1202   return next_focusable_view_;
   1203 }
   1204 
   1205 View* View::GetPreviousFocusableView() {
   1206   return previous_focusable_view_;
   1207 }
   1208 
   1209 void View::SetNextFocusableView(View* view) {
   1210   if (view)
   1211     view->previous_focusable_view_ = this;
   1212   next_focusable_view_ = view;
   1213 }
   1214 
   1215 void View::SetFocusable(bool focusable) {
   1216   if (focusable_ == focusable)
   1217     return;
   1218 
   1219   focusable_ = focusable;
   1220 }
   1221 
   1222 bool View::IsFocusable() const {
   1223   return focusable_ && enabled_ && IsDrawn();
   1224 }
   1225 
   1226 bool View::IsAccessibilityFocusable() const {
   1227   return (focusable_ || accessibility_focusable_) && enabled_ && IsDrawn();
   1228 }
   1229 
   1230 void View::SetAccessibilityFocusable(bool accessibility_focusable) {
   1231   if (accessibility_focusable_ == accessibility_focusable)
   1232     return;
   1233 
   1234   accessibility_focusable_ = accessibility_focusable;
   1235 }
   1236 
   1237 FocusManager* View::GetFocusManager() {
   1238   Widget* widget = GetWidget();
   1239   return widget ? widget->GetFocusManager() : NULL;
   1240 }
   1241 
   1242 const FocusManager* View::GetFocusManager() const {
   1243   const Widget* widget = GetWidget();
   1244   return widget ? widget->GetFocusManager() : NULL;
   1245 }
   1246 
   1247 void View::RequestFocus() {
   1248   FocusManager* focus_manager = GetFocusManager();
   1249   if (focus_manager && IsFocusable())
   1250     focus_manager->SetFocusedView(this);
   1251 }
   1252 
   1253 bool View::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
   1254   return false;
   1255 }
   1256 
   1257 FocusTraversable* View::GetFocusTraversable() {
   1258   return NULL;
   1259 }
   1260 
   1261 FocusTraversable* View::GetPaneFocusTraversable() {
   1262   return NULL;
   1263 }
   1264 
   1265 // Tooltips --------------------------------------------------------------------
   1266 
   1267 bool View::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
   1268   return false;
   1269 }
   1270 
   1271 bool View::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* loc) const {
   1272   return false;
   1273 }
   1274 
   1275 // Context menus ---------------------------------------------------------------
   1276 
   1277 void View::ShowContextMenu(const gfx::Point& p,
   1278                            ui::MenuSourceType source_type) {
   1279   if (!context_menu_controller_)
   1280     return;
   1281 
   1282   context_menu_controller_->ShowContextMenuForView(this, p, source_type);
   1283 }
   1284 
   1285 // static
   1286 bool View::ShouldShowContextMenuOnMousePress() {
   1287   return kContextMenuOnMousePress;
   1288 }
   1289 
   1290 // Drag and drop ---------------------------------------------------------------
   1291 
   1292 bool View::GetDropFormats(
   1293       int* formats,
   1294       std::set<OSExchangeData::CustomFormat>* custom_formats) {
   1295   return false;
   1296 }
   1297 
   1298 bool View::AreDropTypesRequired() {
   1299   return false;
   1300 }
   1301 
   1302 bool View::CanDrop(const OSExchangeData& data) {
   1303   // TODO(sky): when I finish up migration, this should default to true.
   1304   return false;
   1305 }
   1306 
   1307 void View::OnDragEntered(const ui::DropTargetEvent& event) {
   1308 }
   1309 
   1310 int View::OnDragUpdated(const ui::DropTargetEvent& event) {
   1311   return ui::DragDropTypes::DRAG_NONE;
   1312 }
   1313 
   1314 void View::OnDragExited() {
   1315 }
   1316 
   1317 int View::OnPerformDrop(const ui::DropTargetEvent& event) {
   1318   return ui::DragDropTypes::DRAG_NONE;
   1319 }
   1320 
   1321 void View::OnDragDone() {
   1322 }
   1323 
   1324 // static
   1325 bool View::ExceededDragThreshold(const gfx::Vector2d& delta) {
   1326   return (abs(delta.x()) > GetHorizontalDragThreshold() ||
   1327           abs(delta.y()) > GetVerticalDragThreshold());
   1328 }
   1329 
   1330 // Accessibility----------------------------------------------------------------
   1331 
   1332 gfx::NativeViewAccessible View::GetNativeViewAccessible() {
   1333   if (!native_view_accessibility_)
   1334     native_view_accessibility_ = NativeViewAccessibility::Create(this);
   1335   if (native_view_accessibility_)
   1336     return native_view_accessibility_->GetNativeObject();
   1337   return NULL;
   1338 }
   1339 
   1340 void View::NotifyAccessibilityEvent(
   1341     ui::AXEvent event_type,
   1342     bool send_native_event) {
   1343   if (ViewsDelegate::views_delegate)
   1344     ViewsDelegate::views_delegate->NotifyAccessibilityEvent(this, event_type);
   1345 
   1346   if (send_native_event && GetWidget()) {
   1347     if (!native_view_accessibility_)
   1348       native_view_accessibility_ = NativeViewAccessibility::Create(this);
   1349     if (native_view_accessibility_)
   1350       native_view_accessibility_->NotifyAccessibilityEvent(event_type);
   1351   }
   1352 }
   1353 
   1354 // Scrolling -------------------------------------------------------------------
   1355 
   1356 void View::ScrollRectToVisible(const gfx::Rect& rect) {
   1357   // We must take RTL UI mirroring into account when adjusting the position of
   1358   // the region.
   1359   if (parent_) {
   1360     gfx::Rect scroll_rect(rect);
   1361     scroll_rect.Offset(GetMirroredX(), y());
   1362     parent_->ScrollRectToVisible(scroll_rect);
   1363   }
   1364 }
   1365 
   1366 int View::GetPageScrollIncrement(ScrollView* scroll_view,
   1367                                  bool is_horizontal, bool is_positive) {
   1368   return 0;
   1369 }
   1370 
   1371 int View::GetLineScrollIncrement(ScrollView* scroll_view,
   1372                                  bool is_horizontal, bool is_positive) {
   1373   return 0;
   1374 }
   1375 
   1376 ////////////////////////////////////////////////////////////////////////////////
   1377 // View, protected:
   1378 
   1379 // Size and disposition --------------------------------------------------------
   1380 
   1381 void View::OnBoundsChanged(const gfx::Rect& previous_bounds) {
   1382 }
   1383 
   1384 void View::PreferredSizeChanged() {
   1385   InvalidateLayout();
   1386   if (parent_)
   1387     parent_->ChildPreferredSizeChanged(this);
   1388 }
   1389 
   1390 bool View::NeedsNotificationWhenVisibleBoundsChange() const {
   1391   return false;
   1392 }
   1393 
   1394 void View::OnVisibleBoundsChanged() {
   1395 }
   1396 
   1397 // Tree operations -------------------------------------------------------------
   1398 
   1399 void View::ViewHierarchyChanged(const ViewHierarchyChangedDetails& details) {
   1400 }
   1401 
   1402 void View::VisibilityChanged(View* starting_from, bool is_visible) {
   1403 }
   1404 
   1405 void View::NativeViewHierarchyChanged() {
   1406   FocusManager* focus_manager = GetFocusManager();
   1407   if (accelerator_focus_manager_ != focus_manager) {
   1408     UnregisterAccelerators(true);
   1409 
   1410     if (focus_manager)
   1411       RegisterPendingAccelerators();
   1412   }
   1413 }
   1414 
   1415 // Painting --------------------------------------------------------------------
   1416 
   1417 void View::PaintChildren(gfx::Canvas* canvas, const CullSet& cull_set) {
   1418   TRACE_EVENT1("views", "View::PaintChildren", "class", GetClassName());
   1419   for (int i = 0, count = child_count(); i < count; ++i)
   1420     if (!child_at(i)->layer())
   1421       child_at(i)->Paint(canvas, cull_set);
   1422 }
   1423 
   1424 void View::OnPaint(gfx::Canvas* canvas) {
   1425   TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName());
   1426   OnPaintBackground(canvas);
   1427   OnPaintBorder(canvas);
   1428 }
   1429 
   1430 void View::OnPaintBackground(gfx::Canvas* canvas) {
   1431   if (background_.get()) {
   1432     TRACE_EVENT2("views", "View::OnPaintBackground",
   1433                  "width", canvas->sk_canvas()->getDevice()->width(),
   1434                  "height", canvas->sk_canvas()->getDevice()->height());
   1435     background_->Paint(canvas, this);
   1436   }
   1437 }
   1438 
   1439 void View::OnPaintBorder(gfx::Canvas* canvas) {
   1440   if (border_.get()) {
   1441     TRACE_EVENT2("views", "View::OnPaintBorder",
   1442                  "width", canvas->sk_canvas()->getDevice()->width(),
   1443                  "height", canvas->sk_canvas()->getDevice()->height());
   1444     border_->Paint(*this, canvas);
   1445   }
   1446 }
   1447 
   1448 bool View::IsPaintRoot() {
   1449   return paint_to_layer_ || !parent_;
   1450 }
   1451 
   1452 // Accelerated Painting --------------------------------------------------------
   1453 
   1454 void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
   1455   // This method should not have the side-effect of creating the layer.
   1456   if (layer())
   1457     layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
   1458 }
   1459 
   1460 gfx::Vector2d View::CalculateOffsetToAncestorWithLayer(
   1461     ui::Layer** layer_parent) {
   1462   if (layer()) {
   1463     if (layer_parent)
   1464       *layer_parent = layer();
   1465     return gfx::Vector2d();
   1466   }
   1467   if (!parent_)
   1468     return gfx::Vector2d();
   1469 
   1470   return gfx::Vector2d(GetMirroredX(), y()) +
   1471       parent_->CalculateOffsetToAncestorWithLayer(layer_parent);
   1472 }
   1473 
   1474 void View::UpdateParentLayer() {
   1475   if (!layer())
   1476     return;
   1477 
   1478   ui::Layer* parent_layer = NULL;
   1479   gfx::Vector2d offset(GetMirroredX(), y());
   1480 
   1481   if (parent_)
   1482     offset += parent_->CalculateOffsetToAncestorWithLayer(&parent_layer);
   1483 
   1484   ReparentLayer(offset, parent_layer);
   1485 }
   1486 
   1487 void View::MoveLayerToParent(ui::Layer* parent_layer,
   1488                              const gfx::Point& point) {
   1489   gfx::Point local_point(point);
   1490   if (parent_layer != layer())
   1491     local_point.Offset(GetMirroredX(), y());
   1492   if (layer() && parent_layer != layer()) {
   1493     parent_layer->Add(layer());
   1494     SetLayerBounds(gfx::Rect(local_point.x(), local_point.y(),
   1495                              width(), height()));
   1496   } else {
   1497     for (int i = 0, count = child_count(); i < count; ++i)
   1498       child_at(i)->MoveLayerToParent(parent_layer, local_point);
   1499   }
   1500 }
   1501 
   1502 void View::UpdateLayerVisibility() {
   1503   bool visible = visible_;
   1504   for (const View* v = parent_; visible && v && !v->layer(); v = v->parent_)
   1505     visible = v->visible();
   1506 
   1507   UpdateChildLayerVisibility(visible);
   1508 }
   1509 
   1510 void View::UpdateChildLayerVisibility(bool ancestor_visible) {
   1511   if (layer()) {
   1512     layer()->SetVisible(ancestor_visible && visible_);
   1513   } else {
   1514     for (int i = 0, count = child_count(); i < count; ++i)
   1515       child_at(i)->UpdateChildLayerVisibility(ancestor_visible && visible_);
   1516   }
   1517 }
   1518 
   1519 void View::UpdateChildLayerBounds(const gfx::Vector2d& offset) {
   1520   if (layer()) {
   1521     SetLayerBounds(GetLocalBounds() + offset);
   1522   } else {
   1523     for (int i = 0, count = child_count(); i < count; ++i) {
   1524       View* child = child_at(i);
   1525       child->UpdateChildLayerBounds(
   1526           offset + gfx::Vector2d(child->GetMirroredX(), child->y()));
   1527     }
   1528   }
   1529 }
   1530 
   1531 void View::OnPaintLayer(gfx::Canvas* canvas) {
   1532   if (!layer() || !layer()->fills_bounds_opaquely())
   1533     canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
   1534   PaintCommon(canvas, CullSet());
   1535 }
   1536 
   1537 void View::OnDeviceScaleFactorChanged(float device_scale_factor) {
   1538   // Repainting with new scale factor will paint the content at the right scale.
   1539 }
   1540 
   1541 base::Closure View::PrepareForLayerBoundsChange() {
   1542   return base::Closure();
   1543 }
   1544 
   1545 void View::ReorderLayers() {
   1546   View* v = this;
   1547   while (v && !v->layer())
   1548     v = v->parent();
   1549 
   1550   Widget* widget = GetWidget();
   1551   if (!v) {
   1552     if (widget) {
   1553       ui::Layer* layer = widget->GetLayer();
   1554       if (layer)
   1555         widget->GetRootView()->ReorderChildLayers(layer);
   1556     }
   1557   } else {
   1558     v->ReorderChildLayers(v->layer());
   1559   }
   1560 
   1561   if (widget) {
   1562     // Reorder the widget's child NativeViews in case a child NativeView is
   1563     // associated with a view (eg via a NativeViewHost). Always do the
   1564     // reordering because the associated NativeView's layer (if it has one)
   1565     // is parented to the widget's layer regardless of whether the host view has
   1566     // an ancestor with a layer.
   1567     widget->ReorderNativeViews();
   1568   }
   1569 }
   1570 
   1571 void View::ReorderChildLayers(ui::Layer* parent_layer) {
   1572   if (layer() && layer() != parent_layer) {
   1573     DCHECK_EQ(parent_layer, layer()->parent());
   1574     parent_layer->StackAtBottom(layer());
   1575   } else {
   1576     // Iterate backwards through the children so that a child with a layer
   1577     // which is further to the back is stacked above one which is further to
   1578     // the front.
   1579     for (Views::reverse_iterator it(children_.rbegin());
   1580          it != children_.rend(); ++it) {
   1581       (*it)->ReorderChildLayers(parent_layer);
   1582     }
   1583   }
   1584 }
   1585 
   1586 // Input -----------------------------------------------------------------------
   1587 
   1588 bool View::HasHitTestMask() const {
   1589   return false;
   1590 }
   1591 
   1592 void View::GetHitTestMask(HitTestSource source, gfx::Path* mask) const {
   1593   DCHECK(mask);
   1594 }
   1595 
   1596 View::DragInfo* View::GetDragInfo() {
   1597   return parent_ ? parent_->GetDragInfo() : NULL;
   1598 }
   1599 
   1600 // Focus -----------------------------------------------------------------------
   1601 
   1602 void View::OnFocus() {
   1603   // TODO(beng): Investigate whether it's possible for us to move this to
   1604   //             Focus().
   1605   // By default, we clear the native focus. This ensures that no visible native
   1606   // view as the focus and that we still receive keyboard inputs.
   1607   FocusManager* focus_manager = GetFocusManager();
   1608   if (focus_manager)
   1609     focus_manager->ClearNativeFocus();
   1610 
   1611   // TODO(beng): Investigate whether it's possible for us to move this to
   1612   //             Focus().
   1613   // Notify assistive technologies of the focus change.
   1614   NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
   1615 }
   1616 
   1617 void View::OnBlur() {
   1618 }
   1619 
   1620 void View::Focus() {
   1621   OnFocus();
   1622 }
   1623 
   1624 void View::Blur() {
   1625   OnBlur();
   1626 }
   1627 
   1628 // Tooltips --------------------------------------------------------------------
   1629 
   1630 void View::TooltipTextChanged() {
   1631   Widget* widget = GetWidget();
   1632   // TooltipManager may be null if there is a problem creating it.
   1633   if (widget && widget->GetTooltipManager())
   1634     widget->GetTooltipManager()->TooltipTextChanged(this);
   1635 }
   1636 
   1637 // Context menus ---------------------------------------------------------------
   1638 
   1639 gfx::Point View::GetKeyboardContextMenuLocation() {
   1640   gfx::Rect vis_bounds = GetVisibleBounds();
   1641   gfx::Point screen_point(vis_bounds.x() + vis_bounds.width() / 2,
   1642                           vis_bounds.y() + vis_bounds.height() / 2);
   1643   ConvertPointToScreen(this, &screen_point);
   1644   return screen_point;
   1645 }
   1646 
   1647 // Drag and drop ---------------------------------------------------------------
   1648 
   1649 int View::GetDragOperations(const gfx::Point& press_pt) {
   1650   return drag_controller_ ?
   1651       drag_controller_->GetDragOperationsForView(this, press_pt) :
   1652       ui::DragDropTypes::DRAG_NONE;
   1653 }
   1654 
   1655 void View::WriteDragData(const gfx::Point& press_pt, OSExchangeData* data) {
   1656   DCHECK(drag_controller_);
   1657   drag_controller_->WriteDragDataForView(this, press_pt, data);
   1658 }
   1659 
   1660 bool View::InDrag() {
   1661   Widget* widget = GetWidget();
   1662   return widget ? widget->dragged_view() == this : false;
   1663 }
   1664 
   1665 int View::GetHorizontalDragThreshold() {
   1666   // TODO(jennyz): This value may need to be adjusted for different platforms
   1667   // and for different display density.
   1668   return kDefaultHorizontalDragThreshold;
   1669 }
   1670 
   1671 int View::GetVerticalDragThreshold() {
   1672   // TODO(jennyz): This value may need to be adjusted for different platforms
   1673   // and for different display density.
   1674   return kDefaultVerticalDragThreshold;
   1675 }
   1676 
   1677 // Debugging -------------------------------------------------------------------
   1678 
   1679 #if !defined(NDEBUG)
   1680 
   1681 std::string View::PrintViewGraph(bool first) {
   1682   return DoPrintViewGraph(first, this);
   1683 }
   1684 
   1685 std::string View::DoPrintViewGraph(bool first, View* view_with_children) {
   1686   // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19.
   1687   const size_t kMaxPointerStringLength = 19;
   1688 
   1689   std::string result;
   1690 
   1691   if (first)
   1692     result.append("digraph {\n");
   1693 
   1694   // Node characteristics.
   1695   char p[kMaxPointerStringLength];
   1696 
   1697   const std::string class_name(GetClassName());
   1698   size_t base_name_index = class_name.find_last_of('/');
   1699   if (base_name_index == std::string::npos)
   1700     base_name_index = 0;
   1701   else
   1702     base_name_index++;
   1703 
   1704   char bounds_buffer[512];
   1705 
   1706   // Information about current node.
   1707   base::snprintf(p, arraysize(bounds_buffer), "%p", view_with_children);
   1708   result.append("  N");
   1709   result.append(p + 2);
   1710   result.append(" [label=\"");
   1711 
   1712   result.append(class_name.substr(base_name_index).c_str());
   1713 
   1714   base::snprintf(bounds_buffer,
   1715                  arraysize(bounds_buffer),
   1716                  "\\n bounds: (%d, %d), (%dx%d)",
   1717                  bounds().x(),
   1718                  bounds().y(),
   1719                  bounds().width(),
   1720                  bounds().height());
   1721   result.append(bounds_buffer);
   1722 
   1723   gfx::DecomposedTransform decomp;
   1724   if (!GetTransform().IsIdentity() &&
   1725       gfx::DecomposeTransform(&decomp, GetTransform())) {
   1726     base::snprintf(bounds_buffer,
   1727                    arraysize(bounds_buffer),
   1728                    "\\n translation: (%f, %f)",
   1729                    decomp.translate[0],
   1730                    decomp.translate[1]);
   1731     result.append(bounds_buffer);
   1732 
   1733     base::snprintf(bounds_buffer,
   1734                    arraysize(bounds_buffer),
   1735                    "\\n rotation: %3.2f",
   1736                    std::acos(decomp.quaternion[3]) * 360.0 / M_PI);
   1737     result.append(bounds_buffer);
   1738 
   1739     base::snprintf(bounds_buffer,
   1740                    arraysize(bounds_buffer),
   1741                    "\\n scale: (%2.4f, %2.4f)",
   1742                    decomp.scale[0],
   1743                    decomp.scale[1]);
   1744     result.append(bounds_buffer);
   1745   }
   1746 
   1747   result.append("\"");
   1748   if (!parent_)
   1749     result.append(", shape=box");
   1750   if (layer()) {
   1751     if (layer()->has_external_content())
   1752       result.append(", color=green");
   1753     else
   1754       result.append(", color=red");
   1755 
   1756     if (layer()->fills_bounds_opaquely())
   1757       result.append(", style=filled");
   1758   }
   1759   result.append("]\n");
   1760 
   1761   // Link to parent.
   1762   if (parent_) {
   1763     char pp[kMaxPointerStringLength];
   1764 
   1765     base::snprintf(pp, kMaxPointerStringLength, "%p", parent_);
   1766     result.append("  N");
   1767     result.append(pp + 2);
   1768     result.append(" -> N");
   1769     result.append(p + 2);
   1770     result.append("\n");
   1771   }
   1772 
   1773   // Children.
   1774   for (int i = 0, count = view_with_children->child_count(); i < count; ++i)
   1775     result.append(view_with_children->child_at(i)->PrintViewGraph(false));
   1776 
   1777   if (first)
   1778     result.append("}\n");
   1779 
   1780   return result;
   1781 }
   1782 #endif
   1783 
   1784 ////////////////////////////////////////////////////////////////////////////////
   1785 // View, private:
   1786 
   1787 // DropInfo --------------------------------------------------------------------
   1788 
   1789 void View::DragInfo::Reset() {
   1790   possible_drag = false;
   1791   start_pt = gfx::Point();
   1792 }
   1793 
   1794 void View::DragInfo::PossibleDrag(const gfx::Point& p) {
   1795   possible_drag = true;
   1796   start_pt = p;
   1797 }
   1798 
   1799 // Painting --------------------------------------------------------------------
   1800 
   1801 void View::SchedulePaintBoundsChanged(SchedulePaintType type) {
   1802   // If we have a layer and the View's size did not change, we do not need to
   1803   // schedule any paints since the layer will be redrawn at its new location
   1804   // during the next Draw() cycle in the compositor.
   1805   if (!layer() || type == SCHEDULE_PAINT_SIZE_CHANGED) {
   1806     // Otherwise, if the size changes or we don't have a layer then we need to
   1807     // use SchedulePaint to invalidate the area occupied by the View.
   1808     SchedulePaint();
   1809   } else if (parent_ && type == SCHEDULE_PAINT_SIZE_SAME) {
   1810     // The compositor doesn't Draw() until something on screen changes, so
   1811     // if our position changes but nothing is being animated on screen, then
   1812     // tell the compositor to redraw the scene. We know layer() exists due to
   1813     // the above if clause.
   1814     layer()->ScheduleDraw();
   1815   }
   1816 }
   1817 
   1818 void View::PaintCommon(gfx::Canvas* canvas, const CullSet& cull_set) {
   1819   if (!visible_)
   1820     return;
   1821 
   1822   {
   1823     // If the View we are about to paint requested the canvas to be flipped, we
   1824     // should change the transform appropriately.
   1825     // The canvas mirroring is undone once the View is done painting so that we
   1826     // don't pass the canvas with the mirrored transform to Views that didn't
   1827     // request the canvas to be flipped.
   1828     gfx::ScopedCanvas scoped(canvas);
   1829     if (FlipCanvasOnPaintForRTLUI()) {
   1830       canvas->Translate(gfx::Vector2d(width(), 0));
   1831       canvas->Scale(-1, 1);
   1832     }
   1833 
   1834     OnPaint(canvas);
   1835   }
   1836 
   1837   PaintChildren(canvas, cull_set);
   1838 }
   1839 
   1840 // Tree operations -------------------------------------------------------------
   1841 
   1842 void View::DoRemoveChildView(View* view,
   1843                              bool update_focus_cycle,
   1844                              bool update_tool_tip,
   1845                              bool delete_removed_view,
   1846                              View* new_parent) {
   1847   DCHECK(view);
   1848 
   1849   const Views::iterator i(std::find(children_.begin(), children_.end(), view));
   1850   scoped_ptr<View> view_to_be_deleted;
   1851   if (i != children_.end()) {
   1852     if (update_focus_cycle) {
   1853       // Let's remove the view from the focus traversal.
   1854       View* next_focusable = view->next_focusable_view_;
   1855       View* prev_focusable = view->previous_focusable_view_;
   1856       if (prev_focusable)
   1857         prev_focusable->next_focusable_view_ = next_focusable;
   1858       if (next_focusable)
   1859         next_focusable->previous_focusable_view_ = prev_focusable;
   1860     }
   1861 
   1862     if (GetWidget()) {
   1863       UnregisterChildrenForVisibleBoundsNotification(view);
   1864       if (view->visible())
   1865         view->SchedulePaint();
   1866       GetWidget()->NotifyWillRemoveView(view);
   1867     }
   1868 
   1869     // Remove the bounds of this child and any of its descendants from our
   1870     // paint root bounds tree.
   1871     BoundsTree* bounds_tree = GetBoundsTreeFromPaintRoot();
   1872     if (bounds_tree)
   1873       view->RemoveRootBounds(bounds_tree);
   1874 
   1875     view->PropagateRemoveNotifications(this, new_parent);
   1876     view->parent_ = NULL;
   1877     view->UpdateLayerVisibility();
   1878 
   1879     if (delete_removed_view && !view->owned_by_client_)
   1880       view_to_be_deleted.reset(view);
   1881 
   1882     children_.erase(i);
   1883   }
   1884 
   1885   if (update_tool_tip)
   1886     UpdateTooltip();
   1887 
   1888   if (layout_manager_.get())
   1889     layout_manager_->ViewRemoved(this, view);
   1890 }
   1891 
   1892 void View::PropagateRemoveNotifications(View* old_parent, View* new_parent) {
   1893   for (int i = 0, count = child_count(); i < count; ++i)
   1894     child_at(i)->PropagateRemoveNotifications(old_parent, new_parent);
   1895 
   1896   ViewHierarchyChangedDetails details(false, old_parent, this, new_parent);
   1897   for (View* v = this; v; v = v->parent_)
   1898     v->ViewHierarchyChangedImpl(true, details);
   1899 }
   1900 
   1901 void View::PropagateAddNotifications(
   1902     const ViewHierarchyChangedDetails& details) {
   1903   for (int i = 0, count = child_count(); i < count; ++i)
   1904     child_at(i)->PropagateAddNotifications(details);
   1905   ViewHierarchyChangedImpl(true, details);
   1906 }
   1907 
   1908 void View::PropagateNativeViewHierarchyChanged() {
   1909   for (int i = 0, count = child_count(); i < count; ++i)
   1910     child_at(i)->PropagateNativeViewHierarchyChanged();
   1911   NativeViewHierarchyChanged();
   1912 }
   1913 
   1914 void View::ViewHierarchyChangedImpl(
   1915     bool register_accelerators,
   1916     const ViewHierarchyChangedDetails& details) {
   1917   if (register_accelerators) {
   1918     if (details.is_add) {
   1919       // If you get this registration, you are part of a subtree that has been
   1920       // added to the view hierarchy.
   1921       if (GetFocusManager())
   1922         RegisterPendingAccelerators();
   1923     } else {
   1924       if (details.child == this)
   1925         UnregisterAccelerators(true);
   1926     }
   1927   }
   1928 
   1929   if (details.is_add && layer() && !layer()->parent()) {
   1930     UpdateParentLayer();
   1931     Widget* widget = GetWidget();
   1932     if (widget)
   1933       widget->UpdateRootLayers();
   1934   } else if (!details.is_add && details.child == this) {
   1935     // Make sure the layers belonging to the subtree rooted at |child| get
   1936     // removed from layers that do not belong in the same subtree.
   1937     OrphanLayers();
   1938     Widget* widget = GetWidget();
   1939     if (widget)
   1940       widget->UpdateRootLayers();
   1941   }
   1942 
   1943   ViewHierarchyChanged(details);
   1944   details.parent->needs_layout_ = true;
   1945 }
   1946 
   1947 void View::PropagateNativeThemeChanged(const ui::NativeTheme* theme) {
   1948   for (int i = 0, count = child_count(); i < count; ++i)
   1949     child_at(i)->PropagateNativeThemeChanged(theme);
   1950   OnNativeThemeChanged(theme);
   1951 }
   1952 
   1953 // Size and disposition --------------------------------------------------------
   1954 
   1955 void View::PropagateVisibilityNotifications(View* start, bool is_visible) {
   1956   for (int i = 0, count = child_count(); i < count; ++i)
   1957     child_at(i)->PropagateVisibilityNotifications(start, is_visible);
   1958   VisibilityChangedImpl(start, is_visible);
   1959 }
   1960 
   1961 void View::VisibilityChangedImpl(View* starting_from, bool is_visible) {
   1962   VisibilityChanged(starting_from, is_visible);
   1963 }
   1964 
   1965 void View::BoundsChanged(const gfx::Rect& previous_bounds) {
   1966   // Mark our bounds as dirty for the paint root, also see if we need to
   1967   // recompute our children's bounds due to origin change.
   1968   bool origin_changed =
   1969       previous_bounds.OffsetFromOrigin() != bounds_.OffsetFromOrigin();
   1970   SetRootBoundsDirty(origin_changed);
   1971 
   1972   if (visible_) {
   1973     // Paint the new bounds.
   1974     SchedulePaintBoundsChanged(
   1975         bounds_.size() == previous_bounds.size() ? SCHEDULE_PAINT_SIZE_SAME :
   1976         SCHEDULE_PAINT_SIZE_CHANGED);
   1977   }
   1978 
   1979   if (layer()) {
   1980     if (parent_) {
   1981       SetLayerBounds(GetLocalBounds() +
   1982                      gfx::Vector2d(GetMirroredX(), y()) +
   1983                      parent_->CalculateOffsetToAncestorWithLayer(NULL));
   1984     } else {
   1985       SetLayerBounds(bounds_);
   1986     }
   1987   } else {
   1988     // If our bounds have changed, then any descendant layer bounds may have
   1989     // changed. Update them accordingly.
   1990     UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(NULL));
   1991   }
   1992 
   1993   OnBoundsChanged(previous_bounds);
   1994 
   1995   if (previous_bounds.size() != size()) {
   1996     needs_layout_ = false;
   1997     Layout();
   1998   }
   1999 
   2000   if (NeedsNotificationWhenVisibleBoundsChange())
   2001     OnVisibleBoundsChanged();
   2002 
   2003   // Notify interested Views that visible bounds within the root view may have
   2004   // changed.
   2005   if (descendants_to_notify_.get()) {
   2006     for (Views::iterator i(descendants_to_notify_->begin());
   2007          i != descendants_to_notify_->end(); ++i) {
   2008       (*i)->OnVisibleBoundsChanged();
   2009     }
   2010   }
   2011 }
   2012 
   2013 // static
   2014 void View::RegisterChildrenForVisibleBoundsNotification(View* view) {
   2015   if (view->NeedsNotificationWhenVisibleBoundsChange())
   2016     view->RegisterForVisibleBoundsNotification();
   2017   for (int i = 0; i < view->child_count(); ++i)
   2018     RegisterChildrenForVisibleBoundsNotification(view->child_at(i));
   2019 }
   2020 
   2021 // static
   2022 void View::UnregisterChildrenForVisibleBoundsNotification(View* view) {
   2023   if (view->NeedsNotificationWhenVisibleBoundsChange())
   2024     view->UnregisterForVisibleBoundsNotification();
   2025   for (int i = 0; i < view->child_count(); ++i)
   2026     UnregisterChildrenForVisibleBoundsNotification(view->child_at(i));
   2027 }
   2028 
   2029 void View::RegisterForVisibleBoundsNotification() {
   2030   if (registered_for_visible_bounds_notification_)
   2031     return;
   2032 
   2033   registered_for_visible_bounds_notification_ = true;
   2034   for (View* ancestor = parent_; ancestor; ancestor = ancestor->parent_)
   2035     ancestor->AddDescendantToNotify(this);
   2036 }
   2037 
   2038 void View::UnregisterForVisibleBoundsNotification() {
   2039   if (!registered_for_visible_bounds_notification_)
   2040     return;
   2041 
   2042   registered_for_visible_bounds_notification_ = false;
   2043   for (View* ancestor = parent_; ancestor; ancestor = ancestor->parent_)
   2044     ancestor->RemoveDescendantToNotify(this);
   2045 }
   2046 
   2047 void View::AddDescendantToNotify(View* view) {
   2048   DCHECK(view);
   2049   if (!descendants_to_notify_.get())
   2050     descendants_to_notify_.reset(new Views);
   2051   descendants_to_notify_->push_back(view);
   2052 }
   2053 
   2054 void View::RemoveDescendantToNotify(View* view) {
   2055   DCHECK(view && descendants_to_notify_.get());
   2056   Views::iterator i(std::find(
   2057       descendants_to_notify_->begin(), descendants_to_notify_->end(), view));
   2058   DCHECK(i != descendants_to_notify_->end());
   2059   descendants_to_notify_->erase(i);
   2060   if (descendants_to_notify_->empty())
   2061     descendants_to_notify_.reset();
   2062 }
   2063 
   2064 void View::SetLayerBounds(const gfx::Rect& bounds) {
   2065   layer()->SetBounds(bounds);
   2066 }
   2067 
   2068 void View::SetRootBoundsDirty(bool origin_changed) {
   2069   root_bounds_dirty_ = true;
   2070 
   2071   if (origin_changed) {
   2072     // Inform our children that their root bounds are dirty, as their relative
   2073     // coordinates in paint root space have changed since ours have changed.
   2074     for (Views::const_iterator i(children_.begin()); i != children_.end();
   2075          ++i) {
   2076       if (!(*i)->IsPaintRoot())
   2077         (*i)->SetRootBoundsDirty(origin_changed);
   2078     }
   2079   }
   2080 }
   2081 
   2082 void View::UpdateRootBounds(BoundsTree* tree, const gfx::Vector2d& offset) {
   2083   // No need to recompute bounds if we haven't flagged ours as dirty.
   2084   TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName());
   2085 
   2086   // Add our own offset to the provided offset, for our own bounds update and
   2087   // for propagation to our children if needed.
   2088   gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin();
   2089 
   2090   // If our bounds have changed we must re-insert our new bounds to the tree.
   2091   if (root_bounds_dirty_) {
   2092     root_bounds_dirty_ = false;
   2093     gfx::Rect bounds(
   2094         view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height());
   2095     tree->Insert(bounds, reinterpret_cast<intptr_t>(this));
   2096   }
   2097 
   2098   // Update our children's bounds if needed.
   2099   for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
   2100     // We don't descend in to layer views for bounds recomputation, as they
   2101     // manage their own RTree as paint roots.
   2102     if (!(*i)->IsPaintRoot())
   2103       (*i)->UpdateRootBounds(tree, view_offset);
   2104   }
   2105 }
   2106 
   2107 void View::RemoveRootBounds(BoundsTree* tree) {
   2108   tree->Remove(reinterpret_cast<intptr_t>(this));
   2109 
   2110   root_bounds_dirty_ = true;
   2111 
   2112   for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
   2113     if (!(*i)->IsPaintRoot())
   2114       (*i)->RemoveRootBounds(tree);
   2115   }
   2116 }
   2117 
   2118 View::BoundsTree* View::GetBoundsTreeFromPaintRoot() {
   2119   BoundsTree* bounds_tree = bounds_tree_.get();
   2120   View* paint_root = this;
   2121   while (!bounds_tree && !paint_root->IsPaintRoot()) {
   2122     // Assumption is that if IsPaintRoot() is false then parent_ is valid.
   2123     DCHECK(paint_root);
   2124     paint_root = paint_root->parent_;
   2125     bounds_tree = paint_root->bounds_tree_.get();
   2126   }
   2127 
   2128   return bounds_tree;
   2129 }
   2130 
   2131 // Transformations -------------------------------------------------------------
   2132 
   2133 bool View::GetTransformRelativeTo(const View* ancestor,
   2134                                   gfx::Transform* transform) const {
   2135   const View* p = this;
   2136 
   2137   while (p && p != ancestor) {
   2138     transform->ConcatTransform(p->GetTransform());
   2139     gfx::Transform translation;
   2140     translation.Translate(static_cast<float>(p->GetMirroredX()),
   2141                           static_cast<float>(p->y()));
   2142     transform->ConcatTransform(translation);
   2143 
   2144     p = p->parent_;
   2145   }
   2146 
   2147   return p == ancestor;
   2148 }
   2149 
   2150 // Coordinate conversion -------------------------------------------------------
   2151 
   2152 bool View::ConvertPointForAncestor(const View* ancestor,
   2153                                    gfx::Point* point) const {
   2154   gfx::Transform trans;
   2155   // TODO(sad): Have some way of caching the transformation results.
   2156   bool result = GetTransformRelativeTo(ancestor, &trans);
   2157   gfx::Point3F p(*point);
   2158   trans.TransformPoint(&p);
   2159   *point = gfx::ToFlooredPoint(p.AsPointF());
   2160   return result;
   2161 }
   2162 
   2163 bool View::ConvertPointFromAncestor(const View* ancestor,
   2164                                     gfx::Point* point) const {
   2165   gfx::Transform trans;
   2166   bool result = GetTransformRelativeTo(ancestor, &trans);
   2167   gfx::Point3F p(*point);
   2168   trans.TransformPointReverse(&p);
   2169   *point = gfx::ToFlooredPoint(p.AsPointF());
   2170   return result;
   2171 }
   2172 
   2173 bool View::ConvertRectForAncestor(const View* ancestor,
   2174                                   gfx::RectF* rect) const {
   2175   gfx::Transform trans;
   2176   // TODO(sad): Have some way of caching the transformation results.
   2177   bool result = GetTransformRelativeTo(ancestor, &trans);
   2178   trans.TransformRect(rect);
   2179   return result;
   2180 }
   2181 
   2182 bool View::ConvertRectFromAncestor(const View* ancestor,
   2183                                    gfx::RectF* rect) const {
   2184   gfx::Transform trans;
   2185   bool result = GetTransformRelativeTo(ancestor, &trans);
   2186   trans.TransformRectReverse(rect);
   2187   return result;
   2188 }
   2189 
   2190 // Accelerated painting --------------------------------------------------------
   2191 
   2192 void View::CreateLayer() {
   2193   // A new layer is being created for the view. So all the layers of the
   2194   // sub-tree can inherit the visibility of the corresponding view.
   2195   for (int i = 0, count = child_count(); i < count; ++i)
   2196     child_at(i)->UpdateChildLayerVisibility(true);
   2197 
   2198   SetLayer(new ui::Layer());
   2199   layer()->set_delegate(this);
   2200 #if !defined(NDEBUG)
   2201   layer()->set_name(GetClassName());
   2202 #endif
   2203 
   2204   UpdateParentLayers();
   2205   UpdateLayerVisibility();
   2206 
   2207   // The new layer needs to be ordered in the layer tree according
   2208   // to the view tree. Children of this layer were added in order
   2209   // in UpdateParentLayers().
   2210   if (parent())
   2211     parent()->ReorderLayers();
   2212 
   2213   Widget* widget = GetWidget();
   2214   if (widget)
   2215     widget->UpdateRootLayers();
   2216 }
   2217 
   2218 void View::UpdateParentLayers() {
   2219   // Attach all top-level un-parented layers.
   2220   if (layer() && !layer()->parent()) {
   2221     UpdateParentLayer();
   2222   } else {
   2223     for (int i = 0, count = child_count(); i < count; ++i)
   2224       child_at(i)->UpdateParentLayers();
   2225   }
   2226 }
   2227 
   2228 void View::OrphanLayers() {
   2229   if (layer()) {
   2230     if (layer()->parent())
   2231       layer()->parent()->Remove(layer());
   2232 
   2233     // The layer belonging to this View has already been orphaned. It is not
   2234     // necessary to orphan the child layers.
   2235     return;
   2236   }
   2237   for (int i = 0, count = child_count(); i < count; ++i)
   2238     child_at(i)->OrphanLayers();
   2239 }
   2240 
   2241 void View::ReparentLayer(const gfx::Vector2d& offset, ui::Layer* parent_layer) {
   2242   layer()->SetBounds(GetLocalBounds() + offset);
   2243   DCHECK_NE(layer(), parent_layer);
   2244   if (parent_layer)
   2245     parent_layer->Add(layer());
   2246   layer()->SchedulePaint(GetLocalBounds());
   2247   MoveLayerToParent(layer(), gfx::Point());
   2248 }
   2249 
   2250 void View::DestroyLayer() {
   2251   ui::Layer* new_parent = layer()->parent();
   2252   std::vector<ui::Layer*> children = layer()->children();
   2253   for (size_t i = 0; i < children.size(); ++i) {
   2254     layer()->Remove(children[i]);
   2255     if (new_parent)
   2256       new_parent->Add(children[i]);
   2257   }
   2258 
   2259   LayerOwner::DestroyLayer();
   2260 
   2261   if (new_parent)
   2262     ReorderLayers();
   2263 
   2264   UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(NULL));
   2265 
   2266   SchedulePaint();
   2267 
   2268   Widget* widget = GetWidget();
   2269   if (widget)
   2270     widget->UpdateRootLayers();
   2271 }
   2272 
   2273 // Input -----------------------------------------------------------------------
   2274 
   2275 bool View::ProcessMousePressed(const ui::MouseEvent& event) {
   2276   int drag_operations =
   2277       (enabled_ && event.IsOnlyLeftMouseButton() &&
   2278        HitTestPoint(event.location())) ?
   2279        GetDragOperations(event.location()) : 0;
   2280   ContextMenuController* context_menu_controller = event.IsRightMouseButton() ?
   2281       context_menu_controller_ : 0;
   2282   View::DragInfo* drag_info = GetDragInfo();
   2283 
   2284   // TODO(sky): for debugging 360238.
   2285   int storage_id = 0;
   2286   if (event.IsOnlyRightMouseButton() && context_menu_controller &&
   2287       kContextMenuOnMousePress && HitTestPoint(event.location())) {
   2288     ViewStorage* view_storage = ViewStorage::GetInstance();
   2289     storage_id = view_storage->CreateStorageID();
   2290     view_storage->StoreView(storage_id, this);
   2291   }
   2292 
   2293   const bool enabled = enabled_;
   2294   const bool result = OnMousePressed(event);
   2295 
   2296   if (!enabled)
   2297     return result;
   2298 
   2299   if (event.IsOnlyRightMouseButton() && context_menu_controller &&
   2300       kContextMenuOnMousePress) {
   2301     // Assume that if there is a context menu controller we won't be deleted
   2302     // from mouse pressed.
   2303     gfx::Point location(event.location());
   2304     if (HitTestPoint(location)) {
   2305       if (storage_id != 0)
   2306         CHECK_EQ(this, ViewStorage::GetInstance()->RetrieveView(storage_id));
   2307       ConvertPointToScreen(this, &location);
   2308       ShowContextMenu(location, ui::MENU_SOURCE_MOUSE);
   2309       return true;
   2310     }
   2311   }
   2312 
   2313   // WARNING: we may have been deleted, don't use any View variables.
   2314   if (drag_operations != ui::DragDropTypes::DRAG_NONE) {
   2315     drag_info->PossibleDrag(event.location());
   2316     return true;
   2317   }
   2318   return !!context_menu_controller || result;
   2319 }
   2320 
   2321 bool View::ProcessMouseDragged(const ui::MouseEvent& event) {
   2322   // Copy the field, that way if we're deleted after drag and drop no harm is
   2323   // done.
   2324   ContextMenuController* context_menu_controller = context_menu_controller_;
   2325   const bool possible_drag = GetDragInfo()->possible_drag;
   2326   if (possible_drag &&
   2327       ExceededDragThreshold(GetDragInfo()->start_pt - event.location()) &&
   2328       (!drag_controller_ ||
   2329        drag_controller_->CanStartDragForView(
   2330            this, GetDragInfo()->start_pt, event.location()))) {
   2331     DoDrag(event, GetDragInfo()->start_pt,
   2332            ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   2333   } else {
   2334     if (OnMouseDragged(event))
   2335       return true;
   2336     // Fall through to return value based on context menu controller.
   2337   }
   2338   // WARNING: we may have been deleted.
   2339   return (context_menu_controller != NULL) || possible_drag;
   2340 }
   2341 
   2342 void View::ProcessMouseReleased(const ui::MouseEvent& event) {
   2343   if (!kContextMenuOnMousePress && context_menu_controller_ &&
   2344       event.IsOnlyRightMouseButton()) {
   2345     // Assume that if there is a context menu controller we won't be deleted
   2346     // from mouse released.
   2347     gfx::Point location(event.location());
   2348     OnMouseReleased(event);
   2349     if (HitTestPoint(location)) {
   2350       ConvertPointToScreen(this, &location);
   2351       ShowContextMenu(location, ui::MENU_SOURCE_MOUSE);
   2352     }
   2353   } else {
   2354     OnMouseReleased(event);
   2355   }
   2356   // WARNING: we may have been deleted.
   2357 }
   2358 
   2359 // Accelerators ----------------------------------------------------------------
   2360 
   2361 void View::RegisterPendingAccelerators() {
   2362   if (!accelerators_.get() ||
   2363       registered_accelerator_count_ == accelerators_->size()) {
   2364     // No accelerators are waiting for registration.
   2365     return;
   2366   }
   2367 
   2368   if (!GetWidget()) {
   2369     // The view is not yet attached to a widget, defer registration until then.
   2370     return;
   2371   }
   2372 
   2373   accelerator_focus_manager_ = GetFocusManager();
   2374   if (!accelerator_focus_manager_) {
   2375     // Some crash reports seem to show that we may get cases where we have no
   2376     // focus manager (see bug #1291225).  This should never be the case, just
   2377     // making sure we don't crash.
   2378     NOTREACHED();
   2379     return;
   2380   }
   2381   for (std::vector<ui::Accelerator>::const_iterator i(
   2382            accelerators_->begin() + registered_accelerator_count_);
   2383        i != accelerators_->end(); ++i) {
   2384     accelerator_focus_manager_->RegisterAccelerator(
   2385         *i, ui::AcceleratorManager::kNormalPriority, this);
   2386   }
   2387   registered_accelerator_count_ = accelerators_->size();
   2388 }
   2389 
   2390 void View::UnregisterAccelerators(bool leave_data_intact) {
   2391   if (!accelerators_.get())
   2392     return;
   2393 
   2394   if (GetWidget()) {
   2395     if (accelerator_focus_manager_) {
   2396       accelerator_focus_manager_->UnregisterAccelerators(this);
   2397       accelerator_focus_manager_ = NULL;
   2398     }
   2399     if (!leave_data_intact) {
   2400       accelerators_->clear();
   2401       accelerators_.reset();
   2402     }
   2403     registered_accelerator_count_ = 0;
   2404   }
   2405 }
   2406 
   2407 // Focus -----------------------------------------------------------------------
   2408 
   2409 void View::InitFocusSiblings(View* v, int index) {
   2410   int count = child_count();
   2411 
   2412   if (count == 0) {
   2413     v->next_focusable_view_ = NULL;
   2414     v->previous_focusable_view_ = NULL;
   2415   } else {
   2416     if (index == count) {
   2417       // We are inserting at the end, but the end of the child list may not be
   2418       // the last focusable element. Let's try to find an element with no next
   2419       // focusable element to link to.
   2420       View* last_focusable_view = NULL;
   2421       for (Views::iterator i(children_.begin()); i != children_.end(); ++i) {
   2422           if (!(*i)->next_focusable_view_) {
   2423             last_focusable_view = *i;
   2424             break;
   2425           }
   2426       }
   2427       if (last_focusable_view == NULL) {
   2428         // Hum... there is a cycle in the focus list. Let's just insert ourself
   2429         // after the last child.
   2430         View* prev = children_[index - 1];
   2431         v->previous_focusable_view_ = prev;
   2432         v->next_focusable_view_ = prev->next_focusable_view_;
   2433         prev->next_focusable_view_->previous_focusable_view_ = v;
   2434         prev->next_focusable_view_ = v;
   2435       } else {
   2436         last_focusable_view->next_focusable_view_ = v;
   2437         v->next_focusable_view_ = NULL;
   2438         v->previous_focusable_view_ = last_focusable_view;
   2439       }
   2440     } else {
   2441       View* prev = children_[index]->GetPreviousFocusableView();
   2442       v->previous_focusable_view_ = prev;
   2443       v->next_focusable_view_ = children_[index];
   2444       if (prev)
   2445         prev->next_focusable_view_ = v;
   2446       children_[index]->previous_focusable_view_ = v;
   2447     }
   2448   }
   2449 }
   2450 
   2451 // System events ---------------------------------------------------------------
   2452 
   2453 void View::PropagateThemeChanged() {
   2454   for (int i = child_count() - 1; i >= 0; --i)
   2455     child_at(i)->PropagateThemeChanged();
   2456   OnThemeChanged();
   2457 }
   2458 
   2459 void View::PropagateLocaleChanged() {
   2460   for (int i = child_count() - 1; i >= 0; --i)
   2461     child_at(i)->PropagateLocaleChanged();
   2462   OnLocaleChanged();
   2463 }
   2464 
   2465 // Tooltips --------------------------------------------------------------------
   2466 
   2467 void View::UpdateTooltip() {
   2468   Widget* widget = GetWidget();
   2469   // TODO(beng): The TooltipManager NULL check can be removed when we
   2470   //             consolidate Init() methods and make views_unittests Init() all
   2471   //             Widgets that it uses.
   2472   if (widget && widget->GetTooltipManager())
   2473     widget->GetTooltipManager()->UpdateTooltip();
   2474 }
   2475 
   2476 // Drag and drop ---------------------------------------------------------------
   2477 
   2478 bool View::DoDrag(const ui::LocatedEvent& event,
   2479                   const gfx::Point& press_pt,
   2480                   ui::DragDropTypes::DragEventSource source) {
   2481   int drag_operations = GetDragOperations(press_pt);
   2482   if (drag_operations == ui::DragDropTypes::DRAG_NONE)
   2483     return false;
   2484 
   2485   Widget* widget = GetWidget();
   2486   // We should only start a drag from an event, implying we have a widget.
   2487   DCHECK(widget);
   2488 
   2489   // Don't attempt to start a drag while in the process of dragging. This is
   2490   // especially important on X where we can get multiple mouse move events when
   2491   // we start the drag.
   2492   if (widget->dragged_view())
   2493     return false;
   2494 
   2495   OSExchangeData data;
   2496   WriteDragData(press_pt, &data);
   2497 
   2498   // Message the RootView to do the drag and drop. That way if we're removed
   2499   // the RootView can detect it and avoid calling us back.
   2500   gfx::Point widget_location(event.location());
   2501   ConvertPointToWidget(this, &widget_location);
   2502   widget->RunShellDrag(this, data, widget_location, drag_operations, source);
   2503   // WARNING: we may have been deleted.
   2504   return true;
   2505 }
   2506 
   2507 }  // namespace views
   2508