summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authortfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 23:35:20 +0000
committertfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 23:35:20 +0000
commit5025f86107dafec51f98c62dbdc996fbb703a361 (patch)
treea871aad5635c650c243b44b59d1802f79f590458 /views
parent5c9a1adb03e4e0059e25366a908f30dd28786790 (diff)
downloadchromium_src-5025f86107dafec51f98c62dbdc996fbb703a361.zip
chromium_src-5025f86107dafec51f98c62dbdc996fbb703a361.tar.gz
chromium_src-5025f86107dafec51f98c62dbdc996fbb703a361.tar.bz2
views: Move view.h to ui/views/.
BUG=104039 R=ben@chromium.org TBR=stevenjb@chromium.org Review URL: http://codereview.chromium.org/8742030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112333 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/accessible_pane_view.h2
-rw-r--r--views/background.cc2
-rw-r--r--views/border.h2
-rw-r--r--views/paint_lock.cc2
-rw-r--r--views/run_all_unittests.cc2
-rw-r--r--views/view.cc2061
-rw-r--r--views/view.h1440
-rw-r--r--views/view_aura.cc37
-rw-r--r--views/view_gtk.cc39
-rw-r--r--views/view_unittest.cc3068
-rw-r--r--views/view_win.cc36
-rw-r--r--views/views.gyp12
12 files changed, 11 insertions, 6692 deletions
diff --git a/views/accessible_pane_view.h b/views/accessible_pane_view.h
index 655ebd9..104294e 100644
--- a/views/accessible_pane_view.h
+++ b/views/accessible_pane_view.h
@@ -11,7 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/views/focus/focus_manager.h"
-#include "views/view.h"
+#include "ui/views/view.h"
namespace views {
class FocusSearch;
diff --git a/views/background.cc b/views/background.cc
index fa79793..717261d 100644
--- a/views/background.cc
+++ b/views/background.cc
@@ -9,8 +9,8 @@
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/gfx/canvas_skia.h"
#include "ui/gfx/color_utils.h"
+#include "ui/views/view.h"
#include "views/painter.h"
-#include "views/view.h"
namespace views {
diff --git a/views/border.h b/views/border.h
index 27a46c6..fc7bdc4 100644
--- a/views/border.h
+++ b/views/border.h
@@ -8,7 +8,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/insets.h"
-#include "views/view.h"
+#include "ui/views/view.h"
namespace gfx{
class Canvas;
diff --git a/views/paint_lock.cc b/views/paint_lock.cc
index 282c2c3..3b2ce1d 100644
--- a/views/paint_lock.cc
+++ b/views/paint_lock.cc
@@ -4,7 +4,7 @@
#include "views/paint_lock.h"
-#include "views/view.h"
+#include "ui/views/view.h"
namespace views {
diff --git a/views/run_all_unittests.cc b/views/run_all_unittests.cc
index 083d4a8..e675291 100644
--- a/views/run_all_unittests.cc
+++ b/views/run_all_unittests.cc
@@ -7,7 +7,7 @@
#include "ui/base/ui_base_paths.h"
#include "ui/gfx/compositor/test/compositor_test_support.h"
#include "ui/gfx/test/gfx_test_utils.h"
-#include "views/view.h"
+#include "ui/views/view.h"
class ViewTestSuite : public base::TestSuite {
public:
diff --git a/views/view.cc b/views/view.cc
deleted file mode 100644
index 6a0db83..0000000
--- a/views/view.cc
+++ /dev/null
@@ -1,2061 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/view.h"
-
-#include <algorithm>
-
-#include "base/debug/trace_event.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "ui/base/accessibility/accessibility_types.h"
-#include "ui/base/dragdrop/drag_drop_types.h"
-#include "ui/gfx/canvas_skia.h"
-#include "ui/gfx/compositor/compositor.h"
-#include "ui/gfx/compositor/layer.h"
-#include "ui/gfx/compositor/layer_animator.h"
-#include "ui/gfx/interpolated_transform.h"
-#include "ui/gfx/path.h"
-#include "ui/gfx/point3.h"
-#include "ui/gfx/transform.h"
-#include "ui/views/context_menu_controller.h"
-#include "ui/views/drag_controller.h"
-#include "ui/views/layout/layout_manager.h"
-#include "ui/views/widget/native_widget_private.h"
-#include "ui/views/widget/root_view.h"
-#include "ui/views/widget/tooltip_manager.h"
-#include "ui/views/widget/widget.h"
-#include "views/background.h"
-#include "views/views_delegate.h"
-
-#if defined(OS_WIN)
-#include "base/win/scoped_gdi_object.h"
-#include "ui/views/accessibility/native_view_accessibility_win.h"
-#endif
-#if defined(TOOLKIT_USES_GTK)
-#include "ui/base/gtk/scoped_handle_gtk.h"
-#endif
-
-namespace {
-
-// Whether to use accelerated compositing when necessary (e.g. when a view has a
-// transformation).
-#if defined(VIEWS_COMPOSITOR)
-bool use_acceleration_when_possible = true;
-#else
-bool use_acceleration_when_possible = false;
-#endif
-
-// Saves the drawing state, and restores the state when going out of scope.
-class ScopedCanvas {
- public:
- explicit ScopedCanvas(gfx::Canvas* canvas) : canvas_(canvas) {
- if (canvas_)
- canvas_->Save();
- }
- ~ScopedCanvas() {
- if (canvas_)
- canvas_->Restore();
- }
- void SetCanvas(gfx::Canvas* canvas) {
- if (canvas_)
- canvas_->Restore();
- canvas_ = canvas;
- canvas_->Save();
- }
-
- private:
- gfx::Canvas* canvas_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedCanvas);
-};
-
-// Returns the top view in |view|'s hierarchy.
-const views::View* GetHierarchyRoot(const views::View* view) {
- const views::View* root = view;
- while (root && root->parent())
- root = root->parent();
- return root;
-}
-
-} // namespace
-
-namespace views {
-
-// static
-ViewsDelegate* ViewsDelegate::views_delegate = NULL;
-
-// static
-const char View::kViewClassName[] = "views/View";
-
-////////////////////////////////////////////////////////////////////////////////
-// View, public:
-
-// TO BE MOVED -----------------------------------------------------------------
-
-void View::SetHotTracked(bool flag) {
-}
-
-bool View::IsHotTracked() const {
- return false;
-}
-
-// Creation and lifetime -------------------------------------------------------
-
-View::View()
- : parent_owned_(true),
- id_(0),
- group_(-1),
- parent_(NULL),
- visible_(true),
- enabled_(true),
- painting_enabled_(true),
- registered_for_visible_bounds_notification_(false),
- clip_x_(0.0),
- clip_y_(0.0),
- needs_layout_(true),
- flip_canvas_on_paint_for_rtl_ui_(false),
- paint_to_layer_(false),
- accelerator_registration_delayed_(false),
- accelerator_focus_manager_(NULL),
- registered_accelerator_count_(0),
- next_focusable_view_(NULL),
- previous_focusable_view_(NULL),
- focusable_(false),
- accessibility_focusable_(false),
- context_menu_controller_(NULL),
- drag_controller_(NULL) {
-}
-
-View::~View() {
- if (parent_)
- parent_->RemoveChildView(this);
-
- for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
- (*i)->parent_ = NULL;
- if ((*i)->parent_owned())
- delete *i;
- }
-
-#if defined(OS_WIN)
- if (native_view_accessibility_win_.get())
- native_view_accessibility_win_->set_view(NULL);
-#endif
-}
-
-// Tree operations -------------------------------------------------------------
-
-const Widget* View::GetWidget() const {
- // The root view holds a reference to this view hierarchy's Widget.
- return parent_ ? parent_->GetWidget() : NULL;
-}
-
-Widget* View::GetWidget() {
- return const_cast<Widget*>(const_cast<const View*>(this)->GetWidget());
-}
-
-void View::AddChildView(View* view) {
- AddChildViewAt(view, child_count());
-}
-
-void View::AddChildViewAt(View* view, int index) {
- CHECK_NE(view, this) << "You cannot add a view as its own child";
-
- // If |view| has a parent, remove it from its parent.
- View* parent = view->parent_;
- if (parent)
- parent->RemoveChildView(view);
-
- // Sets the prev/next focus views.
- InitFocusSiblings(view, index);
-
- // Let's insert the view.
- view->parent_ = this;
- children_.insert(children_.begin() + index, view);
-
- for (View* v = this; v; v = v->parent_)
- v->ViewHierarchyChangedImpl(false, true, this, view);
-
- view->PropagateAddNotifications(this, view);
- UpdateTooltip();
- if (GetWidget())
- RegisterChildrenForVisibleBoundsNotification(view);
-
- if (layout_manager_.get())
- layout_manager_->ViewAdded(this, view);
-
- if (use_acceleration_when_possible)
- ReorderLayers();
-
- // Make sure the visibility of the child layers are correct.
- // If any of the parent View is hidden, then the layers of the subtree
- // rooted at |this| should be hidden. Otherwise, all the child layers should
- // inherit the visibility of the owner View.
- UpdateLayerVisibility();
-}
-
-void View::ReorderChildView(View* view, int index) {
- DCHECK_EQ(view->parent_, this);
- if (index < 0)
- index = child_count() - 1;
- else if (index >= child_count())
- return;
- if (children_[index] == view)
- return;
-
- const Views::iterator i(std::find(children_.begin(), children_.end(), view));
- DCHECK(i != children_.end());
- children_.erase(i);
-
- // Unlink the view first
- View* next_focusable = view->next_focusable_view_;
- View* prev_focusable = view->previous_focusable_view_;
- if (prev_focusable)
- prev_focusable->next_focusable_view_ = next_focusable;
- if (next_focusable)
- next_focusable->previous_focusable_view_ = prev_focusable;
-
- // Add it in the specified index now.
- InitFocusSiblings(view, index);
- children_.insert(children_.begin() + index, view);
-
- if (use_acceleration_when_possible)
- ReorderLayers();
-}
-
-void View::RemoveChildView(View* view) {
- DoRemoveChildView(view, true, true, false);
-}
-
-void View::RemoveAllChildViews(bool delete_children) {
- while (!children_.empty())
- DoRemoveChildView(children_.front(), false, false, delete_children);
- UpdateTooltip();
-}
-
-bool View::Contains(const View* view) const {
- for (const View* v = view; v; v = v->parent_) {
- if (v == this)
- return true;
- }
- return false;
-}
-
-int View::GetIndexOf(const View* view) const {
- Views::const_iterator i(std::find(children_.begin(), children_.end(), view));
- return i != children_.end() ? static_cast<int>(i - children_.begin()) : -1;
-}
-
-// Size and disposition --------------------------------------------------------
-
-void View::SetBounds(int x, int y, int width, int height) {
- SetBoundsRect(gfx::Rect(x, y, std::max(0, width), std::max(0, height)));
-}
-
-void View::SetBoundsRect(const gfx::Rect& bounds) {
- if (bounds == bounds_) {
- if (needs_layout_) {
- needs_layout_ = false;
- Layout();
- SchedulePaint();
- }
- return;
- }
-
- if (IsVisible()) {
- // Paint where the view is currently.
- SchedulePaintBoundsChanged(
- bounds_.size() == bounds.size() ? SCHEDULE_PAINT_SIZE_SAME :
- SCHEDULE_PAINT_SIZE_CHANGED);
- }
-
- gfx::Rect prev = bounds_;
- bounds_ = bounds;
- BoundsChanged(prev);
-}
-
-void View::SetSize(const gfx::Size& size) {
- SetBounds(x(), y(), size.width(), size.height());
-}
-
-void View::SetPosition(const gfx::Point& position) {
- SetBounds(position.x(), position.y(), width(), height());
-}
-
-void View::SetX(int x) {
- SetBounds(x, y(), width(), height());
-}
-
-void View::SetY(int y) {
- SetBounds(x(), y, width(), height());
-}
-
-gfx::Rect View::GetContentsBounds() const {
- gfx::Rect contents_bounds(GetLocalBounds());
- if (border_.get()) {
- gfx::Insets insets;
- border_->GetInsets(&insets);
- contents_bounds.Inset(insets);
- }
- return contents_bounds;
-}
-
-gfx::Rect View::GetLocalBounds() const {
- return gfx::Rect(gfx::Point(), size());
-}
-
-gfx::Insets View::GetInsets() const {
- gfx::Insets insets;
- if (border_.get())
- border_->GetInsets(&insets);
- return insets;
-}
-
-gfx::Rect View::GetVisibleBounds() const {
- if (!IsVisibleInRootView())
- return gfx::Rect();
- gfx::Rect vis_bounds(0, 0, width(), height());
- gfx::Rect ancestor_bounds;
- const View* view = this;
- ui::Transform transform;
-
- while (view != NULL && !vis_bounds.IsEmpty()) {
- transform.ConcatTransform(view->GetTransform());
- transform.ConcatTranslate(static_cast<float>(view->GetMirroredX()),
- static_cast<float>(view->y()));
-
- vis_bounds = view->ConvertRectToParent(vis_bounds);
- const View* ancestor = view->parent_;
- if (ancestor != NULL) {
- ancestor_bounds.SetRect(0, 0, ancestor->width(), ancestor->height());
- vis_bounds = vis_bounds.Intersect(ancestor_bounds);
- } else if (!view->GetWidget()) {
- // If the view has no Widget, we're not visible. Return an empty rect.
- return gfx::Rect();
- }
- view = ancestor;
- }
- if (vis_bounds.IsEmpty())
- return vis_bounds;
- // Convert back to this views coordinate system.
- transform.TransformRectReverse(&vis_bounds);
- return vis_bounds;
-}
-
-gfx::Rect View::GetScreenBounds() const {
- gfx::Point origin;
- View::ConvertPointToScreen(this, &origin);
- return gfx::Rect(origin, size());
-}
-
-gfx::Size View::GetPreferredSize() {
- if (layout_manager_.get())
- return layout_manager_->GetPreferredSize(this);
- return gfx::Size();
-}
-
-int View::GetBaseline() const {
- return -1;
-}
-
-void View::SizeToPreferredSize() {
- gfx::Size prefsize = GetPreferredSize();
- if ((prefsize.width() != width()) || (prefsize.height() != height()))
- SetBounds(x(), y(), prefsize.width(), prefsize.height());
-}
-
-gfx::Size View::GetMinimumSize() {
- return GetPreferredSize();
-}
-
-int View::GetHeightForWidth(int w) {
- if (layout_manager_.get())
- return layout_manager_->GetPreferredHeightForWidth(this, w);
- return GetPreferredSize().height();
-}
-
-void View::SetVisible(bool visible) {
- if (visible != visible_) {
- // If the View is currently visible, schedule paint to refresh parent.
- // TODO(beng): not sure we should be doing this if we have a layer.
- if (visible_)
- SchedulePaint();
-
- visible_ = visible;
-
- // This notifies all sub-views recursively.
- PropagateVisibilityNotifications(this, visible_);
- UpdateLayerVisibility();
-
- // If we are newly visible, schedule paint.
- if (visible_)
- SchedulePaint();
- }
-}
-
-bool View::IsVisible() const {
- return visible_;
-}
-
-bool View::IsVisibleInRootView() const {
- return IsVisible() && parent_ ? parent_->IsVisibleInRootView() : false;
-}
-
-void View::SetEnabled(bool enabled) {
- if (enabled != enabled_) {
- enabled_ = enabled;
- OnEnabledChanged();
- }
-}
-
-bool View::IsEnabled() const {
- return enabled_;
-}
-
-void View::OnEnabledChanged() {
- SchedulePaint();
-}
-
-// Transformations -------------------------------------------------------------
-
-const ui::Transform& View::GetTransform() const {
- static const ui::Transform* no_op = new ui::Transform;
- return layer() ? layer()->transform() : *no_op;
-}
-
-void View::SetTransform(const ui::Transform& transform) {
- if (!transform.HasChange()) {
- if (layer()) {
- layer()->SetTransform(transform);
- if (!paint_to_layer_)
- DestroyLayer();
- } else {
- // Nothing.
- }
- } else {
- if (!layer())
- CreateLayer();
- layer()->SetTransform(transform);
- layer()->ScheduleDraw();
- }
-}
-
-void View::SetPaintToLayer(bool paint_to_layer) {
- paint_to_layer_ = paint_to_layer;
- if (paint_to_layer_ && !layer()) {
- CreateLayer();
- } else if (!paint_to_layer_ && layer()) {
- DestroyLayer();
- }
-}
-
-// RTL positioning -------------------------------------------------------------
-
-gfx::Rect View::GetMirroredBounds() const {
- gfx::Rect bounds(bounds_);
- bounds.set_x(GetMirroredX());
- return bounds;
-}
-
-gfx::Point View::GetMirroredPosition() const {
- return gfx::Point(GetMirroredX(), y());
-}
-
-int View::GetMirroredX() const {
- return parent_ ? parent_->GetMirroredXForRect(bounds_) : x();
-}
-
-int View::GetMirroredXForRect(const gfx::Rect& bounds) const {
- return base::i18n::IsRTL() ?
- (width() - bounds.x() - bounds.width()) : bounds.x();
-}
-
-int View::GetMirroredXInView(int x) const {
- return base::i18n::IsRTL() ? width() - x : x;
-}
-
-int View::GetMirroredXWithWidthInView(int x, int w) const {
- return base::i18n::IsRTL() ? width() - x - w : x;
-}
-
-// Layout ----------------------------------------------------------------------
-
-void View::Layout() {
- needs_layout_ = false;
-
- // If we have a layout manager, let it handle the layout for us.
- if (layout_manager_.get())
- layout_manager_->Layout(this);
-
- // Make sure to propagate the Layout() call to any children that haven't
- // received it yet through the layout manager and need to be laid out. This
- // is needed for the case when the child requires a layout but its bounds
- // weren't changed by the layout manager. If there is no layout manager, we
- // just propagate the Layout() call down the hierarchy, so whoever receives
- // the call can take appropriate action.
- for (int i = 0, count = child_count(); i < count; ++i) {
- View* child = child_at(i);
- if (child->needs_layout_ || !layout_manager_.get()) {
- child->needs_layout_ = false;
- child->Layout();
- }
- }
-}
-
-void View::InvalidateLayout() {
- // Always invalidate up. This is needed to handle the case of us already being
- // valid, but not our parent.
- needs_layout_ = true;
- if (parent_)
- parent_->InvalidateLayout();
-}
-
-LayoutManager* View::GetLayoutManager() const {
- return layout_manager_.get();
-}
-
-void View::SetLayoutManager(LayoutManager* layout_manager) {
- if (layout_manager_.get())
- layout_manager_->Uninstalled(this);
-
- layout_manager_.reset(layout_manager);
- if (layout_manager_.get())
- layout_manager_->Installed(this);
-}
-
-// Attributes ------------------------------------------------------------------
-
-std::string View::GetClassName() const {
- return kViewClassName;
-}
-
-View* View::GetAncestorWithClassName(const std::string& name) {
- for (View* view = this; view; view = view->parent_) {
- if (view->GetClassName() == name)
- return view;
- }
- return NULL;
-}
-
-const View* View::GetViewByID(int id) const {
- if (id == id_)
- return const_cast<View*>(this);
-
- for (int i = 0, count = child_count(); i < count; ++i) {
- const View* view = child_at(i)->GetViewByID(id);
- if (view)
- return view;
- }
- return NULL;
-}
-
-View* View::GetViewByID(int id) {
- return const_cast<View*>(const_cast<const View*>(this)->GetViewByID(id));
-}
-
-void View::SetGroup(int gid) {
- // Don't change the group id once it's set.
- DCHECK(group_ == -1 || group_ == gid);
- group_ = gid;
-}
-
-int View::GetGroup() const {
- return group_;
-}
-
-bool View::IsGroupFocusTraversable() const {
- return true;
-}
-
-void View::GetViewsInGroup(int group, Views* views) {
- if (group_ == group)
- views->push_back(this);
-
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->GetViewsInGroup(group, views);
-}
-
-View* View::GetSelectedViewForGroup(int group) {
- Views views;
- GetWidget()->GetRootView()->GetViewsInGroup(group, &views);
- return views.empty() ? NULL : views[0];
-}
-
-// Coordinate conversion -------------------------------------------------------
-
-// static
-void View::ConvertPointToView(const View* source,
- const View* target,
- gfx::Point* point) {
- if (source == target)
- return;
-
- // |source| can be NULL.
- const View* root = GetHierarchyRoot(target);
- if (source) {
- CHECK_EQ(GetHierarchyRoot(source), root);
-
- if (source != root)
- source->ConvertPointForAncestor(root, point);
- }
-
- if (target != root)
- target->ConvertPointFromAncestor(root, point);
-
- // API defines NULL |source| as returning the point in screen coordinates.
- if (!source) {
- *point = point->Subtract(
- root->GetWidget()->GetClientAreaScreenBounds().origin());
- }
-}
-
-// static
-void View::ConvertPointToWidget(const View* src, gfx::Point* p) {
- DCHECK(src);
- DCHECK(p);
-
- src->ConvertPointForAncestor(NULL, p);
-}
-
-// static
-void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) {
- DCHECK(dest);
- DCHECK(p);
-
- dest->ConvertPointFromAncestor(NULL, p);
-}
-
-// static
-void View::ConvertPointToScreen(const View* src, gfx::Point* p) {
- DCHECK(src);
- DCHECK(p);
-
- // If the view is not connected to a tree, there's nothing we can do.
- const Widget* widget = src->GetWidget();
- if (widget) {
- ConvertPointToWidget(src, p);
- gfx::Rect r = widget->GetClientAreaScreenBounds();
- p->SetPoint(p->x() + r.x(), p->y() + r.y());
- }
-}
-
-gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
- gfx::Rect x_rect = rect;
- GetTransform().TransformRect(&x_rect);
- x_rect.Offset(GetMirroredPosition());
- return x_rect;
-}
-
-gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const {
- gfx::Rect x_rect = rect;
- for (const View* v = this; v; v = v->parent_)
- x_rect = v->ConvertRectToParent(x_rect);
- return x_rect;
-}
-
-// Painting --------------------------------------------------------------------
-
-void View::SchedulePaint() {
- SchedulePaintInRect(GetLocalBounds());
-}
-
-void View::SchedulePaintInRect(const gfx::Rect& rect) {
- if (!IsVisible() || !painting_enabled_)
- return;
-
- if (layer()) {
- layer()->SchedulePaint(rect);
- } else if (parent_) {
- // Translate the requested paint rect to the parent's coordinate system
- // then pass this notification up to the parent.
- parent_->SchedulePaintInRect(ConvertRectToParent(rect));
- }
-}
-
-void View::Paint(gfx::Canvas* canvas) {
- TRACE_EVENT0("views", "View::Paint");
-
- ScopedCanvas scoped_canvas(canvas);
-
- // Paint this View and its children, setting the clip rect to the bounds
- // of this View and translating the origin to the local bounds' top left
- // point.
- //
- // Note that the X (or left) position we pass to ClipRectInt takes into
- // consideration whether or not the view uses a right-to-left layout so that
- // we paint our view in its mirrored position if need be.
- if (!canvas->ClipRect(gfx::Rect(GetMirroredX(), y(),
- width() - static_cast<int>(clip_x_),
- height() - static_cast<int>(clip_y_)))) {
- return;
- }
- // Non-empty clip, translate the graphics such that 0,0 corresponds to
- // where this view is located (related to its parent).
- canvas->Translate(GetMirroredPosition());
- canvas->Transform(GetTransform());
-
- PaintCommon(canvas);
-}
-
-ThemeProvider* View::GetThemeProvider() const {
- const Widget* widget = GetWidget();
- return widget ? widget->GetThemeProvider() : NULL;
-}
-
-// Accelerated Painting --------------------------------------------------------
-
-// static
-void View::set_use_acceleration_when_possible(bool use) {
- use_acceleration_when_possible = use;
-}
-
-// static
-bool View::get_use_acceleration_when_possible() {
- return use_acceleration_when_possible;
-}
-
-// Input -----------------------------------------------------------------------
-
-View* View::GetEventHandlerForPoint(const gfx::Point& point) {
- // Walk the child Views recursively looking for the View that most
- // tightly encloses the specified point.
- for (int i = child_count() - 1; i >= 0; --i) {
- View* child = child_at(i);
- if (!child->IsVisible())
- continue;
-
- gfx::Point point_in_child_coords(point);
- View::ConvertPointToView(this, child, &point_in_child_coords);
- if (child->HitTest(point_in_child_coords))
- return child->GetEventHandlerForPoint(point_in_child_coords);
- }
- return this;
-}
-
-gfx::NativeCursor View::GetCursor(const MouseEvent& event) {
-#if defined(OS_WIN) && !defined(USE_AURA)
- static HCURSOR arrow = LoadCursor(NULL, IDC_ARROW);
- return arrow;
-#else
- return gfx::kNullCursor;
-#endif
-}
-
-bool View::HitTest(const gfx::Point& l) const {
- if (GetLocalBounds().Contains(l)) {
- if (HasHitTestMask()) {
- gfx::Path mask;
- GetHitTestMask(&mask);
-#if defined(USE_AURA)
- // TODO: should we use this every where?
- SkRegion clip_region;
- clip_region.setRect(0, 0, width(), height());
- SkRegion mask_region;
- return mask_region.setPath(mask, clip_region) &&
- mask_region.contains(l.x(), l.y());
-#elif defined(OS_WIN)
- base::win::ScopedRegion rgn(mask.CreateNativeRegion());
- return !!PtInRegion(rgn, l.x(), l.y());
-#elif defined(TOOLKIT_USES_GTK)
- ui::ScopedRegion rgn(mask.CreateNativeRegion());
- return gdk_region_point_in(rgn.Get(), l.x(), l.y());
-#endif
- }
- // No mask, but inside our bounds.
- return true;
- }
- // Outside our bounds.
- return false;
-}
-
-bool View::OnMousePressed(const MouseEvent& event) {
- return false;
-}
-
-bool View::OnMouseDragged(const MouseEvent& event) {
- return false;
-}
-
-void View::OnMouseReleased(const MouseEvent& event) {
-}
-
-void View::OnMouseCaptureLost() {
-}
-
-void View::OnMouseMoved(const MouseEvent& event) {
-}
-
-void View::OnMouseEntered(const MouseEvent& event) {
-}
-
-void View::OnMouseExited(const MouseEvent& event) {
-}
-
-ui::TouchStatus View::OnTouchEvent(const TouchEvent& event) {
- DVLOG(1) << "visited the OnTouchEvent";
- return ui::TOUCH_STATUS_UNKNOWN;
-}
-
-void View::SetMouseHandler(View *new_mouse_handler) {
- // It is valid for new_mouse_handler to be NULL
- if (parent_)
- parent_->SetMouseHandler(new_mouse_handler);
-}
-
-bool View::OnKeyPressed(const KeyEvent& event) {
- return false;
-}
-
-bool View::OnKeyReleased(const KeyEvent& event) {
- return false;
-}
-
-bool View::OnMouseWheel(const MouseWheelEvent& event) {
- return false;
-}
-
-ui::TextInputClient* View::GetTextInputClient() {
- return NULL;
-}
-
-InputMethod* View::GetInputMethod() {
- Widget* widget = GetWidget();
- return widget ? widget->GetInputMethod() : NULL;
-}
-
-// Accelerators ----------------------------------------------------------------
-
-void View::AddAccelerator(const ui::Accelerator& accelerator) {
- if (!accelerators_.get())
- accelerators_.reset(new std::vector<ui::Accelerator>());
-
- DCHECK(std::find(accelerators_->begin(), accelerators_->end(), accelerator) ==
- accelerators_->end())
- << "Registering the same accelerator multiple times";
-
- accelerators_->push_back(accelerator);
- RegisterPendingAccelerators();
-}
-
-void View::RemoveAccelerator(const ui::Accelerator& accelerator) {
- if (!accelerators_.get()) {
- NOTREACHED() << "Removing non-existing accelerator";
- return;
- }
-
- std::vector<ui::Accelerator>::iterator i(
- std::find(accelerators_->begin(), accelerators_->end(), accelerator));
- if (i == accelerators_->end()) {
- NOTREACHED() << "Removing non-existing accelerator";
- return;
- }
-
- size_t index = i - accelerators_->begin();
- accelerators_->erase(i);
- if (index >= registered_accelerator_count_) {
- // The accelerator is not registered to FocusManager.
- return;
- }
- --registered_accelerator_count_;
-
- // Providing we are attached to a Widget and registered with a focus manager,
- // we should de-register from that focus manager now.
- if (GetWidget() && accelerator_focus_manager_)
- accelerator_focus_manager_->UnregisterAccelerator(accelerator, this);
-}
-
-void View::ResetAccelerators() {
- if (accelerators_.get())
- UnregisterAccelerators(false);
-}
-
-bool View::AcceleratorPressed(const ui::Accelerator& accelerator) {
- return false;
-}
-
-// Focus -----------------------------------------------------------------------
-
-bool View::HasFocus() const {
- const FocusManager* focus_manager = GetFocusManager();
- return focus_manager && (focus_manager->GetFocusedView() == this);
-}
-
-View* View::GetNextFocusableView() {
- return next_focusable_view_;
-}
-
-const View* View::GetNextFocusableView() const {
- return next_focusable_view_;
-}
-
-View* View::GetPreviousFocusableView() {
- return previous_focusable_view_;
-}
-
-void View::SetNextFocusableView(View* view) {
- view->previous_focusable_view_ = this;
- next_focusable_view_ = view;
-}
-
-bool View::IsFocusableInRootView() const {
- return IsFocusable() && IsVisibleInRootView();
-}
-
-bool View::IsAccessibilityFocusableInRootView() const {
- return (focusable_ || accessibility_focusable_) && IsEnabled() &&
- IsVisibleInRootView();
-}
-
-FocusManager* View::GetFocusManager() {
- Widget* widget = GetWidget();
- return widget ? widget->GetFocusManager() : NULL;
-}
-
-const FocusManager* View::GetFocusManager() const {
- const Widget* widget = GetWidget();
- return widget ? widget->GetFocusManager() : NULL;
-}
-
-void View::RequestFocus() {
- FocusManager* focus_manager = GetFocusManager();
- if (focus_manager && IsFocusableInRootView())
- focus_manager->SetFocusedView(this);
-}
-
-bool View::SkipDefaultKeyEventProcessing(const KeyEvent& event) {
- return false;
-}
-
-FocusTraversable* View::GetFocusTraversable() {
- return NULL;
-}
-
-FocusTraversable* View::GetPaneFocusTraversable() {
- return NULL;
-}
-
-// Tooltips --------------------------------------------------------------------
-
-bool View::GetTooltipText(const gfx::Point& p, string16* tooltip) const {
- return false;
-}
-
-bool View::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* loc) const {
- return false;
-}
-
-// Context menus ---------------------------------------------------------------
-
-void View::ShowContextMenu(const gfx::Point& p, bool is_mouse_gesture) {
- if (!context_menu_controller_)
- return;
-
- context_menu_controller_->ShowContextMenuForView(this, p, is_mouse_gesture);
-}
-
-// Drag and drop ---------------------------------------------------------------
-
-bool View::GetDropFormats(
- int* formats,
- std::set<OSExchangeData::CustomFormat>* custom_formats) {
- return false;
-}
-
-bool View::AreDropTypesRequired() {
- return false;
-}
-
-bool View::CanDrop(const OSExchangeData& data) {
- // TODO(sky): when I finish up migration, this should default to true.
- return false;
-}
-
-void View::OnDragEntered(const DropTargetEvent& event) {
-}
-
-int View::OnDragUpdated(const DropTargetEvent& event) {
- return ui::DragDropTypes::DRAG_NONE;
-}
-
-void View::OnDragExited() {
-}
-
-int View::OnPerformDrop(const DropTargetEvent& event) {
- return ui::DragDropTypes::DRAG_NONE;
-}
-
-void View::OnDragDone() {
-}
-
-// static
-bool View::ExceededDragThreshold(int delta_x, int delta_y) {
- return (abs(delta_x) > GetHorizontalDragThreshold() ||
- abs(delta_y) > GetVerticalDragThreshold());
-}
-
-// Scrolling -------------------------------------------------------------------
-
-void View::ScrollRectToVisible(const gfx::Rect& rect) {
- // We must take RTL UI mirroring into account when adjusting the position of
- // the region.
- if (parent_) {
- gfx::Rect scroll_rect(rect);
- scroll_rect.Offset(GetMirroredX(), y());
- parent_->ScrollRectToVisible(scroll_rect);
- }
-}
-
-int View::GetPageScrollIncrement(ScrollView* scroll_view,
- bool is_horizontal, bool is_positive) {
- return 0;
-}
-
-int View::GetLineScrollIncrement(ScrollView* scroll_view,
- bool is_horizontal, bool is_positive) {
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// View, protected:
-
-// Size and disposition --------------------------------------------------------
-
-void View::OnBoundsChanged(const gfx::Rect& previous_bounds) {
-}
-
-void View::PreferredSizeChanged() {
- InvalidateLayout();
- if (parent_)
- parent_->ChildPreferredSizeChanged(this);
-}
-
-bool View::NeedsNotificationWhenVisibleBoundsChange() const {
- return false;
-}
-
-void View::OnVisibleBoundsChanged() {
-}
-
-// Tree operations -------------------------------------------------------------
-
-void View::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
-}
-
-void View::VisibilityChanged(View* starting_from, bool is_visible) {
-}
-
-void View::NativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view,
- internal::RootView* root_view) {
- FocusManager* focus_manager = GetFocusManager();
- if (!accelerator_registration_delayed_ &&
- accelerator_focus_manager_ &&
- accelerator_focus_manager_ != focus_manager) {
- UnregisterAccelerators(true);
- accelerator_registration_delayed_ = true;
- }
- if (accelerator_registration_delayed_ && attached) {
- if (focus_manager) {
- RegisterPendingAccelerators();
- accelerator_registration_delayed_ = false;
- }
- }
-}
-
-// Painting --------------------------------------------------------------------
-
-void View::PaintChildren(gfx::Canvas* canvas) {
- TRACE_EVENT0("views", "View::PaintChildren");
- for (int i = 0, count = child_count(); i < count; ++i)
- if (!child_at(i)->layer())
- child_at(i)->Paint(canvas);
-}
-
-void View::OnPaint(gfx::Canvas* canvas) {
- TRACE_EVENT0("views", "View::OnPaint");
- OnPaintBackground(canvas);
- OnPaintFocusBorder(canvas);
- OnPaintBorder(canvas);
-}
-
-void View::OnPaintBackground(gfx::Canvas* canvas) {
- if (background_.get()) {
- TRACE_EVENT2("views", "View::OnPaintBackground",
- "width", canvas->GetSkCanvas()->getDevice()->width(),
- "height", canvas->GetSkCanvas()->getDevice()->height());
- background_->Paint(canvas, this);
- }
-}
-
-void View::OnPaintBorder(gfx::Canvas* canvas) {
- if (border_.get()) {
- TRACE_EVENT2("views", "View::OnPaintBorder",
- "width", canvas->GetSkCanvas()->getDevice()->width(),
- "height", canvas->GetSkCanvas()->getDevice()->height());
- border_->Paint(*this, canvas);
- }
-}
-
-void View::OnPaintFocusBorder(gfx::Canvas* canvas) {
- if ((IsFocusable() || IsAccessibilityFocusableInRootView()) && HasFocus()) {
- TRACE_EVENT2("views", "views::OnPaintFocusBorder",
- "width", canvas->GetSkCanvas()->getDevice()->width(),
- "height", canvas->GetSkCanvas()->getDevice()->height());
- canvas->DrawFocusRect(GetLocalBounds());
- }
-}
-
-// Accelerated Painting --------------------------------------------------------
-
-void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
- // This method should not have the side-effect of creating the layer.
- if (layer())
- layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
-}
-
-bool View::SetExternalTexture(ui::Texture* texture) {
- DCHECK(texture);
- SetPaintToLayer(true);
-
- layer()->SetExternalTexture(texture);
-
- // Child views must not paint into the external texture. So make sure each
- // child view has its own layer to paint into.
- for (Views::iterator i = children_.begin(); i != children_.end(); ++i)
- (*i)->SetPaintToLayer(true);
-
- SchedulePaintInRect(GetLocalBounds());
- return true;
-}
-
-void View::CalculateOffsetToAncestorWithLayer(gfx::Point* offset,
- ui::Layer** layer_parent) {
- if (layer()) {
- if (layer_parent)
- *layer_parent = layer();
- return;
- }
- if (!parent_)
- return;
-
- offset->Offset(x(), y());
- parent_->CalculateOffsetToAncestorWithLayer(offset, layer_parent);
-}
-
-void View::MoveLayerToParent(ui::Layer* parent_layer,
- const gfx::Point& point) {
- gfx::Point local_point(point);
- if (parent_layer != layer())
- local_point.Offset(x(), y());
- if (layer() && parent_layer != layer()) {
- parent_layer->Add(layer());
- layer()->SetBounds(gfx::Rect(local_point.x(), local_point.y(),
- width(), height()));
- } else {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->MoveLayerToParent(parent_layer, local_point);
- }
-}
-
-void View::UpdateLayerVisibility() {
- if (!use_acceleration_when_possible)
- return;
- bool visible = IsVisible();
- for (const View* v = parent_; visible && v && !v->layer(); v = v->parent_)
- visible = v->IsVisible();
-
- UpdateChildLayerVisibility(visible);
-}
-
-void View::UpdateChildLayerVisibility(bool ancestor_visible) {
- if (layer()) {
- layer()->SetVisible(ancestor_visible && IsVisible());
- } else {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->UpdateChildLayerVisibility(ancestor_visible && IsVisible());
- }
-}
-
-void View::UpdateChildLayerBounds(const gfx::Point& offset) {
- if (layer()) {
- layer()->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
- } else {
- for (int i = 0, count = child_count(); i < count; ++i) {
- gfx::Point new_offset(offset.x() + child_at(i)->x(),
- offset.y() + child_at(i)->y());
- child_at(i)->UpdateChildLayerBounds(new_offset);
- }
- }
-}
-
-void View::OnPaintLayer(gfx::Canvas* canvas) {
- if (!layer() || !layer()->fills_bounds_opaquely())
- canvas->GetSkCanvas()->drawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
- PaintCommon(canvas);
-}
-
-void View::ReorderLayers() {
- View* v = this;
- while (v && !v->layer())
- v = v->parent();
-
- // Forward to widget in case we're in a NativeWidgetView.
- if (!v) {
- if (GetWidget())
- GetWidget()->ReorderLayers();
- } else {
- for (Views::const_iterator i(v->children_.begin());
- i != v->children_.end();
- ++i)
- (*i)->ReorderChildLayers(v->layer());
- }
-}
-
-void View::ReorderChildLayers(ui::Layer* parent_layer) {
- if (layer()) {
- DCHECK_EQ(parent_layer, layer()->parent());
- parent_layer->StackAtTop(layer());
- } else {
- for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i)
- (*i)->ReorderChildLayers(parent_layer);
- }
-}
-
-// Input -----------------------------------------------------------------------
-
-bool View::HasHitTestMask() const {
- return false;
-}
-
-void View::GetHitTestMask(gfx::Path* mask) const {
- DCHECK(mask);
-}
-
-// Focus -----------------------------------------------------------------------
-
-bool View::IsFocusable() const {
- return focusable_ && IsEnabled() && IsVisible();
-}
-
-void View::OnFocus() {
- // TODO(beng): Investigate whether it's possible for us to move this to
- // Focus().
- // By default, we clear the native focus. This ensures that no visible native
- // view as the focus and that we still receive keyboard inputs.
- FocusManager* focus_manager = GetFocusManager();
- if (focus_manager)
- focus_manager->ClearNativeFocus();
-
- // TODO(beng): Investigate whether it's possible for us to move this to
- // Focus().
- // Notify assistive technologies of the focus change.
- GetWidget()->NotifyAccessibilityEvent(
- this, ui::AccessibilityTypes::EVENT_FOCUS, true);
-}
-
-void View::OnBlur() {
-}
-
-void View::Focus() {
- SchedulePaint();
- OnFocus();
-}
-
-void View::Blur() {
- SchedulePaint();
- OnBlur();
-}
-
-// Tooltips --------------------------------------------------------------------
-
-void View::TooltipTextChanged() {
- Widget* widget = GetWidget();
- // TooltipManager may be null if there is a problem creating it.
- if (widget && widget->native_widget_private()->GetTooltipManager()) {
- widget->native_widget_private()->GetTooltipManager()->
- TooltipTextChanged(this);
- }
-}
-
-// Context menus ---------------------------------------------------------------
-
-gfx::Point View::GetKeyboardContextMenuLocation() {
- gfx::Rect vis_bounds = GetVisibleBounds();
- gfx::Point screen_point(vis_bounds.x() + vis_bounds.width() / 2,
- vis_bounds.y() + vis_bounds.height() / 2);
- ConvertPointToScreen(this, &screen_point);
- return screen_point;
-}
-
-// Drag and drop ---------------------------------------------------------------
-
-int View::GetDragOperations(const gfx::Point& press_pt) {
- return drag_controller_ ?
- drag_controller_->GetDragOperationsForView(this, press_pt) :
- ui::DragDropTypes::DRAG_NONE;
-}
-
-void View::WriteDragData(const gfx::Point& press_pt, OSExchangeData* data) {
- DCHECK(drag_controller_);
- drag_controller_->WriteDragDataForView(this, press_pt, data);
-}
-
-bool View::InDrag() {
- Widget* widget = GetWidget();
- return widget ? widget->dragged_view() == this : false;
-}
-
-// Debugging -------------------------------------------------------------------
-
-#if !defined(NDEBUG)
-
-std::string View::PrintViewGraph(bool first) {
- return DoPrintViewGraph(first, this);
-}
-
-std::string View::DoPrintViewGraph(bool first, View* view_with_children) {
- // 64-bit pointer = 16 bytes of hex + "0x" + '\0' = 19.
- const size_t kMaxPointerStringLength = 19;
-
- std::string result;
-
- if (first)
- result.append("digraph {\n");
-
- // Node characteristics.
- char p[kMaxPointerStringLength];
-
- size_t baseNameIndex = GetClassName().find_last_of('/');
- if (baseNameIndex == std::string::npos)
- baseNameIndex = 0;
- else
- baseNameIndex++;
-
- char bounds_buffer[512];
-
- // Information about current node.
- base::snprintf(p, arraysize(bounds_buffer), "%p", view_with_children);
- result.append(" N");
- result.append(p+2);
- result.append(" [label=\"");
-
- result.append(GetClassName().substr(baseNameIndex).c_str());
-
- base::snprintf(bounds_buffer,
- arraysize(bounds_buffer),
- "\\n bounds: (%d, %d), (%dx%d)",
- this->bounds().x(),
- this->bounds().y(),
- this->bounds().width(),
- this->bounds().height());
- result.append(bounds_buffer);
-
- if (layer() && !layer()->hole_rect().IsEmpty()) {
- base::snprintf(bounds_buffer,
- arraysize(bounds_buffer),
- "\\n hole bounds: (%d, %d), (%dx%d)",
- layer()->hole_rect().x(),
- layer()->hole_rect().y(),
- layer()->hole_rect().width(),
- layer()->hole_rect().height());
- result.append(bounds_buffer);
- }
-
- if (GetTransform().HasChange()) {
- gfx::Point translation;
- float rotation;
- gfx::Point3f scale;
- if (ui::InterpolatedTransform::FactorTRS(GetTransform(),
- &translation,
- &rotation,
- &scale)) {
- if (translation != gfx::Point(0, 0)) {
- base::snprintf(bounds_buffer,
- arraysize(bounds_buffer),
- "\\n translation: (%d, %d)",
- translation.x(),
- translation.y());
- result.append(bounds_buffer);
- }
-
- if (fabs(rotation) > 1e-5) {
- base::snprintf(bounds_buffer,
- arraysize(bounds_buffer),
- "\\n rotation: %3.2f", rotation);
- result.append(bounds_buffer);
- }
-
- if (scale.AsPoint() != gfx::Point(0, 0)) {
- base::snprintf(bounds_buffer,
- arraysize(bounds_buffer),
- "\\n scale: (%2.4f, %2.4f)",
- scale.x(),
- scale.y());
- result.append(bounds_buffer);
- }
- }
- }
-
- result.append("\"");
- if (!parent_)
- result.append(", shape=box");
- if (layer()) {
- if (layer()->texture())
- result.append(", color=green");
- else
- result.append(", color=red");
-
- if (layer()->fills_bounds_opaquely())
- result.append(", style=filled");
- }
- result.append("]\n");
-
- // Link to parent.
- if (parent_) {
- char pp[kMaxPointerStringLength];
-
- base::snprintf(pp, kMaxPointerStringLength, "%p", parent_);
- result.append(" N");
- result.append(pp+2);
- result.append(" -> N");
- result.append(p+2);
- result.append("\n");
- }
-
- // Children.
- for (int i = 0, count = view_with_children->child_count(); i < count; ++i)
- result.append(view_with_children->child_at(i)->PrintViewGraph(false));
-
- if (first)
- result.append("}\n");
-
- return result;
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// View, private:
-
-// DropInfo --------------------------------------------------------------------
-
-void View::DragInfo::Reset() {
- possible_drag = false;
- start_pt = gfx::Point();
-}
-
-void View::DragInfo::PossibleDrag(const gfx::Point& p) {
- possible_drag = true;
- start_pt = p;
-}
-
-// Painting --------------------------------------------------------------------
-
-void View::SchedulePaintBoundsChanged(SchedulePaintType type) {
- // If we have a layer and the View's size did not change, we do not need to
- // schedule any paints since the layer will be redrawn at its new location
- // during the next Draw() cycle in the compositor.
- if (!layer() || type == SCHEDULE_PAINT_SIZE_CHANGED) {
- // Otherwise, if the size changes or we don't have a layer then we need to
- // use SchedulePaint to invalidate the area occupied by the View.
- SchedulePaint();
- } else if (parent_ && type == SCHEDULE_PAINT_SIZE_SAME) {
- // The compositor doesn't Draw() until something on screen changes, so
- // if our position changes but nothing is being animated on screen, then
- // tell the compositor to redraw the scene. We know layer() exists due to
- // the above if clause.
- layer()->ScheduleDraw();
- }
-}
-
-void View::PaintCommon(gfx::Canvas* canvas) {
- if (!IsVisible() || !painting_enabled_)
- return;
-
- {
- // If the View we are about to paint requested the canvas to be flipped, we
- // should change the transform appropriately.
- // The canvas mirroring is undone once the View is done painting so that we
- // don't pass the canvas with the mirrored transform to Views that didn't
- // request the canvas to be flipped.
- ScopedCanvas scoped(canvas);
- if (FlipCanvasOnPaintForRTLUI()) {
- canvas->Translate(gfx::Point(width(), 0));
- canvas->Scale(-1, 1);
- }
-
- OnPaint(canvas);
- }
-
- PaintChildren(canvas);
-}
-
-// Tree operations -------------------------------------------------------------
-
-void View::DoRemoveChildView(View* view,
- bool update_focus_cycle,
- bool update_tool_tip,
- bool delete_removed_view) {
- DCHECK(view);
- const Views::iterator i(std::find(children_.begin(), children_.end(), view));
- scoped_ptr<View> view_to_be_deleted;
- if (i != children_.end()) {
- if (update_focus_cycle) {
- // Let's remove the view from the focus traversal.
- View* next_focusable = view->next_focusable_view_;
- View* prev_focusable = view->previous_focusable_view_;
- if (prev_focusable)
- prev_focusable->next_focusable_view_ = next_focusable;
- if (next_focusable)
- next_focusable->previous_focusable_view_ = prev_focusable;
- }
-
- if (GetWidget())
- UnregisterChildrenForVisibleBoundsNotification(view);
- view->PropagateRemoveNotifications(this);
- view->parent_ = NULL;
- view->UpdateLayerVisibility();
-
- if (delete_removed_view && view->parent_owned())
- view_to_be_deleted.reset(view);
-
- children_.erase(i);
- }
-
- if (update_tool_tip)
- UpdateTooltip();
-
- if (layout_manager_.get())
- layout_manager_->ViewRemoved(this, view);
-}
-
-void View::PropagateRemoveNotifications(View* parent) {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->PropagateRemoveNotifications(parent);
-
- for (View* v = this; v; v = v->parent_)
- v->ViewHierarchyChangedImpl(true, false, parent, this);
-}
-
-void View::PropagateAddNotifications(View* parent, View* child) {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->PropagateAddNotifications(parent, child);
- ViewHierarchyChangedImpl(true, true, parent, child);
-}
-
-void View::PropagateNativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view,
- internal::RootView* root_view) {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->PropagateNativeViewHierarchyChanged(attached,
- native_view,
- root_view);
- NativeViewHierarchyChanged(attached, native_view, root_view);
-}
-
-void View::ViewHierarchyChangedImpl(bool register_accelerators,
- bool is_add,
- View* parent,
- View* child) {
- if (register_accelerators) {
- if (is_add) {
- // If you get this registration, you are part of a subtree that has been
- // added to the view hierarchy.
- if (GetFocusManager()) {
- RegisterPendingAccelerators();
- } else {
- // Delay accelerator registration until visible as we do not have
- // focus manager until then.
- accelerator_registration_delayed_ = true;
- }
- } else {
- if (child == this)
- UnregisterAccelerators(true);
- }
- }
-
- if (is_add && layer() && !layer()->parent()) {
- UpdateParentLayer();
- } else if (!is_add && child == this) {
- // Make sure the layers beloning to the subtree rooted at |child| get
- // removed from layers that do not belong in the same subtree.
- OrphanLayers();
- }
-
- ViewHierarchyChanged(is_add, parent, child);
- parent->needs_layout_ = true;
-}
-
-// Size and disposition --------------------------------------------------------
-
-void View::PropagateVisibilityNotifications(View* start, bool is_visible) {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->PropagateVisibilityNotifications(start, is_visible);
- VisibilityChangedImpl(start, is_visible);
-}
-
-void View::VisibilityChangedImpl(View* starting_from, bool is_visible) {
- if (is_visible)
- RegisterPendingAccelerators();
- else
- UnregisterAccelerators(true);
- VisibilityChanged(starting_from, is_visible);
-}
-
-void View::BoundsChanged(const gfx::Rect& previous_bounds) {
- if (IsVisible()) {
- // Paint the new bounds.
- SchedulePaintBoundsChanged(
- bounds_.size() == previous_bounds.size() ? SCHEDULE_PAINT_SIZE_SAME :
- SCHEDULE_PAINT_SIZE_CHANGED);
- }
-
- if (use_acceleration_when_possible) {
- if (layer()) {
- if (parent_) {
- gfx::Point offset;
- parent_->CalculateOffsetToAncestorWithLayer(&offset, NULL);
- offset.Offset(x(), y());
- layer()->SetBounds(gfx::Rect(offset, size()));
- } else {
- layer()->SetBounds(bounds_);
- }
- // TODO(beng): this seems redundant with the SchedulePaint at the top of
- // this function. explore collapsing.
- if (previous_bounds.size() != bounds_.size() &&
- !layer()->layer_updated_externally()) {
- // If our bounds have changed then we need to update the complete
- // texture.
- layer()->SchedulePaint(GetLocalBounds());
- }
- } else {
- // If our bounds have changed, then any descendant layer bounds may
- // have changed. Update them accordingly.
- gfx::Point offset;
- CalculateOffsetToAncestorWithLayer(&offset, NULL);
- UpdateChildLayerBounds(offset);
- }
- }
-
- OnBoundsChanged(previous_bounds);
-
- if (previous_bounds.size() != size()) {
- needs_layout_ = false;
- Layout();
- }
-
- if (NeedsNotificationWhenVisibleBoundsChange())
- OnVisibleBoundsChanged();
-
- // Notify interested Views that visible bounds within the root view may have
- // changed.
- if (descendants_to_notify_.get()) {
- for (Views::iterator i(descendants_to_notify_->begin());
- i != descendants_to_notify_->end(); ++i) {
- (*i)->OnVisibleBoundsChanged();
- }
- }
-}
-
-// static
-void View::RegisterChildrenForVisibleBoundsNotification(View* view) {
- if (view->NeedsNotificationWhenVisibleBoundsChange())
- view->RegisterForVisibleBoundsNotification();
- for (int i = 0; i < view->child_count(); ++i)
- RegisterChildrenForVisibleBoundsNotification(view->child_at(i));
-}
-
-// static
-void View::UnregisterChildrenForVisibleBoundsNotification(View* view) {
- if (view->NeedsNotificationWhenVisibleBoundsChange())
- view->UnregisterForVisibleBoundsNotification();
- for (int i = 0; i < view->child_count(); ++i)
- UnregisterChildrenForVisibleBoundsNotification(view->child_at(i));
-}
-
-void View::RegisterForVisibleBoundsNotification() {
- if (registered_for_visible_bounds_notification_)
- return;
-
- registered_for_visible_bounds_notification_ = true;
- for (View* ancestor = parent_; ancestor; ancestor = ancestor->parent_)
- ancestor->AddDescendantToNotify(this);
-}
-
-void View::UnregisterForVisibleBoundsNotification() {
- if (!registered_for_visible_bounds_notification_)
- return;
-
- registered_for_visible_bounds_notification_ = false;
- for (View* ancestor = parent_; ancestor; ancestor = ancestor->parent_)
- ancestor->RemoveDescendantToNotify(this);
-}
-
-void View::AddDescendantToNotify(View* view) {
- DCHECK(view);
- if (!descendants_to_notify_.get())
- descendants_to_notify_.reset(new Views);
- descendants_to_notify_->push_back(view);
-}
-
-void View::RemoveDescendantToNotify(View* view) {
- DCHECK(view && descendants_to_notify_.get());
- Views::iterator i(std::find(
- descendants_to_notify_->begin(), descendants_to_notify_->end(), view));
- DCHECK(i != descendants_to_notify_->end());
- descendants_to_notify_->erase(i);
- if (descendants_to_notify_->empty())
- descendants_to_notify_.reset();
-}
-
-// Transformations -------------------------------------------------------------
-
-bool View::GetTransformRelativeTo(const View* ancestor,
- ui::Transform* transform) const {
- const View* p = this;
-
- while (p && p != ancestor) {
- transform->ConcatTransform(p->GetTransform());
- transform->ConcatTranslate(static_cast<float>(p->GetMirroredX()),
- static_cast<float>(p->y()));
-
- p = p->parent_;
- }
-
- return p == ancestor;
-}
-
-// Coordinate conversion -------------------------------------------------------
-
-bool View::ConvertPointForAncestor(const View* ancestor,
- gfx::Point* point) const {
- ui::Transform trans;
- // TODO(sad): Have some way of caching the transformation results.
- bool result = GetTransformRelativeTo(ancestor, &trans);
- gfx::Point3f p(*point);
- trans.TransformPoint(p);
- *point = p.AsPoint();
- return result;
-}
-
-bool View::ConvertPointFromAncestor(const View* ancestor,
- gfx::Point* point) const {
- ui::Transform trans;
- bool result = GetTransformRelativeTo(ancestor, &trans);
- gfx::Point3f p(*point);
- trans.TransformPointReverse(p);
- *point = p.AsPoint();
- return result;
-}
-
-// Accelerated painting --------------------------------------------------------
-
-void View::CreateLayer() {
- // A new layer is being created for the view. So all the layers of the
- // sub-tree can inherit the visibility of the corresponding view.
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->UpdateChildLayerVisibility(true);
-
- layer_.reset(new ui::Layer());
- layer_->set_delegate(this);
-#if !defined(NDEBUG)
- layer_->set_name(GetClassName());
-#endif
-
- UpdateParentLayers();
- UpdateLayerVisibility();
-
- // The new layer needs to be ordered in the layer tree according
- // to the view tree. Children of this layer were added in order
- // in UpdateParentLayers().
- if (parent())
- parent()->ReorderLayers();
-}
-
-void View::UpdateParentLayers() {
- // Attach all top-level un-parented layers.
- if (layer() && !layer()->parent()) {
- UpdateParentLayer();
- } else {
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->UpdateParentLayers();
- }
-}
-
-void View::UpdateParentLayer() {
- if (!layer())
- return;
-
- ui::Layer* parent_layer = NULL;
- gfx::Point offset(x(), y());
-
- // TODO(sad): The NULL check here for parent_ essentially is to check if this
- // is the RootView. Instead of doing this, this function should be made
- // virtual and overridden from the RootView.
- if (parent_)
- parent_->CalculateOffsetToAncestorWithLayer(&offset, &parent_layer);
- else if (!parent_ && GetWidget())
- GetWidget()->CalculateOffsetToAncestorWithLayer(&offset, &parent_layer);
-
- ReparentLayer(offset, parent_layer);
-}
-
-void View::OrphanLayers() {
- if (layer()) {
- if (layer()->parent())
- layer()->parent()->Remove(layer());
-
- // The layer belonging to this View has already been orphaned. It is not
- // necessary to orphan the child layers.
- return;
- }
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->OrphanLayers();
-}
-
-void View::ReparentLayer(const gfx::Point& offset, ui::Layer* parent_layer) {
- layer_->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
- DCHECK_NE(layer(), parent_layer);
- if (parent_layer)
- parent_layer->Add(layer());
- layer_->SchedulePaint(GetLocalBounds());
- MoveLayerToParent(layer(), gfx::Point());
-}
-
-void View::DestroyLayer() {
- ui::Layer* new_parent = layer()->parent();
- std::vector<ui::Layer*> children = layer()->children();
- for (size_t i = 0; i < children.size(); ++i) {
- layer()->Remove(children[i]);
- if (new_parent)
- new_parent->Add(children[i]);
- }
-
- layer_.reset();
-
- if (new_parent)
- ReorderLayers();
-
- gfx::Point offset;
- CalculateOffsetToAncestorWithLayer(&offset, NULL);
- UpdateChildLayerBounds(offset);
-
- SchedulePaint();
-}
-
-// Input -----------------------------------------------------------------------
-
-bool View::ProcessMousePressed(const MouseEvent& event, DragInfo* drag_info) {
- const bool enabled = IsEnabled();
- int drag_operations =
- (enabled && event.IsOnlyLeftMouseButton() && HitTest(event.location())) ?
- GetDragOperations(event.location()) : 0;
- ContextMenuController* context_menu_controller = event.IsRightMouseButton() ?
- context_menu_controller_ : 0;
-
- const bool result = OnMousePressed(event);
- // WARNING: we may have been deleted, don't use any View variables.
-
- if (!enabled)
- return result;
-
- if (drag_operations != ui::DragDropTypes::DRAG_NONE) {
- drag_info->PossibleDrag(event.location());
- return true;
- }
- return !!context_menu_controller || result;
-}
-
-bool View::ProcessMouseDragged(const MouseEvent& event, DragInfo* drag_info) {
- // Copy the field, that way if we're deleted after drag and drop no harm is
- // done.
- ContextMenuController* context_menu_controller = context_menu_controller_;
- const bool possible_drag = drag_info->possible_drag;
- if (possible_drag && ExceededDragThreshold(
- drag_info->start_pt.x() - event.x(),
- drag_info->start_pt.y() - event.y())) {
- if (!drag_controller_ ||
- drag_controller_->CanStartDragForView(
- this, drag_info->start_pt, event.location()))
- DoDrag(event, drag_info->start_pt);
- } else {
- if (OnMouseDragged(event))
- return true;
- // Fall through to return value based on context menu controller.
- }
- // WARNING: we may have been deleted.
- return (context_menu_controller != NULL) || possible_drag;
-}
-
-void View::ProcessMouseReleased(const MouseEvent& event) {
- if (context_menu_controller_ && event.IsOnlyRightMouseButton()) {
- // Assume that if there is a context menu controller we won't be deleted
- // from mouse released.
- gfx::Point location(event.location());
- OnMouseReleased(event);
- if (HitTest(location)) {
- ConvertPointToScreen(this, &location);
- ShowContextMenu(location, true);
- }
- } else {
- OnMouseReleased(event);
- }
- // WARNING: we may have been deleted.
-}
-
-ui::TouchStatus View::ProcessTouchEvent(const TouchEvent& event) {
- // TODO(rjkroege): Implement a grab scheme similar to as as is found in
- // MousePressed.
- return OnTouchEvent(event);
-}
-
-// Accelerators ----------------------------------------------------------------
-
-void View::RegisterPendingAccelerators() {
- if (!accelerators_.get() ||
- registered_accelerator_count_ == accelerators_->size()) {
- // No accelerators are waiting for registration.
- return;
- }
-
- if (!GetWidget()) {
- // The view is not yet attached to a widget, defer registration until then.
- return;
- }
-
- accelerator_focus_manager_ = GetFocusManager();
- if (!accelerator_focus_manager_) {
- // Some crash reports seem to show that we may get cases where we have no
- // focus manager (see bug #1291225). This should never be the case, just
- // making sure we don't crash.
-
- // TODO(jcampan): This fails for a view under NativeWidgetGtk with
- // TYPE_CHILD. (see http://crbug.com/21335) reenable
- // NOTREACHED assertion and verify accelerators works as
- // expected.
-#if defined(OS_WIN)
- NOTREACHED();
-#endif
- return;
- }
- // Only register accelerators if we are visible.
- if (!IsVisibleInRootView() || !GetWidget()->IsVisible())
- return;
- for (std::vector<ui::Accelerator>::const_iterator i(
- accelerators_->begin() + registered_accelerator_count_);
- i != accelerators_->end(); ++i) {
- accelerator_focus_manager_->RegisterAccelerator(*i, this);
- }
- registered_accelerator_count_ = accelerators_->size();
-}
-
-void View::UnregisterAccelerators(bool leave_data_intact) {
- if (!accelerators_.get())
- return;
-
- if (GetWidget()) {
- if (accelerator_focus_manager_) {
- // We may not have a FocusManager if the window containing us is being
- // closed, in which case the FocusManager is being deleted so there is
- // nothing to unregister.
- accelerator_focus_manager_->UnregisterAccelerators(this);
- accelerator_focus_manager_ = NULL;
- }
- if (!leave_data_intact) {
- accelerators_->clear();
- accelerators_.reset();
- }
- registered_accelerator_count_ = 0;
- }
-}
-
-// Focus -----------------------------------------------------------------------
-
-void View::InitFocusSiblings(View* v, int index) {
- int count = child_count();
-
- if (count == 0) {
- v->next_focusable_view_ = NULL;
- v->previous_focusable_view_ = NULL;
- } else {
- if (index == count) {
- // We are inserting at the end, but the end of the child list may not be
- // the last focusable element. Let's try to find an element with no next
- // focusable element to link to.
- View* last_focusable_view = NULL;
- for (Views::iterator i(children_.begin()); i != children_.end(); ++i) {
- if (!(*i)->next_focusable_view_) {
- last_focusable_view = *i;
- break;
- }
- }
- if (last_focusable_view == NULL) {
- // Hum... there is a cycle in the focus list. Let's just insert ourself
- // after the last child.
- View* prev = children_[index - 1];
- v->previous_focusable_view_ = prev;
- v->next_focusable_view_ = prev->next_focusable_view_;
- prev->next_focusable_view_->previous_focusable_view_ = v;
- prev->next_focusable_view_ = v;
- } else {
- last_focusable_view->next_focusable_view_ = v;
- v->next_focusable_view_ = NULL;
- v->previous_focusable_view_ = last_focusable_view;
- }
- } else {
- View* prev = children_[index]->GetPreviousFocusableView();
- v->previous_focusable_view_ = prev;
- v->next_focusable_view_ = children_[index];
- if (prev)
- prev->next_focusable_view_ = v;
- children_[index]->previous_focusable_view_ = v;
- }
- }
-}
-
-// System events ---------------------------------------------------------------
-
-void View::PropagateThemeChanged() {
- for (int i = child_count() - 1; i >= 0; --i)
- child_at(i)->PropagateThemeChanged();
- OnThemeChanged();
-}
-
-void View::PropagateLocaleChanged() {
- for (int i = child_count() - 1; i >= 0; --i)
- child_at(i)->PropagateLocaleChanged();
- OnLocaleChanged();
-}
-
-// Tooltips --------------------------------------------------------------------
-
-void View::UpdateTooltip() {
- Widget* widget = GetWidget();
- // TODO(beng): The TooltipManager NULL check can be removed when we
- // consolidate Init() methods and make views_unittests Init() all
- // Widgets that it uses.
- if (widget && widget->native_widget_private()->GetTooltipManager())
- widget->native_widget_private()->GetTooltipManager()->UpdateTooltip();
-}
-
-// Drag and drop ---------------------------------------------------------------
-
-void View::DoDrag(const MouseEvent& event, const gfx::Point& press_pt) {
- int drag_operations = GetDragOperations(press_pt);
- if (drag_operations == ui::DragDropTypes::DRAG_NONE)
- return;
-
- OSExchangeData data;
- WriteDragData(press_pt, &data);
-
- // Message the RootView to do the drag and drop. That way if we're removed
- // the RootView can detect it and avoid calling us back.
- GetWidget()->RunShellDrag(this, data, drag_operations);
-}
-
-} // namespace views
diff --git a/views/view.h b/views/view.h
deleted file mode 100644
index e93a125..0000000
--- a/views/view.h
+++ /dev/null
@@ -1,1440 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_VIEW_H_
-#define VIEWS_VIEW_H_
-#pragma once
-
-#include <algorithm>
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/i18n/rtl.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "build/build_config.h"
-#include "ui/base/accelerators/accelerator.h"
-#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/gfx/compositor/layer_delegate.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/rect.h"
-#include "ui/views/events/event.h"
-#include "views/background.h"
-#include "views/border.h"
-
-#if defined(OS_WIN)
-#include "base/win/scoped_comptr.h"
-#endif
-
-using ui::OSExchangeData;
-
-namespace gfx {
-class Canvas;
-class Insets;
-class Path;
-}
-
-namespace ui {
-struct AccessibleViewState;
-class Compositor;
-class Layer;
-class TextInputClient;
-class Texture;
-class ThemeProvider;
-class Transform;
-enum TouchStatus;
-}
-
-#if defined(OS_WIN)
-class __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
-NativeViewAccessibilityWin;
-#endif
-
-namespace views {
-
-class Background;
-class Border;
-class ContextMenuController;
-class DragController;
-class FocusManager;
-class FocusTraversable;
-class InputMethod;
-class LayoutManager;
-class ScrollView;
-class Widget;
-
-namespace internal {
-class NativeWidgetView;
-class RootView;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// View class
-//
-// A View is a rectangle within the views View hierarchy. It is the base
-// class for all Views.
-//
-// A View is a container of other Views (there is no such thing as a Leaf
-// View - makes code simpler, reduces type conversion headaches, design
-// mistakes etc)
-//
-// The View contains basic properties for sizing (bounds), layout (flex,
-// orientation, etc), painting of children and event dispatch.
-//
-// The View also uses a simple Box Layout Manager similar to XUL's
-// SprocketLayout system. Alternative Layout Managers implementing the
-// LayoutManager interface can be used to lay out children if required.
-//
-// It is up to the subclass to implement Painting and storage of subclass -
-// specific properties and functionality.
-//
-// Unless otherwise documented, views is not thread safe and should only be
-// accessed from the main thread.
-//
-/////////////////////////////////////////////////////////////////////////////
-class VIEWS_EXPORT View : public ui::LayerDelegate,
- public ui::AcceleratorTarget {
- public:
- typedef std::vector<View*> Views;
-
- // TO BE MOVED ---------------------------------------------------------------
- // TODO(beng): These methods are to be moved to other files/classes.
-
- // TODO(beng): delete
- // Set whether this view is hottracked. A disabled view cannot be hottracked.
- // If flag differs from the current value, SchedulePaint is invoked.
- virtual void SetHotTracked(bool flag);
-
- // TODO(beng): delete
- // Returns whether the view is hot-tracked.
- virtual bool IsHotTracked() const;
-
- // Creation and lifetime -----------------------------------------------------
-
- View();
- virtual ~View();
-
- // By default a View is owned by its parent unless specified otherwise here.
- bool parent_owned() const { return parent_owned_; }
- void set_parent_owned(bool parent_owned) { parent_owned_ = parent_owned; }
-
- // Tree operations -----------------------------------------------------------
-
- // Get the Widget that hosts this View, if any.
- virtual const Widget* GetWidget() const;
- virtual Widget* GetWidget();
-
- // Adds |view| as a child of this view, optionally at |index|.
- void AddChildView(View* view);
- void AddChildViewAt(View* view, int index);
-
- // Moves |view| to the specified |index|. A negative value for |index| moves
- // the view at the end.
- void ReorderChildView(View* view, int index);
-
- // Removes |view| from this view. The view's parent will change to NULL.
- void RemoveChildView(View* view);
-
- // Removes all the children from this view. If |delete_children| is true,
- // the views are deleted, unless marked as not parent owned.
- void RemoveAllChildViews(bool delete_children);
-
- // STL-style accessors.
- Views::const_iterator children_begin() { return children_.begin(); }
- Views::const_iterator children_end() { return children_.end(); }
- Views::const_reverse_iterator children_rbegin() { return children_.rbegin(); }
- Views::const_reverse_iterator children_rend() { return children_.rend(); }
- int child_count() const { return static_cast<int>(children_.size()); }
- bool has_children() const { return !children_.empty(); }
-
- // Returns the child view at |index|.
- const View* child_at(int index) const {
- DCHECK_GE(index, 0);
- DCHECK_LT(index, child_count());
- return children_[index];
- }
- View* child_at(int index) {
- return const_cast<View*>(const_cast<const View*>(this)->child_at(index));
- }
-
- // Returns the parent view.
- const View* parent() const { return parent_; }
- View* parent() { return parent_; }
-
- // Returns true if |view| is contained within this View's hierarchy, even as
- // an indirect descendant. Will return true if child is also this view.
- bool Contains(const View* view) const;
-
- // Returns the index of |view|, or -1 if |view| is not a child of this view.
- int GetIndexOf(const View* view) const;
-
- // Size and disposition ------------------------------------------------------
- // Methods for obtaining and modifying the position and size of the view.
- // Position is in the coordinate system of the view's parent.
- // Position is NOT flipped for RTL. See "RTL positioning" for RTL-sensitive
- // position accessors.
- // Transformations are not applied on the size/position. For example, if
- // bounds is (0, 0, 100, 100) and it is scaled by 0.5 along the X axis, the
- // width will still be 100 (although when painted, it will be 50x50, painted
- // at location (0, 0)).
-
- void SetBounds(int x, int y, int width, int height);
- void SetBoundsRect(const gfx::Rect& bounds);
- void SetSize(const gfx::Size& size);
- void SetPosition(const gfx::Point& position);
- void SetX(int x);
- void SetY(int y);
-
- // No transformation is applied on the size or the locations.
- const gfx::Rect& bounds() const { return bounds_; }
- int x() const { return bounds_.x(); }
- int y() const { return bounds_.y(); }
- int width() const { return bounds_.width(); }
- int height() const { return bounds_.height(); }
- const gfx::Size& size() const { return bounds_.size(); }
-
- // Returns the bounds of the content area of the view, i.e. the rectangle
- // enclosed by the view's border.
- gfx::Rect GetContentsBounds() const;
-
- // Returns the bounds of the view in its own coordinates (i.e. position is
- // 0, 0).
- gfx::Rect GetLocalBounds() const;
-
- // Returns the insets of the current border. If there is no border an empty
- // insets is returned.
- virtual gfx::Insets GetInsets() const;
-
- // Returns the visible bounds of the receiver in the receivers coordinate
- // system.
- //
- // When traversing the View hierarchy in order to compute the bounds, the
- // function takes into account the mirroring setting and transformation for
- // each View and therefore it will return the mirrored and transformed version
- // of the visible bounds if need be.
- gfx::Rect GetVisibleBounds() const;
-
- // Return the bounds of the View in screen coordinate system.
- gfx::Rect GetScreenBounds() const;
-
- // Returns the baseline of this view, or -1 if this view has no baseline. The
- // return value is relative to the preferred height.
- virtual int GetBaseline() const;
-
- // Get the size the View would like to be, if enough space were available.
- virtual gfx::Size GetPreferredSize();
-
- // Convenience method that sizes this view to its preferred size.
- void SizeToPreferredSize();
-
- // Gets the minimum size of the view. View's implementation invokes
- // GetPreferredSize.
- virtual gfx::Size GetMinimumSize();
-
- // Return the height necessary to display this view with the provided width.
- // View's implementation returns the value from getPreferredSize.cy.
- // Override if your View's preferred height depends upon the width (such
- // as with Labels).
- virtual int GetHeightForWidth(int w);
-
- // Set whether the receiving view is visible. Painting is scheduled as needed
- virtual void SetVisible(bool visible);
-
- // Return whether a view is visible
- virtual bool IsVisible() const;
-
- // Return whether a view and its ancestors are visible. Returns true if the
- // path from this view to the root view is visible.
- virtual bool IsVisibleInRootView() const;
-
- // Set whether this view is enabled. A disabled view does not receive keyboard
- // or mouse inputs. If flag differs from the current value, SchedulePaint is
- // invoked.
- void SetEnabled(bool enabled);
-
- // Returns whether the view is enabled.
- virtual bool IsEnabled() const;
-
- // This indicates that the view completely fills its bounds in an opaque
- // color. This doesn't affect compositing but is a hint to the compositor to
- // optimize painting.
- // Note that this method does not implicitly create a layer if one does not
- // already exist for the View, but is a no-op in that case.
- void SetFillsBoundsOpaquely(bool fills_bounds_opaquely);
-
- // Transformations -----------------------------------------------------------
-
- // Methods for setting transformations for a view (e.g. rotation, scaling).
-
- const ui::Transform& GetTransform() const;
-
- // Clipping parameters. Clipping happens from the right and/or bottom. The
- // clipping amount is in parent's coordinate system, as in, if the view is
- // rotated, then the clipping will be applied after the rotation (and other
- // transformations, if any).
- void set_clip_x(float x) { clip_x_ = x; }
- void set_clip_y(float y) { clip_y_ = y; }
- void set_clip(float x, float y) { clip_x_ = x; clip_y_ = y; }
-
- // Sets the transform to the supplied transform.
- void SetTransform(const ui::Transform& transform);
-
- // Sets whether this view paints to a layer. A view paints to a layer if
- // either of the following are true:
- // . the view has a non-identity transform.
- // . SetPaintToLayer(true) has been invoked.
- // View creates the Layer only when it exists in a Widget with a non-NULL
- // Compositor.
- void SetPaintToLayer(bool paint_to_layer);
-
- const ui::Layer* layer() const { return layer_.get(); }
- ui::Layer* layer() { return layer_.get(); }
-
- // RTL positioning -----------------------------------------------------------
-
- // Methods for accessing the bounds and position of the view, relative to its
- // parent. The position returned is mirrored if the parent view is using a RTL
- // layout.
- //
- // NOTE: in the vast majority of the cases, the mirroring implementation is
- // transparent to the View subclasses and therefore you should use the
- // bounds() accessor instead.
- gfx::Rect GetMirroredBounds() const;
- gfx::Point GetMirroredPosition() const;
- int GetMirroredX() const;
-
- // Given a rectangle specified in this View's coordinate system, the function
- // computes the 'left' value for the mirrored rectangle within this View. If
- // the View's UI layout is not right-to-left, then bounds.x() is returned.
- //
- // UI mirroring is transparent to most View subclasses and therefore there is
- // no need to call this routine from anywhere within your subclass
- // implementation.
- int GetMirroredXForRect(const gfx::Rect& rect) const;
-
- // Given the X coordinate of a point inside the View, this function returns
- // the mirrored X coordinate of the point if the View's UI layout is
- // right-to-left. If the layout is left-to-right, the same X coordinate is
- // returned.
- //
- // Following are a few examples of the values returned by this function for
- // a View with the bounds {0, 0, 100, 100} and a right-to-left layout:
- //
- // GetMirroredXCoordinateInView(0) -> 100
- // GetMirroredXCoordinateInView(20) -> 80
- // GetMirroredXCoordinateInView(99) -> 1
- int GetMirroredXInView(int x) const;
-
- // Given a X coordinate and a width inside the View, this function returns
- // the mirrored X coordinate if the View's UI layout is right-to-left. If the
- // layout is left-to-right, the same X coordinate is returned.
- //
- // Following are a few examples of the values returned by this function for
- // a View with the bounds {0, 0, 100, 100} and a right-to-left layout:
- //
- // GetMirroredXCoordinateInView(0, 10) -> 90
- // GetMirroredXCoordinateInView(20, 20) -> 60
- int GetMirroredXWithWidthInView(int x, int w) const;
-
- // Layout --------------------------------------------------------------------
-
- // Lay out the child Views (set their bounds based on sizing heuristics
- // specific to the current Layout Manager)
- virtual void Layout();
-
- // TODO(beng): I think we should remove this.
- // Mark this view and all parents to require a relayout. This ensures the
- // next call to Layout() will propagate to this view, even if the bounds of
- // parent views do not change.
- void InvalidateLayout();
-
- // Gets/Sets the Layout Manager used by this view to size and place its
- // children.
- // The LayoutManager is owned by the View and is deleted when the view is
- // deleted, or when a new LayoutManager is installed.
- LayoutManager* GetLayoutManager() const;
- void SetLayoutManager(LayoutManager* layout);
-
- // Attributes ----------------------------------------------------------------
-
- // The view class name.
- static const char kViewClassName[];
-
- // Return the receiving view's class name. A view class is a string which
- // uniquely identifies the view class. It is intended to be used as a way to
- // find out during run time if a view can be safely casted to a specific view
- // subclass. The default implementation returns kViewClassName.
- virtual std::string GetClassName() const;
-
- // Returns the first ancestor, starting at this, whose class name is |name|.
- // Returns null if no ancestor has the class name |name|.
- View* GetAncestorWithClassName(const std::string& name);
-
- // Recursively descends the view tree starting at this view, and returns
- // the first child that it encounters that has the given ID.
- // Returns NULL if no matching child view is found.
- virtual const View* GetViewByID(int id) const;
- virtual View* GetViewByID(int id);
-
- // Gets and sets the ID for this view. ID should be unique within the subtree
- // that you intend to search for it. 0 is the default ID for views.
- int id() const { return id_; }
- void set_id(int id) { id_ = id; }
-
- // A group id is used to tag views which are part of the same logical group.
- // Focus can be moved between views with the same group using the arrow keys.
- // Groups are currently used to implement radio button mutual exclusion.
- // The group id is immutable once it's set.
- void SetGroup(int gid);
- // Returns the group id of the view, or -1 if the id is not set yet.
- int GetGroup() const;
-
- // If this returns true, the views from the same group can each be focused
- // when moving focus with the Tab/Shift-Tab key. If this returns false,
- // only the selected view from the group (obtained with
- // GetSelectedViewForGroup()) is focused.
- virtual bool IsGroupFocusTraversable() const;
-
- // Fills |views| with all the available views which belong to the provided
- // |group|.
- void GetViewsInGroup(int group, Views* views);
-
- // Returns the View that is currently selected in |group|.
- // The default implementation simply returns the first View found for that
- // group.
- virtual View* GetSelectedViewForGroup(int group);
-
- // Coordinate conversion -----------------------------------------------------
-
- // Note that the utility coordinate conversions functions always operate on
- // the mirrored position of the child Views if the parent View uses a
- // right-to-left UI layout.
-
- // Convert a point from the coordinate system of one View to another.
- //
- // |source| and |target| must be in the same widget, but doesn't need to be in
- // the same view hierarchy.
- // |source| can be NULL in which case it means the screen coordinate system.
- static void ConvertPointToView(const View* source,
- const View* target,
- gfx::Point* point);
-
- // Convert a point from a View's coordinate system to that of its Widget.
- static void ConvertPointToWidget(const View* src, gfx::Point* point);
-
- // Convert a point from the coordinate system of a View's Widget to that
- // View's coordinate system.
- static void ConvertPointFromWidget(const View* dest, gfx::Point* p);
-
- // Convert a point from a View's coordinate system to that of the screen.
- static void ConvertPointToScreen(const View* src, gfx::Point* point);
-
- // Applies transformation on the rectangle, which is in the view's coordinate
- // system, to convert it into the parent's coordinate system.
- gfx::Rect ConvertRectToParent(const gfx::Rect& rect) const;
-
- // Converts a rectangle from this views coordinate system to its widget
- // coordinate system.
- gfx::Rect ConvertRectToWidget(const gfx::Rect& rect) const;
-
- // Painting ------------------------------------------------------------------
-
- // Mark all or part of the View's bounds as dirty (needing repaint).
- // |r| is in the View's coordinates.
- // Rectangle |r| should be in the view's coordinate system. The
- // transformations are applied to it to convert it into the parent coordinate
- // system before propagating SchedulePaint up the view hierarchy.
- // TODO(beng): Make protected.
- virtual void SchedulePaint();
- virtual void SchedulePaintInRect(const gfx::Rect& r);
-
- // Called by the framework to paint a View. Performs translation and clipping
- // for View coordinates and language direction as required, allows the View
- // to paint itself via the various OnPaint*() event handlers and then paints
- // the hierarchy beneath it.
- virtual void Paint(gfx::Canvas* canvas);
-
- // The background object is owned by this object and may be NULL.
- void set_background(Background* b) { background_.reset(b); }
- const Background* background() const { return background_.get(); }
- Background* background() { return background_.get(); }
-
- // The border object is owned by this object and may be NULL.
- void set_border(Border* b) { border_.reset(b); }
- const Border* border() const { return border_.get(); }
- Border* border() { return border_.get(); }
-
- // Get the theme provider from the parent widget.
- virtual ui::ThemeProvider* GetThemeProvider() const;
-
- // RTL painting --------------------------------------------------------------
-
- // This method determines whether the gfx::Canvas object passed to
- // View::Paint() needs to be transformed such that anything drawn on the
- // canvas object during View::Paint() is flipped horizontally.
- //
- // By default, this function returns false (which is the initial value of
- // |flip_canvas_on_paint_for_rtl_ui_|). View subclasses that need to paint on
- // a flipped gfx::Canvas when the UI layout is right-to-left need to call
- // EnableCanvasFlippingForRTLUI().
- bool FlipCanvasOnPaintForRTLUI() const {
- return flip_canvas_on_paint_for_rtl_ui_ ? base::i18n::IsRTL() : false;
- }
-
- // Enables or disables flipping of the gfx::Canvas during View::Paint().
- // Note that if canvas flipping is enabled, the canvas will be flipped only
- // if the UI layout is right-to-left; that is, the canvas will be flipped
- // only if base::i18n::IsRTL() returns true.
- //
- // Enabling canvas flipping is useful for leaf views that draw a bitmap that
- // needs to be flipped horizontally when the UI layout is right-to-left
- // (views::Button, for example). This method is helpful for such classes
- // because their drawing logic stays the same and they can become agnostic to
- // the UI directionality.
- void EnableCanvasFlippingForRTLUI(bool enable) {
- flip_canvas_on_paint_for_rtl_ui_ = enable;
- }
-
- // Accelerated painting ------------------------------------------------------
-
- // Enable/Disable accelerated compositing.
- static void set_use_acceleration_when_possible(bool use);
- static bool get_use_acceleration_when_possible();
-
- // Input ---------------------------------------------------------------------
- // The points (and mouse locations) in the following functions are in the
- // view's coordinates, except for a RootView.
-
- // Returns the deepest visible descendant that contains the specified point.
- virtual View* GetEventHandlerForPoint(const gfx::Point& point);
-
- // Return the cursor that should be used for this view or the default cursor.
- // The event location is in the receiver's coordinate system. The caller is
- // responsible for managing the lifetime of the returned object, though that
- // lifetime may vary from platform to platform. On Windows, the cursor is a
- // shared resource, but Gtk destroys the returned cursor after setting it.
- virtual gfx::NativeCursor GetCursor(const MouseEvent& event);
-
- // Convenience to test whether a point is within this view's bounds
- virtual bool HitTest(const gfx::Point& l) const;
-
- // This method is invoked when the user clicks on this view.
- // The provided event is in the receiver's coordinate system.
- //
- // Return true if you processed the event and want to receive subsequent
- // MouseDraggged and MouseReleased events. This also stops the event from
- // bubbling. If you return false, the event will bubble through parent
- // views.
- //
- // If you remove yourself from the tree while processing this, event bubbling
- // stops as if you returned true, but you will not receive future events.
- // The return value is ignored in this case.
- //
- // Default implementation returns true if a ContextMenuController has been
- // set, false otherwise. Override as needed.
- //
- virtual bool OnMousePressed(const MouseEvent& event);
-
- // This method is invoked when the user clicked on this control.
- // and is still moving the mouse with a button pressed.
- // The provided event is in the receiver's coordinate system.
- //
- // Return true if you processed the event and want to receive
- // subsequent MouseDragged and MouseReleased events.
- //
- // Default implementation returns true if a ContextMenuController has been
- // set, false otherwise. Override as needed.
- //
- virtual bool OnMouseDragged(const MouseEvent& event);
-
- // This method is invoked when the user releases the mouse
- // button. The event is in the receiver's coordinate system.
- //
- // Default implementation notifies the ContextMenuController is appropriate.
- // Subclasses that wish to honor the ContextMenuController should invoke
- // super.
- virtual void OnMouseReleased(const MouseEvent& event);
-
- // This method is invoked when the mouse press/drag was canceled by a
- // system/user gesture.
- virtual void OnMouseCaptureLost();
-
- // This method is invoked when the mouse is above this control
- // The event is in the receiver's coordinate system.
- //
- // Default implementation does nothing. Override as needed.
- virtual void OnMouseMoved(const MouseEvent& event);
-
- // This method is invoked when the mouse enters this control.
- //
- // Default implementation does nothing. Override as needed.
- virtual void OnMouseEntered(const MouseEvent& event);
-
- // This method is invoked when the mouse exits this control
- // The provided event location is always (0, 0)
- // Default implementation does nothing. Override as needed.
- virtual void OnMouseExited(const MouseEvent& event);
-
- // This method is invoked for each touch event. Default implementation
- // does nothing. Override as needed.
- virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event);
-
- // Set the MouseHandler for a drag session.
- //
- // A drag session is a stream of mouse events starting
- // with a MousePressed event, followed by several MouseDragged
- // events and finishing with a MouseReleased event.
- //
- // This method should be only invoked while processing a
- // MouseDragged or MousePressed event.
- //
- // All further mouse dragged and mouse up events will be sent
- // the MouseHandler, even if it is reparented to another window.
- //
- // The MouseHandler is automatically cleared when the control
- // comes back from processing the MouseReleased event.
- //
- // Note: if the mouse handler is no longer connected to a
- // view hierarchy, events won't be sent.
- //
- virtual void SetMouseHandler(View* new_mouse_handler);
-
- // Invoked when a key is pressed or released.
- // Subclasser should return true if the event has been processed and false
- // otherwise. If the event has not been processed, the parent will be given a
- // chance.
- virtual bool OnKeyPressed(const KeyEvent& event);
- virtual bool OnKeyReleased(const KeyEvent& event);
-
- // Invoked when the user uses the mousewheel. Implementors should return true
- // if the event has been processed and false otherwise. This message is sent
- // if the view is focused. If the event has not been processed, the parent
- // will be given a chance.
- virtual bool OnMouseWheel(const MouseWheelEvent& event);
-
- // Returns the View's TextInputClient instance or NULL if the View doesn't
- // support text input.
- virtual ui::TextInputClient* GetTextInputClient();
-
- // Convenience method to retrieve the InputMethod associated with the
- // Widget that contains this view. Returns NULL if this view is not part of a
- // view hierarchy with a Widget.
- virtual InputMethod* GetInputMethod();
-
- // Accelerators --------------------------------------------------------------
-
- // Sets a keyboard accelerator for that view. When the user presses the
- // accelerator key combination, the AcceleratorPressed method is invoked.
- // Note that you can set multiple accelerators for a view by invoking this
- // method several times.
- virtual void AddAccelerator(const ui::Accelerator& accelerator);
-
- // Removes the specified accelerator for this view.
- virtual void RemoveAccelerator(const ui::Accelerator& accelerator);
-
- // Removes all the keyboard accelerators for this view.
- virtual void ResetAccelerators();
-
- // Overridden from AcceleratorTarget:
- virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
-
- // Focus ---------------------------------------------------------------------
-
- // Returns whether this view currently has the focus.
- virtual bool HasFocus() const;
-
- // Returns the view that should be selected next when pressing Tab.
- View* GetNextFocusableView();
- const View* GetNextFocusableView() const;
-
- // Returns the view that should be selected next when pressing Shift-Tab.
- View* GetPreviousFocusableView();
-
- // Sets the component that should be selected next when pressing Tab, and
- // makes the current view the precedent view of the specified one.
- // Note that by default views are linked in the order they have been added to
- // their container. Use this method if you want to modify the order.
- // IMPORTANT NOTE: loops in the focus hierarchy are not supported.
- void SetNextFocusableView(View* view);
-
- // Sets whether this view can accept the focus.
- // Note that this is false by default so that a view used as a container does
- // not get the focus.
- void set_focusable(bool focusable) { focusable_ = focusable; }
-
- // Returns true if the view is focusable (IsFocusable) and visible in the root
- // view. See also IsFocusable.
- bool IsFocusableInRootView() const;
-
- // Return whether this view is focusable when the user requires full keyboard
- // access, even though it may not be normally focusable.
- bool IsAccessibilityFocusableInRootView() const;
-
- // Set whether this view can be made focusable if the user requires
- // full keyboard access, even though it's not normally focusable.
- // Note that this is false by default.
- void set_accessibility_focusable(bool accessibility_focusable) {
- accessibility_focusable_ = accessibility_focusable;
- }
-
- // Convenience method to retrieve the FocusManager associated with the
- // Widget that contains this view. This can return NULL if this view is not
- // part of a view hierarchy with a Widget.
- virtual FocusManager* GetFocusManager();
- virtual const FocusManager* GetFocusManager() const;
-
- // Request the keyboard focus. The receiving view will become the
- // focused view.
- virtual void RequestFocus();
-
- // Invoked when a view is about to be requested for focus due to the focus
- // traversal. Reverse is this request was generated going backward
- // (Shift-Tab).
- virtual void AboutToRequestFocusFromTabTraversal(bool reverse) { }
-
- // Invoked when a key is pressed before the key event is processed (and
- // potentially eaten) by the focus manager for tab traversal, accelerators and
- // other focus related actions.
- // The default implementation returns false, ensuring that tab traversal and
- // accelerators processing is performed.
- // Subclasses should return true if they want to process the key event and not
- // have it processed as an accelerator (if any) or as a tab traversal (if the
- // key event is for the TAB key). In that case, OnKeyPressed will
- // subsequently be invoked for that event.
- virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& event);
-
- // Subclasses that contain traversable children that are not directly
- // accessible through the children hierarchy should return the associated
- // FocusTraversable for the focus traversal to work properly.
- virtual FocusTraversable* GetFocusTraversable();
-
- // Subclasses that can act as a "pane" must implement their own
- // FocusTraversable to keep the focus trapped within the pane.
- // If this method returns an object, any view that's a direct or
- // indirect child of this view will always use this FocusTraversable
- // rather than the one from the widget.
- virtual FocusTraversable* GetPaneFocusTraversable();
-
- // Tooltips ------------------------------------------------------------------
-
- // Gets the tooltip for this View. If the View does not have a tooltip,
- // return false. If the View does have a tooltip, copy the tooltip into
- // the supplied string and return true.
- // Any time the tooltip text that a View is displaying changes, it must
- // invoke TooltipTextChanged.
- // |p| provides the coordinates of the mouse (relative to this view).
- virtual bool GetTooltipText(const gfx::Point& p, string16* tooltip) const;
-
- // Returns the location (relative to this View) for the text on the tooltip
- // to display. If false is returned (the default), the tooltip is placed at
- // a default position.
- virtual bool GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* loc) const;
-
- // Context menus -------------------------------------------------------------
-
- // Sets the ContextMenuController. Setting this to non-null makes the View
- // process mouse events.
- ContextMenuController* context_menu_controller() {
- return context_menu_controller_;
- }
- void set_context_menu_controller(ContextMenuController* menu_controller) {
- context_menu_controller_ = menu_controller;
- }
-
- // Provides default implementation for context menu handling. The default
- // implementation calls the ShowContextMenu of the current
- // ContextMenuController (if it is not NULL). Overridden in subclassed views
- // to provide right-click menu display triggerd by the keyboard (i.e. for the
- // Chrome toolbar Back and Forward buttons). No source needs to be specified,
- // as it is always equal to the current View.
- virtual void ShowContextMenu(const gfx::Point& p,
- bool is_mouse_gesture);
-
- // Drag and drop -------------------------------------------------------------
-
- DragController* drag_controller() { return drag_controller_; }
- void set_drag_controller(DragController* drag_controller) {
- drag_controller_ = drag_controller;
- }
-
- // During a drag and drop session when the mouse moves the view under the
- // mouse is queried for the drop types it supports by way of the
- // GetDropFormats methods. If the view returns true and the drag site can
- // provide data in one of the formats, the view is asked if the drop data
- // is required before any other drop events are sent. Once the
- // data is available the view is asked if it supports the drop (by way of
- // the CanDrop method). If a view returns true from CanDrop,
- // OnDragEntered is sent to the view when the mouse first enters the view,
- // as the mouse moves around within the view OnDragUpdated is invoked.
- // If the user releases the mouse over the view and OnDragUpdated returns a
- // valid drop, then OnPerformDrop is invoked. If the mouse moves outside the
- // view or over another view that wants the drag, OnDragExited is invoked.
- //
- // Similar to mouse events, the deepest view under the mouse is first checked
- // if it supports the drop (Drop). If the deepest view under
- // the mouse does not support the drop, the ancestors are walked until one
- // is found that supports the drop.
-
- // Override and return the set of formats that can be dropped on this view.
- // |formats| is a bitmask of the formats defined bye OSExchangeData::Format.
- // The default implementation returns false, which means the view doesn't
- // support dropping.
- virtual bool GetDropFormats(
- int* formats,
- std::set<OSExchangeData::CustomFormat>* custom_formats);
-
- // Override and return true if the data must be available before any drop
- // methods should be invoked. The default is false.
- virtual bool AreDropTypesRequired();
-
- // A view that supports drag and drop must override this and return true if
- // data contains a type that may be dropped on this view.
- virtual bool CanDrop(const OSExchangeData& data);
-
- // OnDragEntered is invoked when the mouse enters this view during a drag and
- // drop session and CanDrop returns true. This is immediately
- // followed by an invocation of OnDragUpdated, and eventually one of
- // OnDragExited or OnPerformDrop.
- virtual void OnDragEntered(const DropTargetEvent& event);
-
- // Invoked during a drag and drop session while the mouse is over the view.
- // This should return a bitmask of the DragDropTypes::DragOperation supported
- // based on the location of the event. Return 0 to indicate the drop should
- // not be accepted.
- virtual int OnDragUpdated(const DropTargetEvent& event);
-
- // Invoked during a drag and drop session when the mouse exits the views, or
- // when the drag session was canceled and the mouse was over the view.
- virtual void OnDragExited();
-
- // Invoked during a drag and drop session when OnDragUpdated returns a valid
- // operation and the user release the mouse.
- virtual int OnPerformDrop(const DropTargetEvent& event);
-
- // Invoked from DoDrag after the drag completes. This implementation does
- // nothing, and is intended for subclasses to do cleanup.
- virtual void OnDragDone();
-
- // Returns true if the mouse was dragged enough to start a drag operation.
- // delta_x and y are the distance the mouse was dragged.
- static bool ExceededDragThreshold(int delta_x, int delta_y);
-
- // Accessibility -------------------------------------------------------------
-
- // Modifies |state| to reflect the current accessible state of this view.
- virtual void GetAccessibleState(ui::AccessibleViewState* state) { }
-
- // Returns an instance of the native accessibility interface for this view.
- virtual gfx::NativeViewAccessible GetNativeViewAccessible();
-
- // Scrolling -----------------------------------------------------------------
- // TODO(beng): Figure out if this can live somewhere other than View, i.e.
- // closer to ScrollView.
-
- // Scrolls the specified region, in this View's coordinate system, to be
- // visible. View's implementation passes the call onto the parent View (after
- // adjusting the coordinates). It is up to views that only show a portion of
- // the child view, such as Viewport, to override appropriately.
- virtual void ScrollRectToVisible(const gfx::Rect& rect);
-
- // The following methods are used by ScrollView to determine the amount
- // to scroll relative to the visible bounds of the view. For example, a
- // return value of 10 indicates the scrollview should scroll 10 pixels in
- // the appropriate direction.
- //
- // Each method takes the following parameters:
- //
- // is_horizontal: if true, scrolling is along the horizontal axis, otherwise
- // the vertical axis.
- // is_positive: if true, scrolling is by a positive amount. Along the
- // vertical axis scrolling by a positive amount equates to
- // scrolling down.
- //
- // The return value should always be positive and gives the number of pixels
- // to scroll. ScrollView interprets a return value of 0 (or negative)
- // to scroll by a default amount.
- //
- // See VariableRowHeightScrollHelper and FixedRowHeightScrollHelper for
- // implementations of common cases.
- virtual int GetPageScrollIncrement(ScrollView* scroll_view,
- bool is_horizontal, bool is_positive);
- virtual int GetLineScrollIncrement(ScrollView* scroll_view,
- bool is_horizontal, bool is_positive);
-
- protected:
- // Size and disposition ------------------------------------------------------
-
- // Override to be notified when the bounds of the view have changed.
- virtual void OnBoundsChanged(const gfx::Rect& previous_bounds);
-
- // Called when the preferred size of a child view changed. This gives the
- // parent an opportunity to do a fresh layout if that makes sense.
- virtual void ChildPreferredSizeChanged(View* child) {}
-
- // Invalidates the layout and calls ChildPreferredSizeChanged on the parent
- // if there is one. Be sure to call View::PreferredSizeChanged when
- // overriding such that the layout is properly invalidated.
- virtual void PreferredSizeChanged();
-
- // Override returning true when the view needs to be notified when its visible
- // bounds relative to the root view may have changed. Only used by
- // NativeViewHost.
- virtual bool NeedsNotificationWhenVisibleBoundsChange() const;
-
- // Notification that this View's visible bounds relative to the root view may
- // have changed. The visible bounds are the region of the View not clipped by
- // its ancestors. This is used for clipping NativeViewHost.
- virtual void OnVisibleBoundsChanged();
-
- // Override to be notified when the enabled state of this View has
- // changed. The default implementation calls SchedulePaint() on this View.
- virtual void OnEnabledChanged();
-
- // Tree operations -----------------------------------------------------------
-
- // This method is invoked when the tree changes.
- //
- // When a view is removed, it is invoked for all children and grand
- // children. For each of these views, a notification is sent to the
- // view and all parents.
- //
- // When a view is added, a notification is sent to the view, all its
- // parents, and all its children (and grand children)
- //
- // Default implementation does nothing. Override to perform operations
- // required when a view is added or removed from a view hierarchy
- //
- // parent is the new or old parent. Child is the view being added or
- // removed.
- //
- virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
-
- // When SetVisible() changes the visibility of a view, this method is
- // invoked for that view as well as all the children recursively.
- virtual void VisibilityChanged(View* starting_from, bool is_visible);
-
- // Called when the native view hierarchy changed.
- // |attached| is true if that view has been attached to a new NativeView
- // hierarchy, false if it has been detached.
- // |native_view| is the NativeView this view was attached/detached from, and
- // |root_view| is the root view associated with the NativeView.
- // Views created without a native view parent don't have a focus manager.
- // When this function is called they could do the processing that requires
- // it - like registering accelerators, for example.
- virtual void NativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view,
- internal::RootView* root_view);
-
- // Painting ------------------------------------------------------------------
-
- // Responsible for calling Paint() on child Views. Override to control the
- // order child Views are painted.
- virtual void PaintChildren(gfx::Canvas* canvas);
-
- // Override to provide rendering in any part of the View's bounds. Typically
- // this is the "contents" of the view. If you override this method you will
- // have to call the subsequent OnPaint*() methods manually.
- virtual void OnPaint(gfx::Canvas* canvas);
-
- // Override to paint a background before any content is drawn. Typically this
- // is done if you are satisfied with a default OnPaint handler but wish to
- // supply a different background.
- virtual void OnPaintBackground(gfx::Canvas* canvas);
-
- // Override to paint a border not specified by SetBorder().
- virtual void OnPaintBorder(gfx::Canvas* canvas);
-
- // Override to paint a focus border (usually a dotted rectangle) around
- // relevant contents.
- virtual void OnPaintFocusBorder(gfx::Canvas* canvas);
-
- // Accelerated painting ------------------------------------------------------
-
- // This creates a layer for the view, if one does not exist. It then
- // passes the texture to a layer associated with the view. While an external
- // texture is set, the view will not update the layer contents.
- //
- // |texture| cannot be NULL.
- //
- // Returns false if it cannot create a layer to which to assign the texture.
- bool SetExternalTexture(ui::Texture* texture);
-
- // Returns the offset from this view to the nearest ancestor with a layer.
- // If |ancestor| is non-NULL it is set to the nearest ancestor with a layer.
- virtual void CalculateOffsetToAncestorWithLayer(
- gfx::Point* offset,
- ui::Layer** layer_parent);
-
- // If this view has a layer, the layer is reparented to |parent_layer| and its
- // bounds is set based on |point|. If this view does not have a layer, then
- // recurses through all children. This is used when adding a layer to an
- // existing view to make sure all descendants that have layers are parented to
- // the right layer.
- virtual void MoveLayerToParent(ui::Layer* parent_layer,
- const gfx::Point& point);
-
- // Called to update the bounds of any child layers within this View's
- // hierarchy when something happens to the hierarchy.
- virtual void UpdateChildLayerBounds(const gfx::Point& offset);
-
- // Overridden from ui::LayerDelegate:
- virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
-
- // Finds the layer that this view paints to (it may belong to an ancestor
- // view), then reorders the immediate children of that layer to match the
- // order of the view tree.
- virtual void ReorderLayers();
-
- // This reorders the immediate children of |*parent_layer| to match the
- // order of the view tree.
- virtual void ReorderChildLayers(ui::Layer* parent_layer);
-
- // Input ---------------------------------------------------------------------
-
- // Called by HitTest to see if this View has a custom hit test mask. If the
- // return value is true, GetHitTestMask will be called to obtain the mask.
- // Default value is false, in which case the View will hit-test against its
- // bounds.
- virtual bool HasHitTestMask() const;
-
- // Called by HitTest to retrieve a mask for hit-testing against. Subclasses
- // override to provide custom shaped hit test regions.
- virtual void GetHitTestMask(gfx::Path* mask) const;
-
- // Focus ---------------------------------------------------------------------
-
- // Returns whether this view can accept focus.
- // A view can accept focus if it's enabled, focusable and visible.
- // This method is intended for views to use when calculating preferred size.
- // The FocusManager and other places use IsFocusableInRootView.
- virtual bool IsFocusable() const;
-
- // Override to be notified when focus has changed either to or from this View.
- virtual void OnFocus();
- virtual void OnBlur();
-
- // Handle view focus/blur events for this view.
- void Focus();
- void Blur();
-
- // System events -------------------------------------------------------------
-
- // Called when the UI theme has changed, overriding allows individual Views to
- // do special cleanup and processing (such as dropping resource caches).
- // To dispatch a theme changed notification, call Widget::ThemeChanged().
- virtual void OnThemeChanged() {}
-
- // Called when the locale has changed, overriding allows individual Views to
- // update locale-dependent strings.
- // To dispatch a locale changed notification, call Widget::LocaleChanged().
- virtual void OnLocaleChanged() {}
-
- // Tooltips ------------------------------------------------------------------
-
- // Views must invoke this when the tooltip text they are to display changes.
- void TooltipTextChanged();
-
- // Context menus -------------------------------------------------------------
-
- // Returns the location, in screen coordinates, to show the context menu at
- // when the context menu is shown from the keyboard. This implementation
- // returns the middle of the visible region of this view.
- //
- // This method is invoked when the context menu is shown by way of the
- // keyboard.
- virtual gfx::Point GetKeyboardContextMenuLocation();
-
- // Drag and drop -------------------------------------------------------------
-
- // These are cover methods that invoke the method of the same name on
- // the DragController. Subclasses may wish to override rather than install
- // a DragController.
- // See DragController for a description of these methods.
- virtual int GetDragOperations(const gfx::Point& press_pt);
- virtual void WriteDragData(const gfx::Point& press_pt, OSExchangeData* data);
-
- // Returns whether we're in the middle of a drag session that was initiated
- // by us.
- bool InDrag();
-
- // Returns how much the mouse needs to move in one direction to start a
- // drag. These methods cache in a platform-appropriate way. These values are
- // used by the public static method ExceededDragThreshold().
- static int GetHorizontalDragThreshold();
- static int GetVerticalDragThreshold();
-
- // Debugging -----------------------------------------------------------------
-
-#if !defined(NDEBUG)
- // Returns string containing a graph of the views hierarchy in graphViz DOT
- // language (http://graphviz.org/). Can be called within debugger and save
- // to a file to compile/view.
- // Note: Assumes initial call made with first = true.
- virtual std::string PrintViewGraph(bool first);
-
- // Some classes may own an object which contains the children to displayed in
- // the views hierarchy. The above function gives the class the flexibility to
- // decide which object should be used to obtain the children, but this
- // function makes the decision explicit.
- std::string DoPrintViewGraph(bool first, View* view_with_children);
-#endif
-
- private:
- friend class internal::NativeWidgetView;
- friend class internal::RootView;
- friend class FocusManager;
- friend class ViewStorage;
- friend class Widget;
- friend class PaintLock;
-
- // Used to track a drag. RootView passes this into
- // ProcessMousePressed/Dragged.
- struct DragInfo {
- // Sets possible_drag to false and start_x/y to 0. This is invoked by
- // RootView prior to invoke ProcessMousePressed.
- void Reset();
-
- // Sets possible_drag to true and start_pt to the specified point.
- // This is invoked by the target view if it detects the press may generate
- // a drag.
- void PossibleDrag(const gfx::Point& p);
-
- // Whether the press may generate a drag.
- bool possible_drag;
-
- // Coordinates of the mouse press.
- gfx::Point start_pt;
- };
-
- // Painting -----------------------------------------------------------------
-
- enum SchedulePaintType {
- // Indicates the size is the same (only the origin changed).
- SCHEDULE_PAINT_SIZE_SAME,
-
- // Indicates the size changed (and possibly the origin).
- SCHEDULE_PAINT_SIZE_CHANGED
- };
-
- // Invoked before and after the bounds change to schedule painting the old and
- // new bounds.
- void SchedulePaintBoundsChanged(SchedulePaintType type);
-
- // Common Paint() code shared by accelerated and non-accelerated code paths to
- // invoke OnPaint() on the View.
- void PaintCommon(gfx::Canvas* canvas);
-
- // Tree operations -----------------------------------------------------------
-
- // Removes |view| from the hierarchy tree. If |update_focus_cycle| is true,
- // the next and previous focusable views of views pointing to this view are
- // updated. If |update_tool_tip| is true, the tooltip is updated. If
- // |delete_removed_view| is true, the view is also deleted (if it is parent
- // owned).
- void DoRemoveChildView(View* view,
- bool update_focus_cycle,
- bool update_tool_tip,
- bool delete_removed_view);
-
- // Call ViewHierarchyChanged for all child views on all parents
- void PropagateRemoveNotifications(View* parent);
-
- // Call ViewHierarchyChanged for all children
- void PropagateAddNotifications(View* parent, View* child);
-
- // Propagates NativeViewHierarchyChanged() notification through all the
- // children.
- void PropagateNativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view,
- internal::RootView* root_view);
-
- // Takes care of registering/unregistering accelerators if
- // |register_accelerators| true and calls ViewHierarchyChanged().
- void ViewHierarchyChangedImpl(bool register_accelerators,
- bool is_add,
- View* parent,
- View* child);
-
- // Size and disposition ------------------------------------------------------
-
- // Call VisibilityChanged() recursively for all children.
- void PropagateVisibilityNotifications(View* from, bool is_visible);
-
- // Registers/unregisters accelerators as necessary and calls
- // VisibilityChanged().
- void VisibilityChangedImpl(View* starting_from, bool is_visible);
-
- // Responsible for propagating bounds change notifications to relevant
- // views.
- void BoundsChanged(const gfx::Rect& previous_bounds);
-
- // Visible bounds notification registration.
- // When a view is added to a hierarchy, it and all its children are asked if
- // they need to be registered for "visible bounds within root" notifications
- // (see comment on OnVisibleBoundsChanged()). If they do, they are registered
- // with every ancestor between them and the root of the hierarchy.
- static void RegisterChildrenForVisibleBoundsNotification(View* view);
- static void UnregisterChildrenForVisibleBoundsNotification(View* view);
- void RegisterForVisibleBoundsNotification();
- void UnregisterForVisibleBoundsNotification();
-
- // Adds/removes view to the list of descendants that are notified any time
- // this views location and possibly size are changed.
- void AddDescendantToNotify(View* view);
- void RemoveDescendantToNotify(View* view);
-
- // Transformations -----------------------------------------------------------
-
- // Returns in |transform| the transform to get from coordinates of |ancestor|
- // to this. Returns true if |ancestor| is found. If |ancestor| is not found,
- // or NULL, |transform| is set to convert from root view coordinates to this.
- bool GetTransformRelativeTo(const View* ancestor,
- ui::Transform* transform) const;
-
- // Coordinate conversion -----------------------------------------------------
-
- // Convert a point in the view's coordinate to an ancestor view's coordinate
- // system using necessary transformations. Returns whether the point was
- // successfully converted to the ancestor's coordinate system.
- bool ConvertPointForAncestor(const View* ancestor, gfx::Point* point) const;
-
- // Convert a point in the ancestor's coordinate system to the view's
- // coordinate system using necessary transformations. Returns whether the
- // point was successfully from the ancestor's coordinate system to the view's
- // coordinate system.
- bool ConvertPointFromAncestor(const View* ancestor, gfx::Point* point) const;
-
- // Accelerated painting ------------------------------------------------------
-
- // Disables painting during time critical operations. Used by PaintLock.
- // TODO(vollick) Ideally, the widget would not dispatch paints into the
- // hierarchy during time critical operations and this would not be needed.
- void set_painting_enabled(bool enabled) { painting_enabled_ = enabled; }
-
- // Creates the layer and related fields for this view.
- void CreateLayer();
-
- // Parents all un-parented layers within this view's hierarchy to this view's
- // layer.
- void UpdateParentLayers();
-
- // Updates the view's layer's parent. Called when a view is added to a view
- // hierarchy, responsible for parenting the view's layer to the enclosing
- // layer in the hierarchy.
- void UpdateParentLayer();
-
- // Parents this view's layer to |parent_layer|, and sets its bounds and other
- // properties in accordance to |offset|, the view's offset from the
- // |parent_layer|.
- void ReparentLayer(const gfx::Point& offset, ui::Layer* parent_layer);
-
- // Called to update the layer visibility. The layer will be visible if the
- // View itself, and all its parent Views are visible. This also updates
- // visibility of the child layers.
- void UpdateLayerVisibility();
- void UpdateChildLayerVisibility(bool visible);
-
- // Orphans the layers in this subtree that are parented to layers outside of
- // this subtree.
- void OrphanLayers();
-
- // Destroys the layer associated with this view, and reparents any descendants
- // to the destroyed layer's parent.
- void DestroyLayer();
-
- // Input ---------------------------------------------------------------------
-
- // RootView invokes these. These in turn invoke the appropriate OnMouseXXX
- // method. If a drag is detected, DoDrag is invoked.
- bool ProcessMousePressed(const MouseEvent& event, DragInfo* drop_info);
- bool ProcessMouseDragged(const MouseEvent& event, DragInfo* drop_info);
- void ProcessMouseReleased(const MouseEvent& event);
-
- // RootView will invoke this with incoming TouchEvents. Returns the
- // the result of OnTouchEvent.
- ui::TouchStatus ProcessTouchEvent(const TouchEvent& event);
-
- // Accelerators --------------------------------------------------------------
-
- // Registers this view's keyboard accelerators that are not registered to
- // FocusManager yet, if possible.
- void RegisterPendingAccelerators();
-
- // Unregisters all the keyboard accelerators associated with this view.
- // |leave_data_intact| if true does not remove data from accelerators_ array,
- // so it could be re-registered with other focus manager
- void UnregisterAccelerators(bool leave_data_intact);
-
- // Focus ---------------------------------------------------------------------
-
- // Initialize the previous/next focusable views of the specified view relative
- // to the view at the specified index.
- void InitFocusSiblings(View* view, int index);
-
- // System events -------------------------------------------------------------
-
- // Used to propagate theme changed notifications from the root view to all
- // views in the hierarchy.
- virtual void PropagateThemeChanged();
-
- // Used to propagate locale changed notifications from the root view to all
- // views in the hierarchy.
- virtual void PropagateLocaleChanged();
-
- // Tooltips ------------------------------------------------------------------
-
- // Propagates UpdateTooltip() to the TooltipManager for the Widget.
- // This must be invoked any time the View hierarchy changes in such a way
- // the view under the mouse differs. For example, if the bounds of a View is
- // changed, this is invoked. Similarly, as Views are added/removed, this
- // is invoked.
- void UpdateTooltip();
-
- // Drag and drop -------------------------------------------------------------
-
- // Starts a drag and drop operation originating from this view. This invokes
- // WriteDragData to write the data and GetDragOperations to determine the
- // supported drag operations. When done, OnDragDone is invoked.
- void DoDrag(const MouseEvent& event, const gfx::Point& press_pt);
-
- //////////////////////////////////////////////////////////////////////////////
-
- // Creation and lifetime -----------------------------------------------------
-
- // True if the hierarchy (i.e. the parent View) is responsible for deleting
- // this View. Default is true.
- bool parent_owned_;
-
- // Attributes ----------------------------------------------------------------
-
- // The id of this View. Used to find this View.
- int id_;
-
- // The group of this view. Some view subclasses use this id to find other
- // views of the same group. For example radio button uses this information
- // to find other radio buttons.
- int group_;
-
- // Tree operations -----------------------------------------------------------
-
- // This view's parent.
- View* parent_;
-
- // This view's children.
- Views children_;
-
- // Size and disposition ------------------------------------------------------
-
- // This View's bounds in the parent coordinate system.
- gfx::Rect bounds_;
-
- // Whether this view is visible.
- bool visible_;
-
- // Whether this view is enabled.
- bool enabled_;
-
- // Whether this view is painting.
- bool painting_enabled_;
-
- // Whether or not RegisterViewForVisibleBoundsNotification on the RootView
- // has been invoked.
- bool registered_for_visible_bounds_notification_;
-
- // List of descendants wanting notification when their visible bounds change.
- scoped_ptr<Views> descendants_to_notify_;
-
- // Transformations -----------------------------------------------------------
-
- // Clipping parameters. skia transformation matrix does not give us clipping.
- // So we do it ourselves.
- float clip_x_;
- float clip_y_;
-
- // Layout --------------------------------------------------------------------
-
- // Whether the view needs to be laid out.
- bool needs_layout_;
-
- // The View's LayoutManager defines the sizing heuristics applied to child
- // Views. The default is absolute positioning according to bounds_.
- scoped_ptr<LayoutManager> layout_manager_;
-
- // Painting ------------------------------------------------------------------
-
- // Background
- scoped_ptr<Background> background_;
-
- // Border.
- scoped_ptr<Border> border_;
-
- // RTL painting --------------------------------------------------------------
-
- // Indicates whether or not the gfx::Canvas object passed to View::Paint()
- // is going to be flipped horizontally (using the appropriate transform) on
- // right-to-left locales for this View.
- bool flip_canvas_on_paint_for_rtl_ui_;
-
- // Accelerated painting ------------------------------------------------------
-
- bool paint_to_layer_;
- scoped_ptr<ui::Layer> layer_;
-
- // Accelerators --------------------------------------------------------------
-
- // true if when we were added to hierarchy we were without focus manager
- // attempt addition when ancestor chain changed.
- bool accelerator_registration_delayed_;
-
- // Focus manager accelerators registered on.
- FocusManager* accelerator_focus_manager_;
-
- // The list of accelerators. List elements in the range
- // [0, registered_accelerator_count_) are already registered to FocusManager,
- // and the rest are not yet.
- scoped_ptr<std::vector<ui::Accelerator> > accelerators_;
- size_t registered_accelerator_count_;
-
- // Focus ---------------------------------------------------------------------
-
- // Next view to be focused when the Tab key is pressed.
- View* next_focusable_view_;
-
- // Next view to be focused when the Shift-Tab key combination is pressed.
- View* previous_focusable_view_;
-
- // Whether this view can be focused.
- bool focusable_;
-
- // Whether this view is focusable if the user requires full keyboard access,
- // even though it may not be normally focusable.
- bool accessibility_focusable_;
-
- // Context menus -------------------------------------------------------------
-
- // The menu controller.
- ContextMenuController* context_menu_controller_;
-
- // Drag and drop -------------------------------------------------------------
-
- DragController* drag_controller_;
-
- // Accessibility -------------------------------------------------------------
-
- // The Windows-specific accessibility implementation for this view.
-#if defined(OS_WIN)
- base::win::ScopedComPtr<NativeViewAccessibilityWin>
- native_view_accessibility_win_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(View);
-};
-
-} // namespace views
-
-#endif // VIEWS_VIEW_H_
diff --git a/views/view_aura.cc b/views/view_aura.cc
deleted file mode 100644
index 0f5911d..0000000
--- a/views/view_aura.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/view.h"
-
-namespace {
-
-// Default horizontal drag threshold in pixels.
-// Same as what gtk uses.
-const int kDefaultHorizontalDragThreshold = 8;
-
-// Default vertical drag threshold in pixels.
-// Same as what gtk uses.
-const int kDefaultVerticalDragThreshold = 8;
-
-} // namespace
-
-namespace views {
-
-gfx::NativeViewAccessible View::GetNativeViewAccessible() {
- return NULL;
-}
-
-int View::GetHorizontalDragThreshold() {
- // TODO(jennyz): This value may need to be adjusted for different platforms
- // and for different display density.
- return kDefaultHorizontalDragThreshold;
-}
-
-int View::GetVerticalDragThreshold() {
- // TODO(jennyz): This value may need to be adjusted for different platforms
- // and for different display density.
- return kDefaultVerticalDragThreshold;
-}
-
-} // namespace views
diff --git a/views/view_gtk.cc b/views/view_gtk.cc
deleted file mode 100644
index af62f1e..0000000
--- a/views/view_gtk.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/view.h"
-
-#include <gtk/gtk.h>
-
-#include "base/logging.h"
-
-namespace views {
-
-gfx::NativeViewAccessible View::GetNativeViewAccessible() {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-int View::GetHorizontalDragThreshold() {
- static bool determined_threshold = false;
- static int drag_threshold = 8;
- if (determined_threshold)
- return drag_threshold;
- determined_threshold = true;
- GtkSettings* settings = gtk_settings_get_default();
- if (!settings)
- return drag_threshold;
- int value = 0;
- g_object_get(G_OBJECT(settings), "gtk-dnd-drag-threshold", &value, NULL);
- if (value)
- drag_threshold = value;
- return drag_threshold;
-}
-
-int View::GetVerticalDragThreshold() {
- // Vertical and horizontal drag threshold are the same in Gtk.
- return GetHorizontalDragThreshold();
-}
-
-} // namespace views
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
deleted file mode 100644
index baee824..0000000
--- a/views/view_unittest.cc
+++ /dev/null
@@ -1,3068 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/rand_util.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "ui/base/accelerators/accelerator.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/base/models/simple_menu_model.h"
-#include "ui/gfx/canvas_skia.h"
-#include "ui/gfx/compositor/compositor.h"
-#include "ui/gfx/compositor/layer.h"
-#include "ui/gfx/compositor/layer_animator.h"
-#include "ui/gfx/compositor/test/test_compositor.h"
-#include "ui/gfx/compositor/test/test_texture.h"
-#include "ui/gfx/path.h"
-#include "ui/gfx/transform.h"
-#include "ui/views/controls/button/button_dropdown.h"
-#include "ui/views/controls/button/checkbox.h"
-#include "ui/views/controls/native/native_view_host.h"
-#include "ui/views/controls/scroll_view.h"
-#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/events/event.h"
-#include "ui/views/focus/accelerator_handler.h"
-#include "ui/views/focus/view_storage.h"
-#include "ui/views/test/views_test_base.h"
-#include "ui/views/touchui/gesture_manager.h"
-#include "ui/views/widget/native_widget.h"
-#include "ui/views/widget/root_view.h"
-#include "ui/views/window/dialog_delegate.h"
-#include "views/background.h"
-#include "views/view.h"
-#include "views/views_delegate.h"
-
-#if defined(OS_WIN)
-#include "ui/views/test/test_views_delegate.h"
-#endif
-#if defined(USE_AURA)
-#include "ui/aura/desktop.h"
-#endif
-
-using ::testing::_;
-
-namespace {
-
-// Returns true if |ancestor| is an ancestor of |layer|.
-bool LayerIsAncestor(const ui::Layer* ancestor, const ui::Layer* layer) {
- while (layer && layer != ancestor)
- layer = layer->parent();
- return layer == ancestor;
-}
-
-// Convenience functions for walking a View tree.
-const views::View* FirstView(const views::View* view) {
- const views::View* v = view;
- while (v->has_children())
- v = v->child_at(0);
- return v;
-}
-
-const views::View* NextView(const views::View* view) {
- const views::View* v = view;
- const views::View* parent = v->parent();
- if (!parent)
- return NULL;
- int next = parent->GetIndexOf(v) + 1;
- if (next != parent->child_count())
- return FirstView(parent->child_at(next));
- return parent;
-}
-
-// Convenience functions for walking a Layer tree.
-const ui::Layer* FirstLayer(const ui::Layer* layer) {
- const ui::Layer* l = layer;
- while (l->children().size() > 0)
- l = l->children()[0];
- return l;
-}
-
-const ui::Layer* NextLayer(const ui::Layer* layer) {
- const ui::Layer* parent = layer->parent();
- if (!parent)
- return NULL;
- const std::vector<ui::Layer*> children = parent->children();
- size_t index;
- for (index = 0; index < children.size(); index++) {
- if (children[index] == layer)
- break;
- }
- size_t next = index + 1;
- if (next < children.size())
- return FirstLayer(children[next]);
- return parent;
-}
-
-// Given the root nodes of a View tree and a Layer tree, makes sure the two
-// trees are in sync.
-bool ViewAndLayerTreeAreConsistent(const views::View* view,
- const ui::Layer* layer) {
- const views::View* v = FirstView(view);
- const ui::Layer* l = FirstLayer(layer);
- while (v && l) {
- // Find the view with a layer.
- while (v && !v->layer())
- v = NextView(v);
- EXPECT_TRUE(v);
- if (!v)
- return false;
-
- // Check if the View tree and the Layer tree are in sync.
- EXPECT_EQ(l, v->layer());
- if (v->layer() != l)
- return false;
-
- // Check if the visibility states of the View and the Layer are in sync.
- EXPECT_EQ(l->IsDrawn(), v->IsVisibleInRootView());
- if (v->IsVisibleInRootView() != l->IsDrawn()) {
- for (const views::View* vv = v; vv; vv = vv->parent())
- LOG(ERROR) << "V: " << vv << " " << vv->IsVisible() << " "
- << vv->IsVisibleInRootView() << " " << vv->layer();
- for (const ui::Layer* ll = l; ll; ll = ll->parent())
- LOG(ERROR) << "L: " << ll << " " << ll->IsDrawn();
- return false;
- }
-
- // Check if the size of the View and the Layer are in sync.
- EXPECT_EQ(l->bounds(), v->bounds());
- if (v->bounds() != l->bounds())
- return false;
-
- if (v == view || l == layer)
- return v == view && l == layer;
-
- v = NextView(v);
- l = NextLayer(l);
- }
-
- return false;
-}
-
-// Constructs a View tree with the specified depth.
-void ConstructTree(views::View* view, int depth) {
- if (depth == 0)
- return;
- int count = base::RandInt(1, 5);
- for (int i = 0; i < count; i++) {
- views::View* v = new views::View;
- view->AddChildView(v);
- if (base::RandDouble() > 0.5)
- v->SetPaintToLayer(true);
- if (base::RandDouble() < 0.2)
- v->SetVisible(false);
-
- ConstructTree(v, depth - 1);
- }
-}
-
-void ScrambleTree(views::View* view) {
- int count = view->child_count();
- if (count == 0)
- return;
- for (int i = 0; i < count; i++) {
- ScrambleTree(view->child_at(i));
- }
-
- if (count > 1) {
- int a = base::RandInt(0, count - 1);
- int b = base::RandInt(0, count - 1);
-
- views::View* view_a = view->child_at(a);
- views::View* view_b = view->child_at(b);
- view->ReorderChildView(view_a, b);
- view->ReorderChildView(view_b, a);
- }
-
- if (!view->layer() && base::RandDouble() < 0.1)
- view->SetPaintToLayer(true);
-
- if (base::RandDouble() < 0.1)
- view->SetVisible(!view->IsVisible());
-}
-
-}
-
-namespace views {
-
-typedef ViewsTestBase ViewTest;
-
-// A derived class for testing purpose.
-class TestView : public View {
- public:
- TestView() : View(), in_touch_sequence_(false) {}
- virtual ~TestView() {}
-
- // Reset all test state
- void Reset() {
- did_change_bounds_ = false;
- last_mouse_event_type_ = 0;
- location_.SetPoint(0, 0);
- last_touch_event_type_ = 0;
- last_touch_event_was_handled_ = false;
- last_clip_.setEmpty();
- accelerator_count_map_.clear();
- }
-
- virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
- virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
- virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
- virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
- virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
- virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
- virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
-
- // OnBoundsChanged.
- bool did_change_bounds_;
- gfx::Rect new_bounds_;
-
- // MouseEvent.
- int last_mouse_event_type_;
- gfx::Point location_;
-
- // Painting.
- std::vector<gfx::Rect> scheduled_paint_rects_;
-
- // TouchEvent.
- int last_touch_event_type_;
- bool last_touch_event_was_handled_;
- bool in_touch_sequence_;
-
- // Painting.
- SkRect last_clip_;
-
- // Accelerators.
- std::map<ui::Accelerator, int> accelerator_count_map_;
-};
-
-// Mock instance of the GestureManager for testing.
-class MockGestureManager : public GestureManager {
- public:
- // Reset all test state.
- void Reset() {
- last_touch_event_ = 0;
- last_view_ = NULL;
- previously_handled_flag_ = false;
- dispatched_synthetic_event_ = false;
- }
-
- bool ProcessTouchEventForGesture(const TouchEvent& event,
- View* source,
- ui::TouchStatus status);
- MockGestureManager();
-
- bool previously_handled_flag_;
- int last_touch_event_;
- View *last_view_;
- bool dispatched_synthetic_event_;
-
- DISALLOW_COPY_AND_ASSIGN(MockGestureManager);
-};
-
-// A view subclass that ignores all touch events for testing purposes.
-class TestViewIgnoreTouch : public TestView {
- public:
- TestViewIgnoreTouch() : TestView() {}
- virtual ~TestViewIgnoreTouch() {}
-
- private:
- virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// OnBoundsChanged
-////////////////////////////////////////////////////////////////////////////////
-
-void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
- did_change_bounds_ = true;
- new_bounds_ = bounds();
-}
-
-TEST_F(ViewTest, OnBoundsChanged) {
- TestView v;
-
- gfx::Rect prev_rect(0, 0, 200, 200);
- gfx::Rect new_rect(100, 100, 250, 250);
-
- v.SetBoundsRect(prev_rect);
- v.Reset();
- v.SetBoundsRect(new_rect);
-
- EXPECT_EQ(v.did_change_bounds_, true);
- EXPECT_EQ(v.new_bounds_, new_rect);
- EXPECT_EQ(v.bounds(), new_rect);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// MouseEvent
-////////////////////////////////////////////////////////////////////////////////
-
-bool TestView::OnMousePressed(const MouseEvent& event) {
- last_mouse_event_type_ = event.type();
- location_.SetPoint(event.x(), event.y());
- return true;
-}
-
-bool TestView::OnMouseDragged(const MouseEvent& event) {
- last_mouse_event_type_ = event.type();
- location_.SetPoint(event.x(), event.y());
- return true;
-}
-
-void TestView::OnMouseReleased(const MouseEvent& event) {
- last_mouse_event_type_ = event.type();
- location_.SetPoint(event.x(), event.y());
-}
-
-TEST_F(ViewTest, MouseEvent) {
- TestView* v1 = new TestView();
- v1->SetBounds(0, 0, 300, 300);
-
- TestView* v2 = new TestView();
- v2->SetBounds(100, 100, 100, 100);
-
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(50, 50, 650, 650);
- widget->Init(params);
- View* root = widget->GetRootView();
-
- root->AddChildView(v1);
- v1->AddChildView(v2);
-
- v1->Reset();
- v2->Reset();
-
- MouseEvent pressed(ui::ET_MOUSE_PRESSED,
- 110,
- 120,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMousePressed(pressed);
- EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_PRESSED);
- EXPECT_EQ(v2->location_.x(), 10);
- EXPECT_EQ(v2->location_.y(), 20);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_mouse_event_type_, 0);
-
- // Drag event out of bounds. Should still go to v2
- v1->Reset();
- v2->Reset();
- MouseEvent dragged(ui::ET_MOUSE_DRAGGED,
- 50,
- 40,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMouseDragged(dragged);
- EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_DRAGGED);
- EXPECT_EQ(v2->location_.x(), -50);
- EXPECT_EQ(v2->location_.y(), -60);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_mouse_event_type_, 0);
-
- // Releasted event out of bounds. Should still go to v2
- v1->Reset();
- v2->Reset();
- MouseEvent released(ui::ET_MOUSE_RELEASED, 0, 0, 0);
- root->OnMouseDragged(released);
- EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_RELEASED);
- EXPECT_EQ(v2->location_.x(), -100);
- EXPECT_EQ(v2->location_.y(), -100);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_mouse_event_type_, 0);
-
- widget->CloseNow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TouchEvent
-////////////////////////////////////////////////////////////////////////////////
-bool MockGestureManager::ProcessTouchEventForGesture(
- const TouchEvent& event,
- View* source,
- ui::TouchStatus status) {
- if (status != ui::TOUCH_STATUS_UNKNOWN) {
- dispatched_synthetic_event_ = false;
- return false;
- }
- last_touch_event_ = event.type();
- last_view_ = source;
- previously_handled_flag_ = status != ui::TOUCH_STATUS_UNKNOWN;
- dispatched_synthetic_event_ = true;
- return true;
-}
-
-MockGestureManager::MockGestureManager() {
-}
-
-ui::TouchStatus TestView::OnTouchEvent(const TouchEvent& event) {
- last_touch_event_type_ = event.type();
- location_.SetPoint(event.x(), event.y());
- if (!in_touch_sequence_) {
- if (event.type() == ui::ET_TOUCH_PRESSED) {
- in_touch_sequence_ = true;
- return ui::TOUCH_STATUS_START;
- }
- } else {
- if (event.type() == ui::ET_TOUCH_RELEASED) {
- in_touch_sequence_ = false;
- return ui::TOUCH_STATUS_END;
- }
- return ui::TOUCH_STATUS_CONTINUE;
- }
- return last_touch_event_was_handled_ ? ui::TOUCH_STATUS_CONTINUE :
- ui::TOUCH_STATUS_UNKNOWN;
-}
-
-ui::TouchStatus TestViewIgnoreTouch::OnTouchEvent(const TouchEvent& event) {
- return ui::TOUCH_STATUS_UNKNOWN;
-}
-
-TEST_F(ViewTest, TouchEvent) {
- MockGestureManager gm;
-
- TestView* v1 = new TestView();
- v1->SetBounds(0, 0, 300, 300);
-
- TestView* v2 = new TestView();
- v2->SetBounds(100, 100, 100, 100);
-
- TestView* v3 = new TestViewIgnoreTouch();
- v3->SetBounds(0, 0, 100, 100);
-
- scoped_ptr<Widget> widget(new Widget());
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(50, 50, 650, 650);
- widget->Init(params);
- View* root = widget->GetRootView();
-
- root->AddChildView(v1);
- static_cast<internal::RootView*>(root)->SetGestureManagerForTesting(&gm);
- v1->AddChildView(v2);
- v2->AddChildView(v3);
-
- // |v3| completely obscures |v2|, but all the touch events on |v3| should
- // reach |v2| because |v3| doesn't process any touch events.
-
- // Make sure if none of the views handle the touch event, the gesture manager
- // does.
- v1->Reset();
- v2->Reset();
- gm.Reset();
-
- TouchEvent unhandled(ui::ET_TOUCH_MOVED,
- 400,
- 400,
- 0, /* no flags */
- 0, /* first finger touch */
- 1.0, 0.0, 1.0, 0.0);
- root->OnTouchEvent(unhandled);
-
- EXPECT_EQ(v1->last_touch_event_type_, 0);
- EXPECT_EQ(v2->last_touch_event_type_, 0);
-
- EXPECT_EQ(gm.previously_handled_flag_, false);
- EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_MOVED);
- EXPECT_EQ(gm.last_view_, root);
- EXPECT_EQ(gm.dispatched_synthetic_event_, true);
-
- // Test press, drag, release touch sequence.
- v1->Reset();
- v2->Reset();
- gm.Reset();
-
- TouchEvent pressed(ui::ET_TOUCH_PRESSED,
- 110,
- 120,
- 0, /* no flags */
- 0, /* first finger touch */
- 1.0, 0.0, 1.0, 0.0);
- v2->last_touch_event_was_handled_ = true;
- root->OnTouchEvent(pressed);
-
- EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_PRESSED);
- EXPECT_EQ(v2->location_.x(), 10);
- EXPECT_EQ(v2->location_.y(), 20);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_touch_event_type_, 0);
-
- // Since v2 handled the touch-event, the gesture manager should not handle it.
- EXPECT_EQ(gm.last_touch_event_, 0);
- EXPECT_EQ(NULL, gm.last_view_);
- EXPECT_EQ(gm.previously_handled_flag_, false);
-
- // Drag event out of bounds. Should still go to v2
- v1->Reset();
- v2->Reset();
- TouchEvent dragged(ui::ET_TOUCH_MOVED,
- 50,
- 40,
- 0, /* no flags */
- 0, /* first finger touch */
- 1.0, 0.0, 1.0, 0.0);
-
- root->OnTouchEvent(dragged);
- EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_MOVED);
- EXPECT_EQ(v2->location_.x(), -50);
- EXPECT_EQ(v2->location_.y(), -60);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_touch_event_type_, 0);
-
- EXPECT_EQ(gm.last_touch_event_, 0);
- EXPECT_EQ(NULL, gm.last_view_);
- EXPECT_EQ(gm.previously_handled_flag_, false);
-
- // Released event out of bounds. Should still go to v2
- v1->Reset();
- v2->Reset();
- TouchEvent released(ui::ET_TOUCH_RELEASED, 0, 0, 0, 0 /* first finger */,
- 1.0, 0.0, 1.0, 0.0);
- v2->last_touch_event_was_handled_ = true;
- root->OnTouchEvent(released);
- EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_RELEASED);
- EXPECT_EQ(v2->location_.x(), -100);
- EXPECT_EQ(v2->location_.y(), -100);
- // Make sure v1 did not receive the event
- EXPECT_EQ(v1->last_touch_event_type_, 0);
-
- EXPECT_EQ(gm.last_touch_event_, 0);
- EXPECT_EQ(NULL, gm.last_view_);
- EXPECT_EQ(gm.previously_handled_flag_, false);
-
- widget->CloseNow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Painting
-////////////////////////////////////////////////////////////////////////////////
-
-void TestView::Paint(gfx::Canvas* canvas) {
- canvas->GetSkCanvas()->getClipBounds(&last_clip_);
-}
-
-void TestView::SchedulePaintInRect(const gfx::Rect& rect) {
- scheduled_paint_rects_.push_back(rect);
- View::SchedulePaintInRect(rect);
-}
-
-void CheckRect(const SkRect& check_rect, const SkRect& target_rect) {
- EXPECT_EQ(target_rect.fLeft, check_rect.fLeft);
- EXPECT_EQ(target_rect.fRight, check_rect.fRight);
- EXPECT_EQ(target_rect.fTop, check_rect.fTop);
- EXPECT_EQ(target_rect.fBottom, check_rect.fBottom);
-}
-
-/* This test is disabled because it is flakey on some systems.
-TEST_F(ViewTest, DISABLED_Painting) {
- // Determine if InvalidateRect generates an empty paint rectangle.
- EmptyWindow paint_window(CRect(50, 50, 650, 650));
- paint_window.RedrawWindow(CRect(0, 0, 600, 600), NULL,
- RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN);
- bool empty_paint = paint_window.empty_paint();
-
- NativeWidgetWin window;
- window.set_delete_on_destroy(false);
- window.set_window_style(WS_OVERLAPPEDWINDOW);
- window.Init(NULL, gfx::Rect(50, 50, 650, 650), NULL);
- View* root = window.GetRootView();
-
- TestView* v1 = new TestView();
- v1->SetBounds(0, 0, 650, 650);
- root->AddChildView(v1);
-
- TestView* v2 = new TestView();
- v2->SetBounds(10, 10, 80, 80);
- v1->AddChildView(v2);
-
- TestView* v3 = new TestView();
- v3->SetBounds(10, 10, 60, 60);
- v2->AddChildView(v3);
-
- TestView* v4 = new TestView();
- v4->SetBounds(10, 200, 100, 100);
- v1->AddChildView(v4);
-
- // Make sure to paint current rects
- PaintRootView(root, empty_paint);
-
-
- v1->Reset();
- v2->Reset();
- v3->Reset();
- v4->Reset();
- v3->SchedulePaintInRect(gfx::Rect(10, 10, 10, 10));
- PaintRootView(root, empty_paint);
-
- SkRect tmp_rect;
-
- tmp_rect.set(SkIntToScalar(10),
- SkIntToScalar(10),
- SkIntToScalar(20),
- SkIntToScalar(20));
- CheckRect(v3->last_clip_, tmp_rect);
-
- tmp_rect.set(SkIntToScalar(20),
- SkIntToScalar(20),
- SkIntToScalar(30),
- SkIntToScalar(30));
- CheckRect(v2->last_clip_, tmp_rect);
-
- tmp_rect.set(SkIntToScalar(30),
- SkIntToScalar(30),
- SkIntToScalar(40),
- SkIntToScalar(40));
- CheckRect(v1->last_clip_, tmp_rect);
-
- // Make sure v4 was not painted
- tmp_rect.setEmpty();
- CheckRect(v4->last_clip_, tmp_rect);
-
- window.DestroyWindow();
-}
-*/
-
-#if defined(OS_WIN)
-TEST_F(ViewTest, RemoveNotification) {
-#else
-// TODO(beng): stopped working with widget hierarchy split,
-// http://crbug.com/82364
-TEST_F(ViewTest, DISABLED_RemoveNotification) {
-#endif
- ViewStorage* vs = ViewStorage::GetInstance();
- Widget* widget = new Widget;
- widget->Init(Widget::InitParams(Widget::InitParams::TYPE_POPUP));
- View* root_view = widget->GetRootView();
-
- View* v1 = new View;
- int s1 = vs->CreateStorageID();
- vs->StoreView(s1, v1);
- root_view->AddChildView(v1);
- View* v11 = new View;
- int s11 = vs->CreateStorageID();
- vs->StoreView(s11, v11);
- v1->AddChildView(v11);
- View* v111 = new View;
- int s111 = vs->CreateStorageID();
- vs->StoreView(s111, v111);
- v11->AddChildView(v111);
- View* v112 = new View;
- int s112 = vs->CreateStorageID();
- vs->StoreView(s112, v112);
- v11->AddChildView(v112);
- View* v113 = new View;
- int s113 = vs->CreateStorageID();
- vs->StoreView(s113, v113);
- v11->AddChildView(v113);
- View* v1131 = new View;
- int s1131 = vs->CreateStorageID();
- vs->StoreView(s1131, v1131);
- v113->AddChildView(v1131);
- View* v12 = new View;
- int s12 = vs->CreateStorageID();
- vs->StoreView(s12, v12);
- v1->AddChildView(v12);
-
- View* v2 = new View;
- int s2 = vs->CreateStorageID();
- vs->StoreView(s2, v2);
- root_view->AddChildView(v2);
- View* v21 = new View;
- int s21 = vs->CreateStorageID();
- vs->StoreView(s21, v21);
- v2->AddChildView(v21);
- View* v211 = new View;
- int s211 = vs->CreateStorageID();
- vs->StoreView(s211, v211);
- v21->AddChildView(v211);
-
- size_t stored_views = vs->view_count();
-
- // Try removing a leaf view.
- v21->RemoveChildView(v211);
- EXPECT_EQ(stored_views - 1, vs->view_count());
- EXPECT_EQ(NULL, vs->RetrieveView(s211));
- delete v211; // We won't use this one anymore.
-
- // Now try removing a view with a hierarchy of depth 1.
- v11->RemoveChildView(v113);
- EXPECT_EQ(stored_views - 3, vs->view_count());
- EXPECT_EQ(NULL, vs->RetrieveView(s113));
- EXPECT_EQ(NULL, vs->RetrieveView(s1131));
- delete v113; // We won't use this one anymore.
-
- // Now remove even more.
- root_view->RemoveChildView(v1);
- EXPECT_EQ(NULL, vs->RetrieveView(s1));
- EXPECT_EQ(NULL, vs->RetrieveView(s11));
- EXPECT_EQ(NULL, vs->RetrieveView(s12));
- EXPECT_EQ(NULL, vs->RetrieveView(s111));
- EXPECT_EQ(NULL, vs->RetrieveView(s112));
-
- // Put v1 back for more tests.
- root_view->AddChildView(v1);
- vs->StoreView(s1, v1);
-
- // Synchronously closing the window deletes the view hierarchy, which should
- // remove all its views from ViewStorage.
- widget->CloseNow();
- EXPECT_EQ(stored_views - 10, vs->view_count());
- EXPECT_EQ(NULL, vs->RetrieveView(s1));
- EXPECT_EQ(NULL, vs->RetrieveView(s12));
- EXPECT_EQ(NULL, vs->RetrieveView(s11));
- EXPECT_EQ(NULL, vs->RetrieveView(s12));
- EXPECT_EQ(NULL, vs->RetrieveView(s21));
- EXPECT_EQ(NULL, vs->RetrieveView(s111));
- EXPECT_EQ(NULL, vs->RetrieveView(s112));
-}
-
-namespace {
-class HitTestView : public View {
- public:
- explicit HitTestView(bool has_hittest_mask)
- : has_hittest_mask_(has_hittest_mask) {
- }
- virtual ~HitTestView() {}
-
- protected:
- // Overridden from View:
- virtual bool HasHitTestMask() const {
- return has_hittest_mask_;
- }
- virtual void GetHitTestMask(gfx::Path* mask) const {
- DCHECK(has_hittest_mask_);
- DCHECK(mask);
-
- SkScalar w = SkIntToScalar(width());
- SkScalar h = SkIntToScalar(height());
-
- // Create a triangular mask within the bounds of this View.
- mask->moveTo(w / 2, 0);
- mask->lineTo(w, h);
- mask->lineTo(0, h);
- mask->close();
- }
-
- private:
- bool has_hittest_mask_;
-
- DISALLOW_COPY_AND_ASSIGN(HitTestView);
-};
-
-gfx::Point ConvertPointToView(View* view, const gfx::Point& p) {
- gfx::Point tmp(p);
- View::ConvertPointToView(view->GetWidget()->GetRootView(), view, &tmp);
- return tmp;
-}
-
-void RotateCounterclockwise(ui::Transform& transform) {
- transform.matrix().set3x3(0, -1, 0,
- 1, 0, 0,
- 0, 0, 1);
-}
-
-void RotateClockwise(ui::Transform& transform) {
- transform.matrix().set3x3( 0, 1, 0,
- -1, 0, 0,
- 0, 0, 1);
-}
-
-} // namespace
-
-TEST_F(ViewTest, HitTestMasks) {
- Widget* widget = new Widget;
- widget->Init(Widget::InitParams(Widget::InitParams::TYPE_POPUP));
- View* root_view = widget->GetRootView();
- root_view->SetBounds(0, 0, 500, 500);
-
- gfx::Rect v1_bounds = gfx::Rect(0, 0, 100, 100);
- HitTestView* v1 = new HitTestView(false);
- v1->SetBoundsRect(v1_bounds);
- root_view->AddChildView(v1);
-
- gfx::Rect v2_bounds = gfx::Rect(105, 0, 100, 100);
- HitTestView* v2 = new HitTestView(true);
- v2->SetBoundsRect(v2_bounds);
- root_view->AddChildView(v2);
-
- gfx::Point v1_centerpoint = v1_bounds.CenterPoint();
- gfx::Point v2_centerpoint = v2_bounds.CenterPoint();
- gfx::Point v1_origin = v1_bounds.origin();
- gfx::Point v2_origin = v2_bounds.origin();
-
- // Test HitTest
- EXPECT_TRUE(v1->HitTest(ConvertPointToView(v1, v1_centerpoint)));
- EXPECT_TRUE(v2->HitTest(ConvertPointToView(v2, v2_centerpoint)));
-
- EXPECT_TRUE(v1->HitTest(ConvertPointToView(v1, v1_origin)));
- EXPECT_FALSE(v2->HitTest(ConvertPointToView(v2, v2_origin)));
-
- // Test GetEventHandlerForPoint
- EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_centerpoint));
- EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint));
- EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin));
- EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin));
-
- widget->CloseNow();
-}
-
-TEST_F(ViewTest, Textfield) {
- const string16 kText = ASCIIToUTF16("Reality is that which, when you stop "
- "believing it, doesn't go away.");
- const string16 kExtraText = ASCIIToUTF16("Pretty deep, Philip!");
- const string16 kEmptyString;
-
- ui::Clipboard clipboard;
-
- Widget* widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget->Init(params);
- View* root_view = widget->GetRootView();
-
- Textfield* textfield = new Textfield();
- root_view->AddChildView(textfield);
-
- // Test setting, appending text.
- textfield->SetText(kText);
- EXPECT_EQ(kText, textfield->text());
- textfield->AppendText(kExtraText);
- EXPECT_EQ(kText + kExtraText, textfield->text());
- textfield->SetText(string16());
- EXPECT_EQ(kEmptyString, textfield->text());
-
- // Test selection related methods.
- textfield->SetText(kText);
- EXPECT_EQ(kEmptyString, textfield->GetSelectedText());
- textfield->SelectAll();
- EXPECT_EQ(kText, textfield->text());
- textfield->ClearSelection();
- EXPECT_EQ(kEmptyString, textfield->GetSelectedText());
-
- widget->CloseNow();
-}
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-
-// Tests that the Textfield view respond appropiately to cut/copy/paste.
-TEST_F(ViewTest, TextfieldCutCopyPaste) {
- const string16 kNormalText = ASCIIToUTF16("Normal");
- const string16 kReadOnlyText = ASCIIToUTF16("Read only");
- const string16 kPasswordText = ASCIIToUTF16("Password! ** Secret stuff **");
-
- ui::Clipboard clipboard;
-
- Widget* widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget->Init(params);
- View* root_view = widget->GetRootView();
-
- Textfield* normal = new Textfield();
- Textfield* read_only = new Textfield();
- read_only->SetReadOnly(true);
- Textfield* password = new Textfield(Textfield::STYLE_PASSWORD);
-
- root_view->AddChildView(normal);
- root_view->AddChildView(read_only);
- root_view->AddChildView(password);
-
- normal->SetText(kNormalText);
- read_only->SetText(kReadOnlyText);
- password->SetText(kPasswordText);
-
- //
- // Test cut.
- //
- ASSERT_TRUE(normal->GetTestingHandle());
- normal->SelectAll();
- ::SendMessage(normal->GetTestingHandle(), WM_CUT, 0, 0);
-
- string16 result;
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- EXPECT_EQ(kNormalText, result);
- normal->SetText(kNormalText); // Let's revert to the original content.
-
- ASSERT_TRUE(read_only->GetTestingHandle());
- read_only->SelectAll();
- ::SendMessage(read_only->GetTestingHandle(), WM_CUT, 0, 0);
- result.clear();
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- // Cut should have failed, so the clipboard content should not have changed.
- EXPECT_EQ(kNormalText, result);
-
- ASSERT_TRUE(password->GetTestingHandle());
- password->SelectAll();
- ::SendMessage(password->GetTestingHandle(), WM_CUT, 0, 0);
- result.clear();
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- // Cut should have failed, so the clipboard content should not have changed.
- EXPECT_EQ(kNormalText, result);
-
- //
- // Test copy.
- //
-
- // Let's start with read_only as the clipboard already contains the content
- // of normal.
- read_only->SelectAll();
- ::SendMessage(read_only->GetTestingHandle(), WM_COPY, 0, 0);
- result.clear();
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- EXPECT_EQ(kReadOnlyText, result);
-
- normal->SelectAll();
- ::SendMessage(normal->GetTestingHandle(), WM_COPY, 0, 0);
- result.clear();
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- EXPECT_EQ(kNormalText, result);
-
- password->SelectAll();
- ::SendMessage(password->GetTestingHandle(), WM_COPY, 0, 0);
- result.clear();
- clipboard.ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
- // We don't let you copy from a password field, clipboard should not have
- // changed.
- EXPECT_EQ(kNormalText, result);
-
- //
- // Test Paste.
- //
- // Note that we use GetWindowText instead of Textfield::GetText below as the
- // text in the Textfield class is synced to the text of the HWND on
- // WM_KEYDOWN messages that we are not simulating here.
-
- // Attempting to copy kNormalText in a read-only text-field should fail.
- read_only->SelectAll();
- ::SendMessage(read_only->GetTestingHandle(), WM_KEYDOWN, 0, 0);
- wchar_t buffer[1024] = { 0 };
- ::GetWindowText(read_only->GetTestingHandle(), buffer, 1024);
- EXPECT_EQ(kReadOnlyText, string16(buffer));
-
- password->SelectAll();
- ::SendMessage(password->GetTestingHandle(), WM_PASTE, 0, 0);
- ::GetWindowText(password->GetTestingHandle(), buffer, 1024);
- EXPECT_EQ(kNormalText, string16(buffer));
-
- // Copy from read_only so the string we are pasting is not the same as the
- // current one.
- read_only->SelectAll();
- ::SendMessage(read_only->GetTestingHandle(), WM_COPY, 0, 0);
- normal->SelectAll();
- ::SendMessage(normal->GetTestingHandle(), WM_PASTE, 0, 0);
- ::GetWindowText(normal->GetTestingHandle(), buffer, 1024);
- EXPECT_EQ(kReadOnlyText, string16(buffer));
- widget->CloseNow();
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Accelerators
-////////////////////////////////////////////////////////////////////////////////
-bool TestView::AcceleratorPressed(const ui::Accelerator& accelerator) {
- accelerator_count_map_[accelerator]++;
- return true;
-}
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-TEST_F(ViewTest, ActivateAccelerator) {
- // Register a keyboard accelerator before the view is added to a window.
- ui::Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false);
- TestView* view = new TestView();
- view->Reset();
- view->AddAccelerator(return_accelerator);
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
-
- // Create a window and add the view as its child.
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget->Init(params);
- View* root = widget->GetRootView();
- root->AddChildView(view);
- widget->Show();
-
- // Get the focus manager.
- FocusManager* focus_manager = widget->GetFocusManager();
- ASSERT_TRUE(focus_manager);
-
- // Hit the return key and see if it takes effect.
- EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
-
- // Hit the escape key. Nothing should happen.
- ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, false, false, false);
- EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 0);
-
- // Now register the escape key and hit it again.
- view->AddAccelerator(escape_accelerator);
- EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
-
- // Remove the return key accelerator.
- view->RemoveAccelerator(return_accelerator);
- EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
-
- // Add it again. Hit the return key and the escape key.
- view->AddAccelerator(return_accelerator);
- EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
- EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
-
- // Remove all the accelerators.
- view->ResetAccelerators();
- EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
- EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
- EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
-
- widget->CloseNow();
-}
-#endif
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-TEST_F(ViewTest, HiddenViewWithAccelerator) {
- ui::Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false);
- TestView* view = new TestView();
- view->Reset();
- view->AddAccelerator(return_accelerator);
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
-
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget->Init(params);
- View* root = widget->GetRootView();
- root->AddChildView(view);
- widget->Show();
-
- FocusManager* focus_manager = widget->GetFocusManager();
- ASSERT_TRUE(focus_manager);
-
- view->SetVisible(false);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
- view->SetVisible(true);
- EXPECT_EQ(view,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
- widget->CloseNow();
-}
-#endif
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-TEST_F(ViewTest, ViewInHiddenWidgetWithAccelerator) {
- ui::Accelerator return_accelerator(ui::VKEY_RETURN, false, false, false);
- TestView* view = new TestView();
- view->Reset();
- view->AddAccelerator(return_accelerator);
- EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
-
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget->Init(params);
- View* root = widget->GetRootView();
- root->AddChildView(view);
-
- FocusManager* focus_manager = widget->GetFocusManager();
- ASSERT_TRUE(focus_manager);
-
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
- widget->Show();
- EXPECT_EQ(view,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
- widget->Hide();
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
- widget->CloseNow();
-}
-#endif
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-////////////////////////////////////////////////////////////////////////////////
-// Mouse-wheel message rerouting
-////////////////////////////////////////////////////////////////////////////////
-class ScrollableTestView : public View {
- public:
- ScrollableTestView() { }
-
- virtual gfx::Size GetPreferredSize() {
- return gfx::Size(100, 10000);
- }
-
- virtual void Layout() {
- SizeToPreferredSize();
- }
-};
-
-class TestViewWithControls : public View {
- public:
- TestViewWithControls() {
- text_field_ = new Textfield();
- AddChildView(text_field_);
- }
-
- Textfield* text_field_;
-};
-
-class SimpleWidgetDelegate : public WidgetDelegate {
- public:
- explicit SimpleWidgetDelegate(View* contents) : contents_(contents) { }
-
- virtual void DeleteDelegate() { delete this; }
-
- virtual View* GetContentsView() { return contents_; }
-
- virtual Widget* GetWidget() { return contents_->GetWidget(); }
- virtual const Widget* GetWidget() const { return contents_->GetWidget(); }
-
- private:
- View* contents_;
-};
-
-// Tests that the mouse-wheel messages are correctly rerouted to the window
-// under the mouse.
-// TODO(jcampan): http://crbug.com/10572 Disabled as it fails on the Vista build
-// bot.
-// Note that this fails for a variety of reasons:
-// - focused view is apparently reset across window activations and never
-// properly restored
-// - this test depends on you not having any other window visible open under the
-// area that it opens the test windows. --beng
-TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) {
- TestViewWithControls* view_with_controls = new TestViewWithControls();
- Widget* window1 = Widget::CreateWindowWithBounds(
- new SimpleWidgetDelegate(view_with_controls),
- gfx::Rect(0, 0, 100, 100));
- window1->Show();
- ScrollView* scroll_view = new ScrollView();
- scroll_view->SetContents(new ScrollableTestView());
- Widget* window2 = Widget::CreateWindowWithBounds(
- new SimpleWidgetDelegate(scroll_view),
- gfx::Rect(200, 200, 100, 100));
- window2->Show();
- EXPECT_EQ(0, scroll_view->GetVisibleRect().y());
-
- // Make the window1 active, as this is what it would be in real-world.
- window1->Activate();
-
- // Let's send a mouse-wheel message to the different controls and check that
- // it is rerouted to the window under the mouse (effectively scrolling the
- // scroll-view).
-
- // First to the Window's HWND.
- ::SendMessage(view_with_controls->GetWidget()->GetNativeView(),
- WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(250, 250));
- EXPECT_EQ(20, scroll_view->GetVisibleRect().y());
-
- // Then the text-field.
- ::SendMessage(view_with_controls->text_field_->GetTestingHandle(),
- WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(250, 250));
- EXPECT_EQ(80, scroll_view->GetVisibleRect().y());
-
- // Ensure we don't scroll when the mouse is not over that window.
- ::SendMessage(view_with_controls->text_field_->GetTestingHandle(),
- WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(50, 50));
- EXPECT_EQ(80, scroll_view->GetVisibleRect().y());
-
- window1->CloseNow();
- window2->CloseNow();
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// Dialogs' default button
-////////////////////////////////////////////////////////////////////////////////
-
-class MockMenuModel : public ui::MenuModel {
- public:
- MOCK_CONST_METHOD0(HasIcons, bool());
- MOCK_CONST_METHOD1(GetFirstItemIndex, int(gfx::NativeMenu native_menu));
- MOCK_CONST_METHOD0(GetItemCount, int());
- MOCK_CONST_METHOD1(GetTypeAt, ItemType(int index));
- MOCK_CONST_METHOD1(GetCommandIdAt, int(int index));
- MOCK_CONST_METHOD1(GetLabelAt, string16(int index));
- MOCK_CONST_METHOD1(IsItemDynamicAt, bool(int index));
- MOCK_CONST_METHOD1(GetLabelFontAt, const gfx::Font* (int index));
- MOCK_CONST_METHOD2(GetAcceleratorAt, bool(int index,
- ui::Accelerator* accelerator));
- MOCK_CONST_METHOD1(IsItemCheckedAt, bool(int index));
- MOCK_CONST_METHOD1(GetGroupIdAt, int(int index));
- MOCK_METHOD2(GetIconAt, bool(int index, SkBitmap* icon));
- MOCK_CONST_METHOD1(GetButtonMenuItemAt, ui::ButtonMenuItemModel*(int index));
- MOCK_CONST_METHOD1(IsEnabledAt, bool(int index));
- MOCK_CONST_METHOD1(IsVisibleAt, bool(int index));
- MOCK_CONST_METHOD1(GetSubmenuModelAt, MenuModel*(int index));
- MOCK_METHOD1(HighlightChangedTo, void(int index));
- MOCK_METHOD1(ActivatedAt, void(int index));
- MOCK_METHOD2(ActivatedAt, void(int index, int disposition));
- MOCK_METHOD0(MenuWillShow, void());
- MOCK_METHOD0(MenuClosed, void());
- MOCK_METHOD1(SetMenuModelDelegate, void(ui::MenuModelDelegate* delegate));
- MOCK_METHOD3(GetModelAndIndexForCommandId, bool(int command_id,
- MenuModel** model, int* index));
-};
-
-class TestDialog : public DialogDelegate, public ButtonListener {
- public:
- explicit TestDialog(MockMenuModel* mock_menu_model)
- : contents_(NULL),
- button1_(NULL),
- button2_(NULL),
- checkbox_(NULL),
- button_drop_(NULL),
- last_pressed_button_(NULL),
- mock_menu_model_(mock_menu_model),
- canceled_(false),
- oked_(false),
- closeable_(false),
- widget_(NULL) {
- }
-
- void TearDown() {
- // Now we can close safely.
- closeable_ = true;
- widget_->Close();
- widget_ = NULL;
- // delegate has to be alive while shutting down.
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
- }
-
- // DialogDelegate implementation:
- virtual int GetDefaultDialogButton() const OVERRIDE {
- return ui::DIALOG_BUTTON_OK;
- }
-
- virtual View* GetContentsView() OVERRIDE {
- if (!contents_) {
- contents_ = new View;
- button1_ = new NativeTextButton(this, ASCIIToUTF16("Button1"));
- button2_ = new NativeTextButton(this, ASCIIToUTF16("Button2"));
- checkbox_ = new Checkbox(ASCIIToUTF16("My checkbox"));
- button_drop_ = new ButtonDropDown(this, mock_menu_model_);
- contents_->AddChildView(button1_);
- contents_->AddChildView(button2_);
- contents_->AddChildView(checkbox_);
- contents_->AddChildView(button_drop_);
- }
- return contents_;
- }
-
- // Prevent the dialog from really closing (so we can click the OK/Cancel
- // buttons to our heart's content).
- virtual bool Cancel() OVERRIDE {
- canceled_ = true;
- return closeable_;
- }
- virtual bool Accept() OVERRIDE {
- oked_ = true;
- return closeable_;
- }
-
- virtual Widget* GetWidget() OVERRIDE {
- return widget_;
- }
- virtual const Widget* GetWidget() const OVERRIDE {
- return widget_;
- }
-
- // ButtonListener implementation.
- virtual void ButtonPressed(Button* sender, const Event& event) OVERRIDE {
- last_pressed_button_ = sender;
- }
-
- void ResetStates() {
- oked_ = false;
- canceled_ = false;
- last_pressed_button_ = NULL;
- }
-
- // Set up expectations for methods that are called when an (empty) menu is
- // shown from a drop down button.
- void ExpectShowDropMenu() {
- if (mock_menu_model_) {
- EXPECT_CALL(*mock_menu_model_, HasIcons());
- EXPECT_CALL(*mock_menu_model_, GetFirstItemIndex(_));
- EXPECT_CALL(*mock_menu_model_, GetItemCount());
- EXPECT_CALL(*mock_menu_model_, MenuClosed());
- }
- }
-
- View* contents_;
- NativeTextButton* button1_;
- NativeTextButton* button2_;
- Checkbox* checkbox_;
- ButtonDropDown* button_drop_;
- Button* last_pressed_button_;
- MockMenuModel* mock_menu_model_;
-
- bool canceled_;
- bool oked_;
- bool closeable_;
- Widget* widget_;
-};
-
-class DefaultButtonTest : public ViewTest {
- public:
- enum ButtonID {
- OK,
- CANCEL,
- BUTTON1,
- BUTTON2
- };
-
- DefaultButtonTest()
- : focus_manager_(NULL),
- test_dialog_(NULL),
- client_view_(NULL),
- ok_button_(NULL),
- cancel_button_(NULL) {
- }
-
- virtual void SetUp() OVERRIDE {
- ViewTest::SetUp();
- test_dialog_ = new TestDialog(NULL);
- Widget* window =
- Widget::CreateWindowWithBounds(test_dialog_, gfx::Rect(0, 0, 100, 100));
- test_dialog_->widget_ = window;
- window->Show();
- focus_manager_ = test_dialog_->contents_->GetFocusManager();
- ASSERT_TRUE(focus_manager_ != NULL);
- client_view_ =
- static_cast<DialogClientView*>(window->client_view());
- ok_button_ = client_view_->ok_button();
- cancel_button_ = client_view_->cancel_button();
- }
-
- virtual void TearDown() OVERRIDE {
- test_dialog_->TearDown();
- ViewTest::TearDown();
- }
-
- void SimulatePressingEnterAndCheckDefaultButton(ButtonID button_id) {
- KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);
- focus_manager_->OnKeyEvent(event);
- switch (button_id) {
- case OK:
- EXPECT_TRUE(test_dialog_->oked_);
- EXPECT_FALSE(test_dialog_->canceled_);
- EXPECT_FALSE(test_dialog_->last_pressed_button_);
- break;
- case CANCEL:
- EXPECT_FALSE(test_dialog_->oked_);
- EXPECT_TRUE(test_dialog_->canceled_);
- EXPECT_FALSE(test_dialog_->last_pressed_button_);
- break;
- case BUTTON1:
- EXPECT_FALSE(test_dialog_->oked_);
- EXPECT_FALSE(test_dialog_->canceled_);
- EXPECT_TRUE(test_dialog_->last_pressed_button_ ==
- test_dialog_->button1_);
- break;
- case BUTTON2:
- EXPECT_FALSE(test_dialog_->oked_);
- EXPECT_FALSE(test_dialog_->canceled_);
- EXPECT_TRUE(test_dialog_->last_pressed_button_ ==
- test_dialog_->button2_);
- break;
- }
- test_dialog_->ResetStates();
- }
-
- FocusManager* focus_manager_;
- TestDialog* test_dialog_;
- DialogClientView* client_view_;
- NativeTextButton* ok_button_;
- NativeTextButton* cancel_button_;
-};
-
-TEST_F(DefaultButtonTest, DialogDefaultButtonTest) {
- // Window has just been shown, we expect the default button specified in the
- // DialogDelegate.
- EXPECT_TRUE(ok_button_->is_default());
-
- // Simulate pressing enter, that should trigger the OK button.
- SimulatePressingEnterAndCheckDefaultButton(OK);
-
- // Simulate focusing another button, it should become the default button.
- client_view_->OnWillChangeFocus(ok_button_, test_dialog_->button1_);
- EXPECT_FALSE(ok_button_->is_default());
- EXPECT_TRUE(test_dialog_->button1_->is_default());
- // Simulate pressing enter, that should trigger button1.
- SimulatePressingEnterAndCheckDefaultButton(BUTTON1);
-
- // Now select something that is not a button, the OK should become the default
- // button again.
- client_view_->OnWillChangeFocus(test_dialog_->button1_,
- test_dialog_->checkbox_);
- EXPECT_TRUE(ok_button_->is_default());
- EXPECT_FALSE(test_dialog_->button1_->is_default());
- SimulatePressingEnterAndCheckDefaultButton(OK);
-
- // Select yet another button.
- client_view_->OnWillChangeFocus(test_dialog_->checkbox_,
- test_dialog_->button2_);
- EXPECT_FALSE(ok_button_->is_default());
- EXPECT_FALSE(test_dialog_->button1_->is_default());
- EXPECT_TRUE(test_dialog_->button2_->is_default());
- SimulatePressingEnterAndCheckDefaultButton(BUTTON2);
-
- // Focus nothing.
- client_view_->OnWillChangeFocus(test_dialog_->button2_, NULL);
- EXPECT_TRUE(ok_button_->is_default());
- EXPECT_FALSE(test_dialog_->button1_->is_default());
- EXPECT_FALSE(test_dialog_->button2_->is_default());
- SimulatePressingEnterAndCheckDefaultButton(OK);
-
- // Focus the cancel button.
- client_view_->OnWillChangeFocus(NULL, cancel_button_);
- EXPECT_FALSE(ok_button_->is_default());
- EXPECT_TRUE(cancel_button_->is_default());
- EXPECT_FALSE(test_dialog_->button1_->is_default());
- EXPECT_FALSE(test_dialog_->button2_->is_default());
- SimulatePressingEnterAndCheckDefaultButton(CANCEL);
-}
-
-class ButtonDropDownTest : public ViewTest {
- public:
- ButtonDropDownTest()
- : test_dialog_(NULL),
- button_as_view_(NULL) {
- }
-
- virtual void SetUp() OVERRIDE {
- ViewTest::SetUp();
- test_dialog_ = new TestDialog(&mock_menu_model_);
- Widget* window =
- Widget::CreateWindowWithBounds(test_dialog_, gfx::Rect(0, 0, 100, 100));
- test_dialog_->widget_ = window;
- window->Show();
- test_dialog_->button_drop_->SetBounds(0, 0, 100, 100);
- // We have to cast the button back into a View in order to invoke it's
- // OnMouseReleased method.
- button_as_view_ = static_cast<View*>(test_dialog_->button_drop_);
- }
-
- virtual void TearDown() OVERRIDE {
- test_dialog_->TearDown();
- ViewTest::TearDown();
- }
-
- TestDialog* test_dialog_;
- MockMenuModel mock_menu_model_;
- // This is owned by test_dialog_.
- View* button_as_view_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ButtonDropDownTest);
-};
-
-// Ensure that regular clicks on the drop down button still work. (i.e. - the
-// click events are processed and the listener gets the click)
-TEST_F(ButtonDropDownTest, RegularClickTest) {
- MouseEvent press_event(ui::ET_MOUSE_PRESSED, 1, 1, ui::EF_LEFT_BUTTON_DOWN);
- MouseEvent release_event(ui::ET_MOUSE_RELEASED, 1, 1,
- ui::EF_LEFT_BUTTON_DOWN);
- button_as_view_->OnMousePressed(press_event);
- button_as_view_->OnMouseReleased(release_event);
- EXPECT_EQ(test_dialog_->last_pressed_button_, test_dialog_->button_drop_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// View hierarchy / Visibility changes
-////////////////////////////////////////////////////////////////////////////////
-/*
-TEST_F(ViewTest, ChangeVisibility) {
-#if defined(OS_LINUX)
- // Make CRITICAL messages fatal
- // TODO(oshima): we probably should enable this for entire tests on linux.
- g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
-#endif
- scoped_ptr<Widget> window(CreateWidget());
- window->Init(NULL, gfx::Rect(0, 0, 500, 300));
- View* root_view = window->GetRootView();
- NativeTextButton* native = new NativeTextButton(NULL, ASCIIToUTF16("Native"));
-
- root_view->SetContentsView(native);
- native->SetVisible(true);
-
- root_view->RemoveChildView(native);
- native->SetVisible(false);
- // Change visibility to true with no widget.
- native->SetVisible(true);
-
- root_view->SetContentsView(native);
- native->SetVisible(true);
-}
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// Native view hierachy
-////////////////////////////////////////////////////////////////////////////////
-class TestNativeViewHierarchy : public View {
- public:
- TestNativeViewHierarchy() {
- }
-
- virtual void NativeViewHierarchyChanged(bool attached,
- gfx::NativeView native_view,
- internal::RootView* root_view) {
- NotificationInfo info;
- info.attached = attached;
- info.native_view = native_view;
- info.root_view = root_view;
- notifications_.push_back(info);
- };
- struct NotificationInfo {
- bool attached;
- gfx::NativeView native_view;
- internal::RootView* root_view;
- };
- static const size_t kTotalViews = 2;
- std::vector<NotificationInfo> notifications_;
-};
-
-class TestChangeNativeViewHierarchy {
- public:
- explicit TestChangeNativeViewHierarchy(ViewTest *view_test) {
- view_test_ = view_test;
- native_host_ = new NativeViewHost();
- host_ = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(0, 0, 500, 300);
- host_->Init(params);
- host_->GetRootView()->AddChildView(native_host_);
- for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
- windows_[i] = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
- params.parent = host_->GetNativeView();
- params.bounds = gfx::Rect(0, 0, 500, 300);
- windows_[i]->Init(params);
- root_views_[i] = windows_[i]->GetRootView();
- test_views_[i] = new TestNativeViewHierarchy;
- root_views_[i]->AddChildView(test_views_[i]);
- }
- }
-
- ~TestChangeNativeViewHierarchy() {
- for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
- windows_[i]->Close();
- }
- host_->Close();
- // Will close and self-delete widgets - no need to manually delete them.
- view_test_->RunPendingMessages();
- }
-
- void CheckEnumeratingNativeWidgets() {
- if (!host_->GetTopLevelWidget())
- return;
- Widget::Widgets widgets;
- Widget::GetAllChildWidgets(host_->GetNativeView(), &widgets);
- EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1, widgets.size());
- // Unfortunately there is no guarantee the sequence of views here so always
- // go through all of them.
- for (Widget::Widgets::iterator i = widgets.begin();
- i != widgets.end(); ++i) {
- View* root_view = (*i)->GetRootView();
- if (host_->GetRootView() == root_view)
- continue;
- size_t j;
- for (j = 0; j < TestNativeViewHierarchy::kTotalViews; ++j)
- if (root_views_[j] == root_view)
- break;
- // EXPECT_LT/GT/GE() fails to compile with class-defined constants
- // with gcc, with error
- // "error: undefined reference to 'TestNativeViewHierarchy::kTotalViews'"
- // so I forced to use EXPECT_TRUE() instead.
- EXPECT_TRUE(TestNativeViewHierarchy::kTotalViews > j);
- }
- }
-
- void CheckChangingHierarhy() {
- size_t i;
- for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
- // TODO(georgey): use actual hierarchy changes to send notifications.
- static_cast<internal::RootView*>(root_views_[i])->
- NotifyNativeViewHierarchyChanged(false, host_->GetNativeView());
- static_cast<internal::RootView*>(root_views_[i])->
- NotifyNativeViewHierarchyChanged(true, host_->GetNativeView());
- }
- for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) {
- ASSERT_EQ(static_cast<size_t>(2), test_views_[i]->notifications_.size());
- EXPECT_FALSE(test_views_[i]->notifications_[0].attached);
- EXPECT_EQ(host_->GetNativeView(),
- test_views_[i]->notifications_[0].native_view);
- EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[0].root_view);
- EXPECT_TRUE(test_views_[i]->notifications_[1].attached);
- EXPECT_EQ(host_->GetNativeView(),
- test_views_[i]->notifications_[1].native_view);
- EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[1].root_view);
- }
- }
-
- NativeViewHost* native_host_;
- Widget* host_;
- Widget* windows_[TestNativeViewHierarchy::kTotalViews];
- View* root_views_[TestNativeViewHierarchy::kTotalViews];
- TestNativeViewHierarchy* test_views_[TestNativeViewHierarchy::kTotalViews];
- ViewTest* view_test_;
-};
-
-TEST_F(ViewTest, ChangeNativeViewHierarchyFindRoots) {
- // TODO(georgey): Fix the test for Linux
-#if defined(OS_WIN)
- TestChangeNativeViewHierarchy test(this);
- test.CheckEnumeratingNativeWidgets();
-#endif
-}
-
-TEST_F(ViewTest, ChangeNativeViewHierarchyChangeHierarchy) {
- // TODO(georgey): Fix the test for Linux
-#if defined(OS_WIN)
- TestChangeNativeViewHierarchy test(this);
- test.CheckChangingHierarhy();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Transformations
-////////////////////////////////////////////////////////////////////////////////
-
-class TransformPaintView : public TestView {
- public:
- TransformPaintView() {}
- virtual ~TransformPaintView() {}
-
- void ClearScheduledPaintRect() {
- scheduled_paint_rect_ = gfx::Rect();
- }
-
- gfx::Rect scheduled_paint_rect() const { return scheduled_paint_rect_; }
-
- // Overridden from View:
- virtual void SchedulePaintInRect(const gfx::Rect& rect) {
- gfx::Rect xrect = ConvertRectToParent(rect);
- scheduled_paint_rect_ = scheduled_paint_rect_.Union(xrect);
- }
-
- private:
- gfx::Rect scheduled_paint_rect_;
-
- DISALLOW_COPY_AND_ASSIGN(TransformPaintView);
-};
-
-TEST_F(ViewTest, TransformPaint) {
- TransformPaintView* v1 = new TransformPaintView();
- v1->SetBounds(0, 0, 500, 300);
-
- TestView* v2 = new TestView();
- v2->SetBounds(100, 100, 200, 100);
-
- Widget* widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(50, 50, 650, 650);
- widget->Init(params);
- widget->Show();
- View* root = widget->GetRootView();
-
- root->AddChildView(v1);
- v1->AddChildView(v2);
-
- // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
- v1->ClearScheduledPaintRect();
- v2->SchedulePaint();
-
- EXPECT_EQ(gfx::Rect(100, 100, 200, 100), v1->scheduled_paint_rect());
-
- // Rotate |v1| counter-clockwise.
- ui::Transform transform;
- RotateCounterclockwise(transform);
- transform.SetTranslateY(500.0f);
- v1->SetTransform(transform);
-
- // |v2| now occupies (100, 200) to (200, 400) in |root|.
-
- v1->ClearScheduledPaintRect();
- v2->SchedulePaint();
-
- EXPECT_EQ(gfx::Rect(100, 200, 100, 200), v1->scheduled_paint_rect());
-
- widget->CloseNow();
-}
-
-TEST_F(ViewTest, TransformEvent) {
- TestView* v1 = new TestView();
- v1->SetBounds(0, 0, 500, 300);
-
- TestView* v2 = new TestView();
- v2->SetBounds(100, 100, 200, 100);
-
- Widget* widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(50, 50, 650, 650);
- widget->Init(params);
- View* root = widget->GetRootView();
-
- root->AddChildView(v1);
- v1->AddChildView(v2);
-
- // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
-
- // Rotate |v1| counter-clockwise.
- ui::Transform transform(v1->GetTransform());
- RotateCounterclockwise(transform);
- transform.SetTranslateY(500.0f);
- v1->SetTransform(transform);
-
- // |v2| now occupies (100, 200) to (200, 400) in |root|.
- v1->Reset();
- v2->Reset();
-
- MouseEvent pressed(ui::ET_MOUSE_PRESSED,
- 110, 210,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMousePressed(pressed);
- EXPECT_EQ(0, v1->last_mouse_event_type_);
- EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
- EXPECT_EQ(190, v2->location_.x());
- EXPECT_EQ(10, v2->location_.y());
-
- MouseEvent released(ui::ET_MOUSE_RELEASED, 0, 0, 0);
- root->OnMouseReleased(released);
-
- // Now rotate |v2| inside |v1| clockwise.
- transform = v2->GetTransform();
- RotateClockwise(transform);
- transform.SetTranslateX(100.0f);
- v2->SetTransform(transform);
-
- // Now, |v2| occupies (100, 100) to (200, 300) in |v1|, and (100, 300) to
- // (300, 400) in |root|.
-
- v1->Reset();
- v2->Reset();
-
- MouseEvent p2(ui::ET_MOUSE_PRESSED,
- 110, 320,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMousePressed(p2);
- EXPECT_EQ(0, v1->last_mouse_event_type_);
- EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
- EXPECT_EQ(10, v2->location_.x());
- EXPECT_EQ(20, v2->location_.y());
-
- root->OnMouseReleased(released);
-
- v1->SetTransform(ui::Transform());
- v2->SetTransform(ui::Transform());
-
- TestView* v3 = new TestView();
- v3->SetBounds(10, 10, 20, 30);
- v2->AddChildView(v3);
-
- // Rotate |v3| clockwise with respect to |v2|.
- transform = v1->GetTransform();
- RotateClockwise(transform);
- transform.SetTranslateX(30.0f);
- v3->SetTransform(transform);
-
- // Scale |v2| with respect to |v1| along both axis.
- transform = v2->GetTransform();
- transform.SetScale(0.8f, 0.5f);
- v2->SetTransform(transform);
-
- // |v3| occupies (108, 105) to (132, 115) in |root|.
-
- v1->Reset();
- v2->Reset();
- v3->Reset();
-
- MouseEvent p3(ui::ET_MOUSE_PRESSED,
- 112, 110,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMousePressed(p3);
-
- EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
- EXPECT_EQ(10, v3->location_.x());
- EXPECT_EQ(25, v3->location_.y());
-
- root->OnMouseReleased(released);
-
- v1->SetTransform(ui::Transform());
- v2->SetTransform(ui::Transform());
- v3->SetTransform(ui::Transform());
-
- v1->Reset();
- v2->Reset();
- v3->Reset();
-
- // Rotate |v3| clockwise with respect to |v2|, and scale it along both axis.
- transform = v3->GetTransform();
- RotateClockwise(transform);
- transform.SetTranslateX(30.0f);
- // Rotation sets some scaling transformation. Using SetScale would overwrite
- // that and pollute the rotation. So combine the scaling with the existing
- // transforamtion.
- transform.ConcatScale(0.8f, 0.5f);
- v3->SetTransform(transform);
-
- // Translate |v2| with respect to |v1|.
- transform = v2->GetTransform();
- transform.SetTranslate(10, 10);
- v2->SetTransform(transform);
-
- // |v3| now occupies (120, 120) to (144, 130) in |root|.
-
- MouseEvent p4(ui::ET_MOUSE_PRESSED,
- 124, 125,
- ui::EF_LEFT_BUTTON_DOWN);
- root->OnMousePressed(p4);
-
- EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
- EXPECT_EQ(10, v3->location_.x());
- EXPECT_EQ(25, v3->location_.y());
-
- root->OnMouseReleased(released);
-
- widget->CloseNow();
-}
-
-TEST_F(ViewTest, TransformVisibleBound) {
- gfx::Rect viewport_bounds(0, 0, 100, 100);
-
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = viewport_bounds;
- widget->Init(params);
- widget->GetRootView()->SetBoundsRect(viewport_bounds);
-
- View* viewport = new View;
- widget->SetContentsView(viewport);
- View* contents = new View;
- viewport->AddChildView(contents);
- viewport->SetBoundsRect(viewport_bounds);
- contents->SetBounds(0, 0, 100, 200);
-
- View* child = new View;
- contents->AddChildView(child);
- child->SetBounds(10, 90, 50, 50);
- EXPECT_EQ(gfx::Rect(0, 0, 50, 10), child->GetVisibleBounds());
-
- // Rotate |child| counter-clockwise
- ui::Transform transform;
- RotateCounterclockwise(transform);
- transform.SetTranslateY(50.0f);
- child->SetTransform(transform);
- EXPECT_EQ(gfx::Rect(40, 0, 10, 50), child->GetVisibleBounds());
-
- widget->CloseNow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OnVisibleBoundsChanged()
-
-class VisibleBoundsView : public View {
- public:
- VisibleBoundsView() : received_notification_(false) {}
- virtual ~VisibleBoundsView() {}
-
- bool received_notification() const { return received_notification_; }
- void set_received_notification(bool received) {
- received_notification_ = received;
- }
-
- private:
- // Overridden from View:
- virtual bool NeedsNotificationWhenVisibleBoundsChange() const {
- return true;
- }
- virtual void OnVisibleBoundsChanged() {
- received_notification_ = true;
- }
-
- bool received_notification_;
-
- DISALLOW_COPY_AND_ASSIGN(VisibleBoundsView);
-};
-
-TEST_F(ViewTest, OnVisibleBoundsChanged) {
- gfx::Rect viewport_bounds(0, 0, 100, 100);
-
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = viewport_bounds;
- widget->Init(params);
- widget->GetRootView()->SetBoundsRect(viewport_bounds);
-
- View* viewport = new View;
- widget->SetContentsView(viewport);
- View* contents = new View;
- viewport->AddChildView(contents);
- viewport->SetBoundsRect(viewport_bounds);
- contents->SetBounds(0, 0, 100, 200);
-
- // Create a view that cares about visible bounds notifications, and position
- // it just outside the visible bounds of the viewport.
- VisibleBoundsView* child = new VisibleBoundsView;
- contents->AddChildView(child);
- child->SetBounds(10, 110, 50, 50);
-
- // The child bound should be fully clipped.
- EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
-
- // Now scroll the contents, but not enough to make the child visible.
- contents->SetY(contents->y() - 1);
-
- // We should have received the notification since the visible bounds may have
- // changed (even though they didn't).
- EXPECT_TRUE(child->received_notification());
- EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
- child->set_received_notification(false);
-
- // Now scroll the contents, this time by enough to make the child visible by
- // one pixel.
- contents->SetY(contents->y() - 10);
- EXPECT_TRUE(child->received_notification());
- EXPECT_EQ(1, child->GetVisibleBounds().height());
- child->set_received_notification(false);
-
- widget->CloseNow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BoundsChanged()
-
-TEST_F(ViewTest, SetBoundsPaint) {
- TestView top_view;
- TestView* child_view = new TestView;
-
- top_view.SetBounds(0, 0, 100, 100);
- top_view.scheduled_paint_rects_.clear();
- child_view->SetBounds(10, 10, 20, 20);
- top_view.AddChildView(child_view);
-
- top_view.scheduled_paint_rects_.clear();
- child_view->SetBounds(30, 30, 20, 20);
- EXPECT_EQ(2U, top_view.scheduled_paint_rects_.size());
-
- // There should be 2 rects, spanning from (10, 10) to (50, 50).
- gfx::Rect paint_rect =
- top_view.scheduled_paint_rects_[0].Union(
- top_view.scheduled_paint_rects_[1]);
- EXPECT_EQ(gfx::Rect(10, 10, 40, 40), paint_rect);
-}
-
-// Tests conversion methods with a transform.
-TEST_F(ViewTest, ConvertPointToViewWithTransform) {
- TestView top_view;
- TestView* child = new TestView;
- TestView* child_child = new TestView;
-
- top_view.AddChildView(child);
- child->AddChildView(child_child);
-
- top_view.SetBounds(0, 0, 1000, 1000);
-
- child->SetBounds(7, 19, 500, 500);
- ui::Transform transform;
- transform.SetScale(3.0f, 4.0f);
- child->SetTransform(transform);
-
- child_child->SetBounds(17, 13, 100, 100);
- transform = ui::Transform();
- transform.SetScale(5.0f, 7.0f);
- child_child->SetTransform(transform);
-
- // Sanity check to make sure basic transforms act as expected.
- {
- ui::Transform transform;
- transform.ConcatTranslate(1, 1);
- transform.ConcatScale(100, 55);
- transform.ConcatTranslate(110, -110);
-
- // convert to a 3x3 matrix.
- const SkMatrix& matrix = transform.matrix();
-
- EXPECT_EQ(210, matrix.getTranslateX());
- EXPECT_EQ(-55, matrix.getTranslateY());
- EXPECT_EQ(100, matrix.getScaleX());
- EXPECT_EQ(55, matrix.getScaleY());
- EXPECT_EQ(0, matrix.getSkewX());
- EXPECT_EQ(0, matrix.getSkewY());
- }
-
- {
- ui::Transform transform;
- transform.SetTranslate(1, 1);
- ui::Transform t2;
- t2.SetScale(100, 55);
- ui::Transform t3;
- t3.SetTranslate(110, -110);
- transform.ConcatTransform(t2);
- transform.ConcatTransform(t3);
-
- // convert to a 3x3 matrix
- const SkMatrix& matrix = transform.matrix();
-
- EXPECT_EQ(210, matrix.getTranslateX());
- EXPECT_EQ(-55, matrix.getTranslateY());
- EXPECT_EQ(100, matrix.getScaleX());
- EXPECT_EQ(55, matrix.getScaleY());
- EXPECT_EQ(0, matrix.getSkewX());
- EXPECT_EQ(0, matrix.getSkewY());
- }
-
- // Conversions from child->top and top->child.
- {
- gfx::Point point(5, 5);
- View::ConvertPointToView(child, &top_view, &point);
- EXPECT_EQ(22, point.x());
- EXPECT_EQ(39, point.y());
-
- point.SetPoint(22, 39);
- View::ConvertPointToView(&top_view, child, &point);
- EXPECT_EQ(5, point.x());
- EXPECT_EQ(5, point.y());
- }
-
- // Conversions from child_child->top and top->child_child.
- {
- gfx::Point point(5, 5);
- View::ConvertPointToView(child_child, &top_view, &point);
- EXPECT_EQ(133, point.x());
- EXPECT_EQ(211, point.y());
-
- point.SetPoint(133, 211);
- View::ConvertPointToView(&top_view, child_child, &point);
- EXPECT_EQ(5, point.x());
- EXPECT_EQ(5, point.y());
- }
-
- // Conversions from child_child->child and child->child_child
- {
- gfx::Point point(5, 5);
- View::ConvertPointToView(child_child, child, &point);
- EXPECT_EQ(42, point.x());
- EXPECT_EQ(48, point.y());
-
- point.SetPoint(42, 48);
- View::ConvertPointToView(child, child_child, &point);
- EXPECT_EQ(5, point.x());
- EXPECT_EQ(5, point.y());
- }
-
- // Conversions from top_view to child with a value that should be negative.
- // This ensures we don't round up with negative numbers.
- {
- gfx::Point point(6, 18);
- View::ConvertPointToView(&top_view, child, &point);
- EXPECT_EQ(-1, point.x());
- EXPECT_EQ(-1, point.y());
- }
-}
-
-// Tests conversion methods for rectangles.
-TEST_F(ViewTest, ConvertRectWithTransform) {
- scoped_ptr<Widget> widget(new Widget);
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.bounds = gfx::Rect(50, 50, 650, 650);
- widget->Init(params);
- View* root = widget->GetRootView();
-
- TestView* v1 = new TestView;
- TestView* v2 = new TestView;
- root->AddChildView(v1);
- v1->AddChildView(v2);
-
- v1->SetBounds(10, 10, 500, 500);
- v2->SetBounds(20, 20, 100, 200);
-
- // |v2| now occupies (30, 30) to (130, 230) in |widget|
- gfx::Rect rect(5, 5, 15, 40);
- EXPECT_EQ(gfx::Rect(25, 25, 15, 40), v2->ConvertRectToParent(rect));
- EXPECT_EQ(gfx::Rect(35, 35, 15, 40), v2->ConvertRectToWidget(rect));
-
- // Rotate |v2|
- ui::Transform t2;
- RotateCounterclockwise(t2);
- t2.SetTranslateY(100.0f);
- v2->SetTransform(t2);
-
- // |v2| now occupies (30, 30) to (230, 130) in |widget|
- EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
- EXPECT_EQ(gfx::Rect(35, 110, 40, 15), v2->ConvertRectToWidget(rect));
-
- // Scale down |v1|
- ui::Transform t1;
- t1.SetScale(0.5, 0.5);
- v1->SetTransform(t1);
-
- // The rectangle should remain the same for |v1|.
- EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
-
- // |v2| now occupies (20, 20) to (120, 70) in |widget|
- // There are some rounding of floating values here. These values may change if
- // floating operations are improved/changed.
- EXPECT_EQ(gfx::Rect(22, 60, 20, 7), v2->ConvertRectToWidget(rect));
-
- widget->CloseNow();
-}
-
-class ObserverView : public View {
- public:
- ObserverView();
- virtual ~ObserverView();
-
- void ResetTestState();
-
- bool child_added() const { return child_added_; }
- bool child_removed() const { return child_removed_; }
- const View* parent_view() const { return parent_view_; }
- const View* child_view() const { return child_view_; }
-
- private:
- // View:
- virtual void ViewHierarchyChanged(bool is_add,
- View* parent,
- View* child) OVERRIDE;
-
- bool child_added_;
- bool child_removed_;
- View* parent_view_;
- View* child_view_;
-
- DISALLOW_COPY_AND_ASSIGN(ObserverView);
-};
-
-ObserverView::ObserverView()
- : child_added_(false),
- child_removed_(false),
- parent_view_(NULL),
- child_view_(NULL) {
-}
-
-ObserverView::~ObserverView() {}
-
-void ObserverView::ResetTestState() {
- child_added_ = false;
- child_removed_ = false;
- parent_view_ = NULL;
- child_view_ = NULL;
-}
-
-void ObserverView::ViewHierarchyChanged(bool is_add,
- View* parent,
- View* child) {
- if (is_add)
- child_added_ = true;
- else
- child_removed_ = true;
-
- parent_view_ = parent;
- child_view_ = child;
-}
-
-// Verifies that the ViewHierarchyChanged() notification is sent correctly when
-// a child view is added or removed to all the views in the hierarchy (up and
-// down).
-// The tree looks like this:
-// v1
-// +-- v2
-// +-- v3
-TEST_F(ViewTest, ViewHierarchyChanged) {
- ObserverView v1;
-
- ObserverView* v3 = new ObserverView();
-
- // Add |v3| to |v2|.
- scoped_ptr<ObserverView> v2(new ObserverView());
- v2->AddChildView(v3);
-
- // Make sure both |v2| and |v3| receive the ViewHierarchyChanged()
- // notification.
- EXPECT_TRUE(v2->child_added());
- EXPECT_FALSE(v2->child_removed());
- EXPECT_EQ(v2.get(), v2->parent_view());
- EXPECT_EQ(v3, v2->child_view());
-
- EXPECT_TRUE(v3->child_added());
- EXPECT_FALSE(v3->child_removed());
- EXPECT_EQ(v2.get(), v3->parent_view());
- EXPECT_EQ(v3, v3->child_view());
-
- // Reset everything to the initial state.
- v2->ResetTestState();
- v3->ResetTestState();
-
- // Add |v2| to v1.
- v1.AddChildView(v2.get());
-
- // Verifies that |v2| is the child view *added* and the parent view is |v1|.
- // Make sure all the views (v1, v2, v3) received _that_ information.
- EXPECT_TRUE(v1.child_added());
- EXPECT_FALSE(v1.child_removed());
- EXPECT_EQ(&v1, v1.parent_view());
- EXPECT_EQ(v2.get(), v1.child_view());
-
- EXPECT_TRUE(v2->child_added());
- EXPECT_FALSE(v2->child_removed());
- EXPECT_EQ(&v1, v2->parent_view());
- EXPECT_EQ(v2.get(), v2->child_view());
-
- EXPECT_TRUE(v3->child_added());
- EXPECT_FALSE(v3->child_removed());
- EXPECT_EQ(&v1, v3->parent_view());
- EXPECT_EQ(v2.get(), v3->child_view());
-
- // Reset everything to the initial state.
- v1.ResetTestState();
- v2->ResetTestState();
- v3->ResetTestState();
-
- // Remove |v2| from |v1|.
- v1.RemoveChildView(v2.get());
-
- // Verifies that |v2| is the child view *removed* and the parent view is |v1|.
- // Make sure all the views (v1, v2, v3) received _that_ information.
- EXPECT_FALSE(v1.child_added());
- EXPECT_TRUE(v1.child_removed());
- EXPECT_EQ(&v1, v1.parent_view());
- EXPECT_EQ(v2.get(), v1.child_view());
-
- EXPECT_FALSE(v2->child_added());
- EXPECT_TRUE(v2->child_removed());
- EXPECT_EQ(&v1, v2->parent_view());
- EXPECT_EQ(v2.get(), v2->child_view());
-
- EXPECT_FALSE(v3->child_added());
- EXPECT_TRUE(v3->child_removed());
- EXPECT_EQ(&v1, v3->parent_view());
- EXPECT_EQ(v3, v3->child_view());
-}
-
-// Verifies if the child views added under the root are all deleted when calling
-// RemoveAllChildViews.
-// The tree looks like this:
-// root
-// +-- child1
-// +-- foo
-// +-- bar0
-// +-- bar1
-// +-- bar2
-// +-- child2
-// +-- child3
-TEST_F(ViewTest, RemoveAllChildViews) {
- View root;
-
- View* child1 = new View;
- root.AddChildView(child1);
-
- for (int i = 0; i < 2; ++i)
- root.AddChildView(new View);
-
- View* foo = new View;
- child1->AddChildView(foo);
-
- // Add some nodes to |foo|.
- for (int i = 0; i < 3; ++i)
- foo->AddChildView(new View);
-
- EXPECT_EQ(3, root.child_count());
- EXPECT_EQ(1, child1->child_count());
- EXPECT_EQ(3, foo->child_count());
-
- // Now remove all child views from root.
- root.RemoveAllChildViews(true);
-
- EXPECT_EQ(0, root.child_count());
- EXPECT_FALSE(root.has_children());
-}
-
-TEST_F(ViewTest, Contains) {
- View v1;
- View* v2 = new View;
- View* v3 = new View;
-
- v1.AddChildView(v2);
- v2->AddChildView(v3);
-
- EXPECT_FALSE(v1.Contains(NULL));
- EXPECT_TRUE(v1.Contains(&v1));
- EXPECT_TRUE(v1.Contains(v2));
- EXPECT_TRUE(v1.Contains(v3));
-
- EXPECT_FALSE(v2->Contains(NULL));
- EXPECT_TRUE(v2->Contains(v2));
- EXPECT_FALSE(v2->Contains(&v1));
- EXPECT_TRUE(v2->Contains(v3));
-
- EXPECT_FALSE(v3->Contains(NULL));
- EXPECT_TRUE(v3->Contains(v3));
- EXPECT_FALSE(v3->Contains(&v1));
- EXPECT_FALSE(v3->Contains(v2));
-}
-
-// Verifies if GetIndexOf() returns the correct index for the specified child
-// view.
-// The tree looks like this:
-// root
-// +-- child1
-// +-- foo1
-// +-- child2
-TEST_F(ViewTest, GetIndexOf) {
- View root;
-
- View* child1 = new View;
- root.AddChildView(child1);
-
- View* child2 = new View;
- root.AddChildView(child2);
-
- View* foo1 = new View;
- child1->AddChildView(foo1);
-
- EXPECT_EQ(-1, root.GetIndexOf(NULL));
- EXPECT_EQ(-1, root.GetIndexOf(&root));
- EXPECT_EQ(0, root.GetIndexOf(child1));
- EXPECT_EQ(1, root.GetIndexOf(child2));
- EXPECT_EQ(-1, root.GetIndexOf(foo1));
-
- EXPECT_EQ(-1, child1->GetIndexOf(NULL));
- EXPECT_EQ(-1, child1->GetIndexOf(&root));
- EXPECT_EQ(-1, child1->GetIndexOf(child1));
- EXPECT_EQ(-1, child1->GetIndexOf(child2));
- EXPECT_EQ(0, child1->GetIndexOf(foo1));
-
- EXPECT_EQ(-1, child2->GetIndexOf(NULL));
- EXPECT_EQ(-1, child2->GetIndexOf(&root));
- EXPECT_EQ(-1, child2->GetIndexOf(child2));
- EXPECT_EQ(-1, child2->GetIndexOf(child1));
- EXPECT_EQ(-1, child2->GetIndexOf(foo1));
-}
-
-// Verifies that the child views can be reordered correctly.
-TEST_F(ViewTest, ReorderChildren) {
- View root;
-
- View* child = new View();
- root.AddChildView(child);
-
- View* foo1 = new View();
- child->AddChildView(foo1);
- View* foo2 = new View();
- child->AddChildView(foo2);
- View* foo3 = new View();
- child->AddChildView(foo3);
- foo1->set_focusable(true);
- foo2->set_focusable(true);
- foo3->set_focusable(true);
-
- ASSERT_EQ(0, child->GetIndexOf(foo1));
- ASSERT_EQ(1, child->GetIndexOf(foo2));
- ASSERT_EQ(2, child->GetIndexOf(foo3));
- ASSERT_EQ(foo2, foo1->GetNextFocusableView());
- ASSERT_EQ(foo3, foo2->GetNextFocusableView());
- ASSERT_EQ(NULL, foo3->GetNextFocusableView());
-
- // Move |foo2| at the end.
- child->ReorderChildView(foo2, -1);
- ASSERT_EQ(0, child->GetIndexOf(foo1));
- ASSERT_EQ(1, child->GetIndexOf(foo3));
- ASSERT_EQ(2, child->GetIndexOf(foo2));
- ASSERT_EQ(foo3, foo1->GetNextFocusableView());
- ASSERT_EQ(foo2, foo3->GetNextFocusableView());
- ASSERT_EQ(NULL, foo2->GetNextFocusableView());
-
- // Move |foo1| at the end.
- child->ReorderChildView(foo1, -1);
- ASSERT_EQ(0, child->GetIndexOf(foo3));
- ASSERT_EQ(1, child->GetIndexOf(foo2));
- ASSERT_EQ(2, child->GetIndexOf(foo1));
- ASSERT_EQ(NULL, foo1->GetNextFocusableView());
- ASSERT_EQ(foo2, foo1->GetPreviousFocusableView());
- ASSERT_EQ(foo2, foo3->GetNextFocusableView());
- ASSERT_EQ(foo1, foo2->GetNextFocusableView());
-
- // Move |foo2| to the front.
- child->ReorderChildView(foo2, 0);
- ASSERT_EQ(0, child->GetIndexOf(foo2));
- ASSERT_EQ(1, child->GetIndexOf(foo3));
- ASSERT_EQ(2, child->GetIndexOf(foo1));
- ASSERT_EQ(NULL, foo1->GetNextFocusableView());
- ASSERT_EQ(foo3, foo1->GetPreviousFocusableView());
- ASSERT_EQ(foo3, foo2->GetNextFocusableView());
- ASSERT_EQ(foo1, foo3->GetNextFocusableView());
-}
-
-// Verifies that GetViewByID returns the correctly child view from the specified
-// ID.
-// The tree looks like this:
-// v1
-// +-- v2
-// +-- v3
-// +-- v4
-TEST_F(ViewTest, GetViewByID) {
- View v1;
- const int kV1ID = 1;
- v1.set_id(kV1ID);
-
- View v2;
- const int kV2ID = 2;
- v2.set_id(kV2ID);
-
- View v3;
- const int kV3ID = 3;
- v3.set_id(kV3ID);
-
- View v4;
- const int kV4ID = 4;
- v4.set_id(kV4ID);
-
- const int kV5ID = 5;
-
- v1.AddChildView(&v2);
- v2.AddChildView(&v3);
- v2.AddChildView(&v4);
-
- EXPECT_EQ(&v1, v1.GetViewByID(kV1ID));
- EXPECT_EQ(&v2, v1.GetViewByID(kV2ID));
- EXPECT_EQ(&v4, v1.GetViewByID(kV4ID));
-
- EXPECT_EQ(NULL, v1.GetViewByID(kV5ID)); // No V5 exists.
- EXPECT_EQ(NULL, v2.GetViewByID(kV1ID)); // It can get only from child views.
-
- const int kGroup = 1;
- v3.SetGroup(kGroup);
- v4.SetGroup(kGroup);
-
- View::Views views;
- v1.GetViewsInGroup(kGroup, &views);
- EXPECT_EQ(2U, views.size());
-
- View::Views::const_iterator i(std::find(views.begin(), views.end(), &v3));
- EXPECT_NE(views.end(), i);
-
- i = std::find(views.begin(), views.end(), &v4);
- EXPECT_NE(views.end(), i);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Layers
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(VIEWS_COMPOSITOR)
-
-namespace {
-
-// Test implementation of LayerAnimator.
-class TestLayerAnimator : public ui::LayerAnimator {
- public:
- TestLayerAnimator();
-
- const gfx::Rect& last_bounds() const { return last_bounds_; }
-
- // LayerAnimator.
- virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
-
- private:
- gfx::Rect last_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(TestLayerAnimator);
-};
-
-TestLayerAnimator::TestLayerAnimator()
- : ui::LayerAnimator(base::TimeDelta::FromMilliseconds(0)) {
-}
-
-void TestLayerAnimator::SetBounds(const gfx::Rect& bounds) {
- last_bounds_ = bounds;
-}
-
-} // namespace
-
-class ViewLayerTest : public ViewsTestBase {
- public:
- ViewLayerTest() : widget_(NULL), old_use_acceleration_(false) {}
-
- virtual ~ViewLayerTest() {
- }
-
- // Returns the Layer used by the RootView.
- ui::Layer* GetRootLayer() {
-#if defined(USE_AURA)
- ui::Layer* root_layer = NULL;
- gfx::Point origin;
- widget()->CalculateOffsetToAncestorWithLayer(&origin, &root_layer);
- return root_layer;
-#else
- return widget()->GetRootView()->layer();
-#endif
- }
-
- virtual void SetUp() OVERRIDE {
- ViewTest::SetUp();
- old_use_acceleration_ = View::get_use_acceleration_when_possible();
- View::set_use_acceleration_when_possible(true);
-
- ui::TestTexture::reset_live_count();
-
- widget_ = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(50, 50, 200, 200);
- widget_->Init(params);
- widget_->Show();
- widget_->GetRootView()->SetBounds(0, 0, 200, 200);
- }
-
- virtual void TearDown() OVERRIDE {
- View::set_use_acceleration_when_possible(old_use_acceleration_);
- widget_->CloseNow();
- Widget::SetPureViews(false);
- ViewsTestBase::TearDown();
- }
-
- Widget* widget() { return widget_; }
-
- private:
- Widget* widget_;
- bool old_use_acceleration_;
-};
-
-#if !defined(USE_AURA)
-// This test assumes a particular layer hierarchy that isn't valid for aura.
-// Ensures the RootView has a layer and its set up correctly.
-TEST_F(ViewLayerTest, RootState) {
- ui::Layer* layer = widget()->GetRootView()->layer();
- ASSERT_TRUE(layer);
- EXPECT_FALSE(layer->parent());
- EXPECT_EQ(0u, layer->children().size());
- EXPECT_FALSE(layer->transform().HasChange());
- EXPECT_EQ(widget()->GetRootView()->bounds(), layer->bounds());
- EXPECT_TRUE(layer->GetCompositor() != NULL);
-}
-
-// Verifies that the complete bounds of a texture are updated if the texture
-// needs to be refreshed and paint with a clip is invoked.
-// This test invokes OnNativeWidgetPaintAccelerated, which is not used by aura.
-TEST_F(ViewLayerTest, PaintAll) {
- View* view = widget()->GetRootView();
- ui::Layer* layer = GetRootLayer();
- view->SetBounds(0, 0, 200, 200);
- widget()->OnNativeWidgetPaintAccelerated(gfx::Rect(0, 0, 1, 1));
- ASSERT_TRUE(layer != NULL);
- const ui::TestTexture* texture =
- static_cast<const ui::TestTexture*>(layer->texture());
- ASSERT_TRUE(texture != NULL);
- EXPECT_EQ(view->GetLocalBounds(), texture->bounds_of_last_paint());
-}
-#endif
-
-TEST_F(ViewLayerTest, LayerToggling) {
- // Because we lazily create textures the calls to DrawTree are necessary to
- // ensure we trigger creation of textures.
-#if defined(USE_AURA)
- ui::Layer* root_layer = NULL;
- gfx::Point origin;
- widget()->CalculateOffsetToAncestorWithLayer(&origin, &root_layer);
-#else
- ui::Layer* root_layer = widget()->GetRootView()->layer();
-#endif
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
-#if !defined(USE_WEBKIT_COMPOSITOR)
- // TODO(piman): with the webkit compositor, we don't create Textures on
- // Layers. We're not supposed to be calling Layer::DrawTree. This test needs
- // refactoring to fully work in that case.
- root_layer->DrawTree();
- ui::TestTexture::reset_live_count();
-#endif
-
- // Create v1, give it a bounds and verify everything is set up correctly.
- View* v1 = new View;
- v1->SetPaintToLayer(true);
-#if !defined(USE_WEBKIT_COMPOSITOR)
- root_layer->DrawTree();
- EXPECT_EQ(0, ui::TestTexture::live_count());
-#endif
- EXPECT_TRUE(v1->layer() != NULL);
- v1->SetBounds(20, 30, 140, 150);
- content_view->AddChildView(v1);
-#if !defined(USE_WEBKIT_COMPOSITOR)
- root_layer->DrawTree();
- EXPECT_EQ(1, ui::TestTexture::live_count());
-#endif
- ASSERT_TRUE(v1->layer() != NULL);
- EXPECT_EQ(root_layer, v1->layer()->parent());
- EXPECT_EQ(gfx::Rect(20, 30, 140, 150), v1->layer()->bounds());
-
- // Create v2 as a child of v1 and do basic assertion testing.
- View* v2 = new View;
- v1->AddChildView(v2);
- EXPECT_TRUE(v2->layer() == NULL);
- v2->SetBounds(10, 20, 30, 40);
- v2->SetPaintToLayer(true);
-#if !defined(USE_WEBKIT_COMPOSITOR)
- root_layer->DrawTree();
- EXPECT_EQ(2, ui::TestTexture::live_count());
-#endif
- ASSERT_TRUE(v2->layer() != NULL);
- EXPECT_EQ(v1->layer(), v2->layer()->parent());
- EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
-
- // Turn off v1s layer. v2 should still have a layer but its parent should have
- // changed.
- v1->SetPaintToLayer(false);
-#if !defined(USE_WEBKIT_COMPOSITOR)
- root_layer->DrawTree();
- EXPECT_EQ(1, ui::TestTexture::live_count());
-#endif
- EXPECT_TRUE(v1->layer() == NULL);
- EXPECT_TRUE(v2->layer() != NULL);
- EXPECT_EQ(root_layer, v2->layer()->parent());
- ASSERT_EQ(1u, root_layer->children().size());
- EXPECT_EQ(root_layer->children()[0], v2->layer());
- // The bounds of the layer should have changed to be relative to the root view
- // now.
- EXPECT_EQ(gfx::Rect(30, 50, 30, 40), v2->layer()->bounds());
-
- // Make v1 have a layer again and verify v2s layer is wired up correctly.
- ui::Transform transform;
- transform.SetScale(2.0f, 2.0f);
- v1->SetTransform(transform);
-#if !defined(USE_WEBKIT_COMPOSITOR)
- root_layer->DrawTree();
- EXPECT_EQ(2, ui::TestTexture::live_count());
-#endif
- EXPECT_TRUE(v1->layer() != NULL);
- EXPECT_TRUE(v2->layer() != NULL);
- EXPECT_EQ(root_layer, v1->layer()->parent());
- EXPECT_EQ(v1->layer(), v2->layer()->parent());
- ASSERT_EQ(1u, root_layer->children().size());
- EXPECT_EQ(root_layer->children()[0], v1->layer());
- ASSERT_EQ(1u, v1->layer()->children().size());
- EXPECT_EQ(v1->layer()->children()[0], v2->layer());
- EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
-}
-
-// Verifies turning on a layer wires up children correctly.
-TEST_F(ViewLayerTest, NestedLayerToggling) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- // Create v1, give it a bounds and verify everything is set up correctly.
- View* v1 = new View;
- content_view->AddChildView(v1);
- v1->SetBounds(20, 30, 140, 150);
-
- View* v2 = new View;
- v1->AddChildView(v2);
-
- View* v3 = new View;
- v3->SetPaintToLayer(true);
- v2->AddChildView(v3);
- ASSERT_TRUE(v3->layer() != NULL);
-
- // At this point we have v1-v2-v3. v3 has a layer, v1 and v2 don't.
-
- v1->SetPaintToLayer(true);
- EXPECT_EQ(v1->layer(), v3->layer()->parent());
-}
-
-TEST_F(ViewLayerTest, LayerAnimator) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* v1 = new View;
- content_view->AddChildView(v1);
- v1->SetPaintToLayer(true);
- EXPECT_TRUE(v1->layer() != NULL);
-
- TestLayerAnimator* animator = new TestLayerAnimator();
- v1->layer()->SetAnimator(animator);
-
- gfx::Rect bounds(1, 2, 3, 4);
- v1->SetBoundsRect(bounds);
- EXPECT_EQ(bounds, animator->last_bounds());
- // TestLayerAnimator doesn't update the layer.
- EXPECT_NE(bounds, v1->layer()->bounds());
-}
-
-// Verifies the bounds of a layer are updated if the bounds of ancestor that
-// doesn't have a layer change.
-TEST_F(ViewLayerTest, BoundsChangeWithLayer) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* v1 = new View;
- content_view->AddChildView(v1);
- v1->SetBounds(20, 30, 140, 150);
-
- View* v2 = new View;
- v2->SetBounds(10, 11, 40, 50);
- v1->AddChildView(v2);
- v2->SetPaintToLayer(true);
- ASSERT_TRUE(v2->layer() != NULL);
- EXPECT_EQ(gfx::Rect(30, 41, 40, 50), v2->layer()->bounds());
-
- v1->SetPosition(gfx::Point(25, 36));
- EXPECT_EQ(gfx::Rect(35, 47, 40, 50), v2->layer()->bounds());
-
- v2->SetPosition(gfx::Point(11, 12));
- EXPECT_EQ(gfx::Rect(36, 48, 40, 50), v2->layer()->bounds());
-
- // Bounds of the layer should change even if the view is not invisible.
- v1->SetVisible(false);
- v1->SetPosition(gfx::Point(20, 30));
- EXPECT_EQ(gfx::Rect(31, 42, 40, 50), v2->layer()->bounds());
-
- v2->SetVisible(false);
- v2->SetBounds(10, 11, 20, 30);
- EXPECT_EQ(gfx::Rect(30, 41, 20, 30), v2->layer()->bounds());
-}
-
-// Makes sure a transform persists after toggling the visibility.
-TEST_F(ViewLayerTest, ToggleVisibilityWithTransform) {
- View* view = new View;
- ui::Transform transform;
- transform.SetScale(2.0f, 2.0f);
- view->SetTransform(transform);
- widget()->SetContentsView(view);
- EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
-
- view->SetVisible(false);
- EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
-
- view->SetVisible(true);
- EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
-}
-
-// Verifies a transform persists after removing/adding a view with a transform.
-TEST_F(ViewLayerTest, ResetTransformOnLayerAfterAdd) {
- View* view = new View;
- ui::Transform transform;
- transform.SetScale(2.0f, 2.0f);
- view->SetTransform(transform);
- widget()->SetContentsView(view);
- EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
- ASSERT_TRUE(view->layer() != NULL);
- EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
-
- View* parent = view->parent();
- parent->RemoveChildView(view);
- parent->AddChildView(view);
-
- EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
- ASSERT_TRUE(view->layer() != NULL);
- EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
-}
-
-// Makes sure that layer visibility is correct after toggling View visibility.
-TEST_F(ViewLayerTest, ToggleVisibilityWithLayer) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- // The view isn't attached to a widget or a parent view yet. But it should
- // still have a layer, but the layer should not be attached to the root
- // layer.
- View* v1 = new View;
- v1->SetPaintToLayer(true);
- EXPECT_TRUE(v1->layer());
- EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
- v1->layer()));
-
- // Once the view is attached to a widget, its layer should be attached to the
- // root layer and visible.
- content_view->AddChildView(v1);
- EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
- v1->layer()));
- EXPECT_TRUE(v1->layer()->IsDrawn());
-
- v1->SetVisible(false);
- EXPECT_FALSE(v1->layer()->IsDrawn());
-
- v1->SetVisible(true);
- EXPECT_TRUE(v1->layer()->IsDrawn());
-
- widget()->Hide();
- EXPECT_FALSE(v1->layer()->IsDrawn());
-
- widget()->Show();
- EXPECT_TRUE(v1->layer()->IsDrawn());
-}
-
-// Test that a hole in a layer is correctly created regardless of whether
-// the opacity attribute is set before or after the layer is created.
-TEST_F(ViewLayerTest, ToggleOpacityWithLayer) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* parent_view = new View;
- content_view->AddChildView(parent_view);
- parent_view->SetPaintToLayer(true);
- parent_view->SetBounds(0, 0, 400, 400);
-
- View* child_view = new View;
- child_view->SetBounds(50, 50, 100, 100);
- parent_view->AddChildView(child_view);
-
- widget()->GetCompositor()->Draw(false);
-
- ASSERT_TRUE(child_view->layer() == NULL);
- child_view->SetPaintToLayer(true);
- child_view->SetFillsBoundsOpaquely(true);
- widget()->GetCompositor()->Draw(false);
- ASSERT_TRUE(child_view->layer());
- EXPECT_EQ(
- gfx::Rect(50, 50, 100, 100), parent_view->layer()->hole_rect());
-
- child_view->SetFillsBoundsOpaquely(false);
- widget()->GetCompositor()->Draw(false);
- EXPECT_TRUE(parent_view->layer()->hole_rect().IsEmpty());
-}
-
-// Test that a hole in a layer always corresponds to the bounds of opaque
-// layers.
-TEST_F(ViewLayerTest, MultipleOpaqueLayers) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* parent_view = new View;
- parent_view->SetPaintToLayer(true);
- parent_view->SetBounds(0, 0, 400, 400);
- content_view->AddChildView(parent_view);
-
- View* child_view1 = new View;
- child_view1->SetPaintToLayer(true);
- child_view1->SetFillsBoundsOpaquely(true);
- child_view1->SetBounds(50, 50, 100, 100);
- parent_view->AddChildView(child_view1);
-
- View* child_view2 = new View;
- child_view2->SetPaintToLayer(true);
- child_view2->SetFillsBoundsOpaquely(false);
- child_view2->SetBounds(150, 150, 200, 200);
- parent_view->AddChildView(child_view2);
-
- widget()->GetCompositor()->Draw(false);
-
- // Only child_view1 is opaque
- EXPECT_EQ(
- gfx::Rect(50, 50, 100, 100), parent_view->layer()->hole_rect());
-
- // Both child views are opaque
- child_view2->SetFillsBoundsOpaquely(true);
- widget()->GetCompositor()->Draw(false);
- EXPECT_TRUE(
- gfx::Rect(50, 50, 100, 100) == parent_view->layer()->hole_rect() ||
- gfx::Rect(150, 150, 200, 200) == parent_view->layer()->hole_rect());
-
- // Only child_view2 is opaque
- delete child_view1;
- EXPECT_EQ(
- gfx::Rect(150, 150, 200, 200), parent_view->layer()->hole_rect());
-}
-
-// Makes sure that opacity of layer persists after toggling visibilty.
-TEST_F(ViewLayerTest, ToggleVisibilityWithOpaqueLayer) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* parent_view = new View;
- parent_view->SetPaintToLayer(true);
- parent_view->SetBounds(0, 0, 400, 400);
- content_view->AddChildView(parent_view);
-
- parent_view->SetPaintToLayer(true);
- parent_view->SetBounds(0, 0, 400, 400);
-
- View* child_view = new View;
- child_view->SetBounds(50, 50, 100, 100);
- child_view->SetPaintToLayer(true);
- child_view->SetFillsBoundsOpaquely(true);
- parent_view->AddChildView(child_view);
- widget()->GetCompositor()->Draw(false);
- EXPECT_EQ(
- gfx::Rect(50, 50, 100, 100), parent_view->layer()->hole_rect());
-
- child_view->SetVisible(false);
- widget()->GetCompositor()->Draw(false);
- EXPECT_TRUE(parent_view->layer()->hole_rect().IsEmpty());
-
- child_view->SetVisible(true);
- widget()->GetCompositor()->Draw(false);
- EXPECT_EQ(
- gfx::Rect(50, 50, 100, 100), parent_view->layer()->hole_rect());
-}
-
-// Tests that the layers in the subtree are orphaned after a View is removed
-// from the parent.
-TEST_F(ViewLayerTest, OrphanLayerAfterViewRemove) {
- View* content_view = new View;
- widget()->SetContentsView(content_view);
-
- View* v1 = new View;
- content_view->AddChildView(v1);
-
- View* v2 = new View;
- v1->AddChildView(v2);
- v2->SetPaintToLayer(true);
- EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
- v2->layer()));
- EXPECT_TRUE(v2->layer()->IsDrawn());
-
- content_view->RemoveChildView(v1);
- EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
- v2->layer()));
-
- // Reparent |v2|.
- content_view->AddChildView(v2);
- EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
- v2->layer()));
- EXPECT_TRUE(v2->layer()->IsDrawn());
-}
-
-class PaintTrackingView : public View {
- public:
- PaintTrackingView() : painted_(false) {
- }
-
- bool painted() const { return painted_; }
- void set_painted(bool value) { painted_ = value; }
-
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- painted_ = true;
- }
-
- private:
- bool painted_;
-
- DISALLOW_COPY_AND_ASSIGN(PaintTrackingView);
-};
-
-#if !defined(USE_WEBKIT_COMPOSITOR)
-// TODO(piman): this test relies on the way the non-webkit compositor works.
-// Layer::DrawTree should not be called with the webkit compositor. In the
-// WebKit case, it needs to go through the "real" compositor (not the test one)
-// to do the paints on the layer/views.
-
-// Makes sure child views with layers aren't painted when paint starts at an
-// ancestor.
-TEST_F(ViewLayerTest, DontPaintChildrenWithLayers) {
- PaintTrackingView* content_view = new PaintTrackingView;
- widget()->SetContentsView(content_view);
- content_view->SetPaintToLayer(true);
- GetRootLayer()->DrawTree();
- GetRootLayer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
- content_view->set_painted(false);
- // content_view no longer has a dirty rect. Paint from the root and make sure
- // PaintTrackingView isn't painted.
- GetRootLayer()->DrawTree();
- EXPECT_FALSE(content_view->painted());
-
- // Make content_view have a dirty rect, paint the layers and make sure
- // PaintTrackingView is painted.
- content_view->layer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
- GetRootLayer()->DrawTree();
- EXPECT_TRUE(content_view->painted());
-}
-#endif
-
-// Tests that the visibility of child layers are updated correctly when a View's
-// visibility changes.
-TEST_F(ViewLayerTest, VisibilityChildLayers) {
- View* v1 = new View;
- v1->SetPaintToLayer(true);
- widget()->SetContentsView(v1);
-
- View* v2 = new View;
- v1->AddChildView(v2);
-
- View* v3 = new View;
- v2->AddChildView(v3);
- v3->SetVisible(false);
-
- View* v4 = new View;
- v4->SetPaintToLayer(true);
- v3->AddChildView(v4);
-
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_FALSE(v4->layer()->IsDrawn());
-
- v2->SetVisible(false);
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_FALSE(v4->layer()->IsDrawn());
-
- v2->SetVisible(true);
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_FALSE(v4->layer()->IsDrawn());
-
- v2->SetVisible(false);
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_FALSE(v4->layer()->IsDrawn());
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
-
- v3->SetVisible(true);
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_FALSE(v4->layer()->IsDrawn());
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
-
- // Reparent |v3| to |v1|.
- v1->AddChildView(v3);
- EXPECT_TRUE(v1->layer()->IsDrawn());
- EXPECT_TRUE(v4->layer()->IsDrawn());
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
-}
-
-// This test creates a random View tree, and then randomly reorders child views,
-// reparents views etc. Unrelated changes can appear to break this test. So
-// marking this as FLAKY.
-TEST_F(ViewLayerTest, FLAKY_ViewLayerTreesInSync) {
- View* content = new View;
- content->SetPaintToLayer(true);
- widget()->SetContentsView(content);
- widget()->Show();
-
- ConstructTree(content, 5);
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
-
- ScrambleTree(content);
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
-
- ScrambleTree(content);
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
-
- ScrambleTree(content);
- EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
-}
-
-#endif // VIEWS_COMPOSITOR
-
-} // namespace views
diff --git a/views/view_win.cc b/views/view_win.cc
deleted file mode 100644
index f8adb43..0000000
--- a/views/view_win.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/view.h"
-
-// Necessary to define oleacc GUID's.
-#include <windows.h>
-#include <initguid.h>
-#include <oleacc.h>
-
-#include "ui/views/accessibility/native_view_accessibility_win.h"
-
-namespace views {
-
-gfx::NativeViewAccessible View::GetNativeViewAccessible() {
- if (!native_view_accessibility_win_.get())
- native_view_accessibility_win_ = NativeViewAccessibilityWin::Create(this);
- return native_view_accessibility_win_.get();
-}
-
-int View::GetHorizontalDragThreshold() {
- static int threshold = -1;
- if (threshold == -1)
- threshold = GetSystemMetrics(SM_CXDRAG) / 2;
- return threshold;
-}
-
-int View::GetVerticalDragThreshold() {
- static int threshold = -1;
- if (threshold == -1)
- threshold = GetSystemMetrics(SM_CYDRAG) / 2;
- return threshold;
-}
-
-} // namespace views
diff --git a/views/views.gyp b/views/views.gyp
index 889df74..63373b8 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -60,15 +60,10 @@
'painter.h',
'repeat_controller.cc',
'repeat_controller.h',
- 'view.cc',
- 'view.h',
- 'view_aura.cc',
'view_constants.cc',
'view_constants.h',
- 'view_gtk.cc',
'view_text_utils.cc',
'view_text_utils.h',
- 'view_win.cc',
'views_delegate.h',
'../ui/views/accessibility/native_view_accessibility_win.cc',
'../ui/views/accessibility/native_view_accessibility_win.h',
@@ -325,6 +320,11 @@
'../ui/views/touchui/gesture_manager.h',
'../ui/views/touchui/touch_selection_controller.cc',
'../ui/views/touchui/touch_selection_controller.h',
+ '../ui/views/view.cc',
+ '../ui/views/view.h',
+ '../ui/views/view_aura.cc',
+ '../ui/views/view_gtk.cc',
+ '../ui/views/view_win.cc',
'../ui/views/widget/aero_tooltip_manager.cc',
'../ui/views/widget/aero_tooltip_manager.h',
'../ui/views/widget/child_window_message_processor.cc',
@@ -534,6 +534,7 @@
'../ui/views/test/test_views_delegate.h',
'../ui/views/test/views_test_base.cc',
'../ui/views/test/views_test_base.h',
+ '../ui/views/view_unittest.cc',
'../ui/views/widget/native_widget_test_utils.h',
'../ui/views/widget/native_widget_test_utils_aura.cc',
'../ui/views/widget/native_widget_test_utils_gtk.cc',
@@ -543,7 +544,6 @@
'../ui/views/widget/widget_unittest.cc',
'accessible_pane_view_unittest.cc',
'run_all_unittests.cc',
- 'view_unittest.cc',
'<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc',
'<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc',