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