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