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