Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / views / view_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <map>
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/rand_util.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "grit/ui_strings.h"
12 #include "ui/base/accelerators/accelerator.h"
13 #include "ui/base/clipboard/clipboard.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/compositor/compositor.h"
16 #include "ui/compositor/layer.h"
17 #include "ui/compositor/layer_animator.h"
18 #include "ui/compositor/test/draw_waiter_for_test.h"
19 #include "ui/events/event.h"
20 #include "ui/events/keycodes/keyboard_codes.h"
21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/path.h"
23 #include "ui/gfx/transform.h"
24 #include "ui/views/background.h"
25 #include "ui/views/controls/native/native_view_host.h"
26 #include "ui/views/controls/scroll_view.h"
27 #include "ui/views/controls/textfield/textfield.h"
28 #include "ui/views/focus/view_storage.h"
29 #include "ui/views/test/views_test_base.h"
30 #include "ui/views/view.h"
31 #include "ui/views/views_delegate.h"
32 #include "ui/views/widget/native_widget.h"
33 #include "ui/views/widget/root_view.h"
34 #include "ui/views/window/dialog_client_view.h"
35 #include "ui/views/window/dialog_delegate.h"
36
37 #if defined(OS_WIN)
38 #include "ui/views/test/test_views_delegate.h"
39 #endif
40 #if defined(USE_AURA)
41 #include "ui/aura/root_window.h"
42 #include "ui/events/gestures/gesture_recognizer.h"
43 #endif
44
45 using base::ASCIIToUTF16;
46
47 namespace {
48
49 // Returns true if |ancestor| is an ancestor of |layer|.
50 bool LayerIsAncestor(const ui::Layer* ancestor, const ui::Layer* layer) {
51   while (layer && layer != ancestor)
52     layer = layer->parent();
53   return layer == ancestor;
54 }
55
56 // Convenience functions for walking a View tree.
57 const views::View* FirstView(const views::View* view) {
58   const views::View* v = view;
59   while (v->has_children())
60     v = v->child_at(0);
61   return v;
62 }
63
64 const views::View* NextView(const views::View* view) {
65   const views::View* v = view;
66   const views::View* parent = v->parent();
67   if (!parent)
68     return NULL;
69   int next = parent->GetIndexOf(v) + 1;
70   if (next != parent->child_count())
71     return FirstView(parent->child_at(next));
72   return parent;
73 }
74
75 // Convenience functions for walking a Layer tree.
76 const ui::Layer* FirstLayer(const ui::Layer* layer) {
77   const ui::Layer* l = layer;
78   while (l->children().size() > 0)
79     l = l->children()[0];
80   return l;
81 }
82
83 const ui::Layer* NextLayer(const ui::Layer* layer) {
84   const ui::Layer* parent = layer->parent();
85   if (!parent)
86     return NULL;
87   const std::vector<ui::Layer*> children = parent->children();
88   size_t index;
89   for (index = 0; index < children.size(); index++) {
90     if (children[index] == layer)
91       break;
92   }
93   size_t next = index + 1;
94   if (next < children.size())
95     return FirstLayer(children[next]);
96   return parent;
97 }
98
99 // Given the root nodes of a View tree and a Layer tree, makes sure the two
100 // trees are in sync.
101 bool ViewAndLayerTreeAreConsistent(const views::View* view,
102                                    const ui::Layer* layer) {
103   const views::View* v = FirstView(view);
104   const ui::Layer* l = FirstLayer(layer);
105   while (v && l) {
106     // Find the view with a layer.
107     while (v && !v->layer())
108       v = NextView(v);
109     EXPECT_TRUE(v);
110     if (!v)
111       return false;
112
113     // Check if the View tree and the Layer tree are in sync.
114     EXPECT_EQ(l, v->layer());
115     if (v->layer() != l)
116       return false;
117
118     // Check if the visibility states of the View and the Layer are in sync.
119     EXPECT_EQ(l->IsDrawn(), v->IsDrawn());
120     if (v->IsDrawn() != l->IsDrawn()) {
121       for (const views::View* vv = v; vv; vv = vv->parent())
122         LOG(ERROR) << "V: " << vv << " " << vv->visible() << " "
123                    << vv->IsDrawn() << " " << vv->layer();
124       for (const ui::Layer* ll = l; ll; ll = ll->parent())
125         LOG(ERROR) << "L: " << ll << " " << ll->IsDrawn();
126       return false;
127     }
128
129     // Check if the size of the View and the Layer are in sync.
130     EXPECT_EQ(l->bounds(), v->bounds());
131     if (v->bounds() != l->bounds())
132       return false;
133
134     if (v == view || l == layer)
135       return v == view && l == layer;
136
137     v = NextView(v);
138     l = NextLayer(l);
139   }
140
141   return false;
142 }
143
144 // Constructs a View tree with the specified depth.
145 void ConstructTree(views::View* view, int depth) {
146   if (depth == 0)
147     return;
148   int count = base::RandInt(1, 5);
149   for (int i = 0; i < count; i++) {
150     views::View* v = new views::View;
151     view->AddChildView(v);
152     if (base::RandDouble() > 0.5)
153       v->SetPaintToLayer(true);
154     if (base::RandDouble() < 0.2)
155       v->SetVisible(false);
156
157     ConstructTree(v, depth - 1);
158   }
159 }
160
161 void ScrambleTree(views::View* view) {
162   int count = view->child_count();
163   if (count == 0)
164     return;
165   for (int i = 0; i < count; i++) {
166     ScrambleTree(view->child_at(i));
167   }
168
169   if (count > 1) {
170     int a = base::RandInt(0, count - 1);
171     int b = base::RandInt(0, count - 1);
172
173     views::View* view_a = view->child_at(a);
174     views::View* view_b = view->child_at(b);
175     view->ReorderChildView(view_a, b);
176     view->ReorderChildView(view_b, a);
177   }
178
179   if (!view->layer() && base::RandDouble() < 0.1)
180     view->SetPaintToLayer(true);
181
182   if (base::RandDouble() < 0.1)
183     view->SetVisible(!view->visible());
184 }
185
186 // Convenience to make constructing a GestureEvent simpler.
187 class GestureEventForTest : public ui::GestureEvent {
188  public:
189   GestureEventForTest(ui::EventType type, int x, int y, int flags)
190       : GestureEvent(type, x, y, flags, base::TimeDelta(),
191                      ui::GestureEventDetails(type, 0.0f, 0.0f), 0) {
192   }
193
194  private:
195   DISALLOW_COPY_AND_ASSIGN(GestureEventForTest);
196 };
197
198 }  // namespace
199
200 namespace views {
201
202 typedef ViewsTestBase ViewTest;
203
204 // A derived class for testing purpose.
205 class TestView : public View {
206  public:
207   TestView() : View(), delete_on_pressed_(false), in_touch_sequence_(false) {}
208   virtual ~TestView() {}
209
210   // Reset all test state
211   void Reset() {
212     did_change_bounds_ = false;
213     last_mouse_event_type_ = 0;
214     location_.SetPoint(0, 0);
215     received_mouse_enter_ = false;
216     received_mouse_exit_ = false;
217     last_touch_event_type_ = 0;
218     last_touch_event_was_handled_ = false;
219     last_gesture_event_type_ = 0;
220     last_gesture_event_was_handled_ = false;
221     last_clip_.setEmpty();
222     accelerator_count_map_.clear();
223   }
224
225   // Exposed as public for testing.
226   void DoFocus() {
227     views::View::Focus();
228   }
229
230   void DoBlur() {
231     views::View::Blur();
232   }
233
234   bool focusable() const { return View::focusable(); }
235
236   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
237   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
238   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
239   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
240   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
241   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
242
243   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
244   // Ignores GestureEvent by default.
245   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
246
247   virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
248   virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
249   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
250
251   // OnBoundsChanged.
252   bool did_change_bounds_;
253   gfx::Rect new_bounds_;
254
255   // MouseEvent.
256   int last_mouse_event_type_;
257   gfx::Point location_;
258   bool received_mouse_enter_;
259   bool received_mouse_exit_;
260   bool delete_on_pressed_;
261
262   // Painting.
263   std::vector<gfx::Rect> scheduled_paint_rects_;
264
265   // GestureEvent
266   int last_gesture_event_type_;
267   bool last_gesture_event_was_handled_;
268
269   // TouchEvent.
270   int last_touch_event_type_;
271   bool last_touch_event_was_handled_;
272   bool in_touch_sequence_;
273
274   // Painting.
275   SkRect last_clip_;
276
277   // Accelerators.
278   std::map<ui::Accelerator, int> accelerator_count_map_;
279 };
280
281 // A view subclass that ignores all touch events for testing purposes.
282 class TestViewIgnoreTouch : public TestView {
283  public:
284   TestViewIgnoreTouch() : TestView() {}
285   virtual ~TestViewIgnoreTouch() {}
286
287  private:
288   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
289 };
290
291 // A view subclass that consumes all Gesture events for testing purposes.
292 class TestViewConsumeGesture : public TestView {
293  public:
294   TestViewConsumeGesture() : TestView() {}
295   virtual ~TestViewConsumeGesture() {}
296
297  protected:
298   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
299     last_gesture_event_type_ = event->type();
300     location_.SetPoint(event->x(), event->y());
301     event->StopPropagation();
302   }
303
304  private:
305   DISALLOW_COPY_AND_ASSIGN(TestViewConsumeGesture);
306 };
307
308 // A view subclass that ignores all Gesture events.
309 class TestViewIgnoreGesture: public TestView {
310  public:
311   TestViewIgnoreGesture() : TestView() {}
312   virtual ~TestViewIgnoreGesture() {}
313
314  private:
315   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
316   }
317
318   DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreGesture);
319 };
320
321 // A view subclass that ignores all scroll-gesture events, but consume all other
322 // gesture events.
323 class TestViewIgnoreScrollGestures : public TestViewConsumeGesture {
324  public:
325   TestViewIgnoreScrollGestures() {}
326   virtual ~TestViewIgnoreScrollGestures() {}
327
328  private:
329   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
330     if (event->IsScrollGestureEvent())
331       return;
332     TestViewConsumeGesture::OnGestureEvent(event);
333   }
334
335   DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreScrollGestures);
336 };
337
338 ////////////////////////////////////////////////////////////////////////////////
339 // OnBoundsChanged
340 ////////////////////////////////////////////////////////////////////////////////
341
342 void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
343   did_change_bounds_ = true;
344   new_bounds_ = bounds();
345 }
346
347 TEST_F(ViewTest, OnBoundsChanged) {
348   TestView v;
349
350   gfx::Rect prev_rect(0, 0, 200, 200);
351   gfx::Rect new_rect(100, 100, 250, 250);
352
353   v.SetBoundsRect(prev_rect);
354   v.Reset();
355   v.SetBoundsRect(new_rect);
356
357   EXPECT_TRUE(v.did_change_bounds_);
358   EXPECT_EQ(v.new_bounds_, new_rect);
359   EXPECT_EQ(v.bounds(), new_rect);
360 }
361
362 ////////////////////////////////////////////////////////////////////////////////
363 // MouseEvent
364 ////////////////////////////////////////////////////////////////////////////////
365
366 bool TestView::OnMousePressed(const ui::MouseEvent& event) {
367   last_mouse_event_type_ = event.type();
368   location_.SetPoint(event.x(), event.y());
369   if (delete_on_pressed_)
370     delete this;
371   return true;
372 }
373
374 bool TestView::OnMouseDragged(const ui::MouseEvent& event) {
375   last_mouse_event_type_ = event.type();
376   location_.SetPoint(event.x(), event.y());
377   return true;
378 }
379
380 void TestView::OnMouseReleased(const ui::MouseEvent& event) {
381   last_mouse_event_type_ = event.type();
382   location_.SetPoint(event.x(), event.y());
383 }
384
385 void TestView::OnMouseEntered(const ui::MouseEvent& event) {
386   received_mouse_enter_ = true;
387 }
388
389 void TestView::OnMouseExited(const ui::MouseEvent& event) {
390   received_mouse_exit_ = true;
391 }
392
393 TEST_F(ViewTest, MouseEvent) {
394   TestView* v1 = new TestView();
395   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
396
397   TestView* v2 = new TestView();
398   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
399
400   scoped_ptr<Widget> widget(new Widget);
401   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
402   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
403   params.bounds = gfx::Rect(50, 50, 650, 650);
404   widget->Init(params);
405   internal::RootView* root =
406       static_cast<internal::RootView*>(widget->GetRootView());
407
408   root->AddChildView(v1);
409   v1->AddChildView(v2);
410
411   v1->Reset();
412   v2->Reset();
413
414   gfx::Point p1(110, 120);
415   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
416                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
417   root->OnMousePressed(pressed);
418   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_PRESSED);
419   EXPECT_EQ(v2->location_.x(), 10);
420   EXPECT_EQ(v2->location_.y(), 20);
421   // Make sure v1 did not receive the event
422   EXPECT_EQ(v1->last_mouse_event_type_, 0);
423
424   // Drag event out of bounds. Should still go to v2
425   v1->Reset();
426   v2->Reset();
427   gfx::Point p2(50, 40);
428   ui::MouseEvent dragged(ui::ET_MOUSE_DRAGGED, p2, p2,
429                          ui::EF_LEFT_MOUSE_BUTTON, 0);
430   root->OnMouseDragged(dragged);
431   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_DRAGGED);
432   EXPECT_EQ(v2->location_.x(), -50);
433   EXPECT_EQ(v2->location_.y(), -60);
434   // Make sure v1 did not receive the event
435   EXPECT_EQ(v1->last_mouse_event_type_, 0);
436
437   // Releasted event out of bounds. Should still go to v2
438   v1->Reset();
439   v2->Reset();
440   ui::MouseEvent released(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), 0,
441                           0);
442   root->OnMouseDragged(released);
443   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_RELEASED);
444   EXPECT_EQ(v2->location_.x(), -100);
445   EXPECT_EQ(v2->location_.y(), -100);
446   // Make sure v1 did not receive the event
447   EXPECT_EQ(v1->last_mouse_event_type_, 0);
448
449   widget->CloseNow();
450 }
451
452 // Confirm that a view can be deleted as part of processing a mouse press.
453 TEST_F(ViewTest, DeleteOnPressed) {
454   TestView* v1 = new TestView();
455   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
456
457   TestView* v2 = new TestView();
458   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
459
460   v1->Reset();
461   v2->Reset();
462
463   scoped_ptr<Widget> widget(new Widget);
464   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
465   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
466   params.bounds = gfx::Rect(50, 50, 650, 650);
467   widget->Init(params);
468   View* root = widget->GetRootView();
469
470   root->AddChildView(v1);
471   v1->AddChildView(v2);
472
473   v2->delete_on_pressed_ = true;
474   gfx::Point point(110, 120);
475   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
476                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
477   root->OnMousePressed(pressed);
478   EXPECT_EQ(0, v1->child_count());
479
480   widget->CloseNow();
481 }
482
483 ////////////////////////////////////////////////////////////////////////////////
484 // TouchEvent
485 ////////////////////////////////////////////////////////////////////////////////
486 void TestView::OnTouchEvent(ui::TouchEvent* event) {
487   last_touch_event_type_ = event->type();
488   location_.SetPoint(event->x(), event->y());
489   if (!in_touch_sequence_) {
490     if (event->type() == ui::ET_TOUCH_PRESSED) {
491       in_touch_sequence_ = true;
492       event->StopPropagation();
493       return;
494     }
495   } else {
496     if (event->type() == ui::ET_TOUCH_RELEASED) {
497       in_touch_sequence_ = false;
498       event->SetHandled();
499       return;
500     }
501     event->StopPropagation();
502     return;
503   }
504
505   if (last_touch_event_was_handled_)
506    event->StopPropagation();
507 }
508
509 void TestViewIgnoreTouch::OnTouchEvent(ui::TouchEvent* event) {
510 }
511
512 TEST_F(ViewTest, TouchEvent) {
513   TestView* v1 = new TestView();
514   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
515
516   TestView* v2 = new TestView();
517   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
518
519   TestView* v3 = new TestViewIgnoreTouch();
520   v3->SetBoundsRect(gfx::Rect(0, 0, 100, 100));
521
522   scoped_ptr<Widget> widget(new Widget());
523   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
524   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
525   params.bounds = gfx::Rect(50, 50, 650, 650);
526   widget->Init(params);
527   internal::RootView* root =
528       static_cast<internal::RootView*>(widget->GetRootView());
529
530   root->AddChildView(v1);
531   v1->AddChildView(v2);
532   v2->AddChildView(v3);
533
534   // |v3| completely obscures |v2|, but all the touch events on |v3| should
535   // reach |v2| because |v3| doesn't process any touch events.
536
537   // Make sure if none of the views handle the touch event, the gesture manager
538   // does.
539   v1->Reset();
540   v2->Reset();
541
542   ui::TouchEvent unhandled(ui::ET_TOUCH_MOVED,
543                            gfx::Point(400, 400),
544                            0, /* no flags */
545                            0, /* first finger touch */
546                            base::TimeDelta(),
547                            1.0, 0.0, 1.0, 0.0);
548   root->DispatchTouchEvent(&unhandled);
549
550   EXPECT_EQ(v1->last_touch_event_type_, 0);
551   EXPECT_EQ(v2->last_touch_event_type_, 0);
552
553   // Test press, drag, release touch sequence.
554   v1->Reset();
555   v2->Reset();
556
557   ui::TouchEvent pressed(ui::ET_TOUCH_PRESSED,
558                          gfx::Point(110, 120),
559                          0, /* no flags */
560                          0, /* first finger touch */
561                          base::TimeDelta(),
562                          1.0, 0.0, 1.0, 0.0);
563   v2->last_touch_event_was_handled_ = true;
564   root->DispatchTouchEvent(&pressed);
565
566   EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_PRESSED);
567   EXPECT_EQ(v2->location_.x(), 10);
568   EXPECT_EQ(v2->location_.y(), 20);
569   // Make sure v1 did not receive the event
570   EXPECT_EQ(v1->last_touch_event_type_, 0);
571
572   // Drag event out of bounds. Should still go to v2
573   v1->Reset();
574   v2->Reset();
575   ui::TouchEvent dragged(ui::ET_TOUCH_MOVED,
576                          gfx::Point(50, 40),
577                          0, /* no flags */
578                          0, /* first finger touch */
579                          base::TimeDelta(),
580                          1.0, 0.0, 1.0, 0.0);
581
582   root->DispatchTouchEvent(&dragged);
583   EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_MOVED);
584   EXPECT_EQ(v2->location_.x(), -50);
585   EXPECT_EQ(v2->location_.y(), -60);
586   // Make sure v1 did not receive the event
587   EXPECT_EQ(v1->last_touch_event_type_, 0);
588
589   // Released event out of bounds. Should still go to v2
590   v1->Reset();
591   v2->Reset();
592   ui::TouchEvent released(ui::ET_TOUCH_RELEASED, gfx::Point(),
593                           0, /* no flags */
594                           0, /* first finger */
595                           base::TimeDelta(),
596                           1.0, 0.0, 1.0, 0.0);
597   v2->last_touch_event_was_handled_ = true;
598   root->DispatchTouchEvent(&released);
599   EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_RELEASED);
600   EXPECT_EQ(v2->location_.x(), -100);
601   EXPECT_EQ(v2->location_.y(), -100);
602   // Make sure v1 did not receive the event
603   EXPECT_EQ(v1->last_touch_event_type_, 0);
604
605   widget->CloseNow();
606 }
607
608 void TestView::OnGestureEvent(ui::GestureEvent* event) {
609 }
610
611 TEST_F(ViewTest, GestureEvent) {
612   // Views hierarchy for non delivery of GestureEvent.
613   TestView* v1 = new TestViewConsumeGesture();
614   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
615
616   TestView* v2 = new TestViewConsumeGesture();
617   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
618
619   TestView* v3 = new TestViewIgnoreGesture();
620   v3->SetBoundsRect(gfx::Rect(0, 0, 100, 100));
621
622   scoped_ptr<Widget> widget(new Widget());
623   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
624   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
625   params.bounds = gfx::Rect(50, 50, 650, 650);
626   widget->Init(params);
627   internal::RootView* root =
628       static_cast<internal::RootView*>(widget->GetRootView());
629
630   root->AddChildView(v1);
631   v1->AddChildView(v2);
632   v2->AddChildView(v3);
633
634   // |v3| completely obscures |v2|, but all the gesture events on |v3| should
635   // reach |v2| because |v3| doesn't process any gesture events. However, since
636   // |v2| does process gesture events, gesture events on |v3| or |v2| should not
637   // reach |v1|.
638
639   v1->Reset();
640   v2->Reset();
641   v3->Reset();
642
643   // Gesture on |v3|
644   GestureEventForTest g1(ui::ET_GESTURE_TAP, 110, 110, 0);
645   root->DispatchGestureEvent(&g1);
646   EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_);
647   EXPECT_EQ(gfx::Point(10, 10), v2->location_);
648   EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_);
649
650   // Simulate an up so that RootView is no longer targetting |v3|.
651   GestureEventForTest g1_up(ui::ET_GESTURE_END, 110, 110, 0);
652   root->DispatchGestureEvent(&g1_up);
653
654   v1->Reset();
655   v2->Reset();
656   v3->Reset();
657
658   // Gesture on |v1|
659   GestureEventForTest g2(ui::ET_GESTURE_TAP, 80, 80, 0);
660   root->DispatchGestureEvent(&g2);
661   EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
662   EXPECT_EQ(gfx::Point(80, 80), v1->location_);
663   EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_);
664
665   // Send event |g1| again. Even though the coordinates target |v3| it should go
666   // to |v1| as that is the view the touch was initially down on.
667   v1->last_gesture_event_type_ = ui::ET_UNKNOWN;
668   v3->last_gesture_event_type_ = ui::ET_UNKNOWN;
669   root->DispatchGestureEvent(&g1);
670   EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
671   EXPECT_EQ(ui::ET_UNKNOWN, v3->last_gesture_event_type_);
672   EXPECT_EQ("110,110", v1->location_.ToString());
673
674   widget->CloseNow();
675 }
676
677 TEST_F(ViewTest, ScrollGestureEvent) {
678   // Views hierarchy for non delivery of GestureEvent.
679   TestView* v1 = new TestViewConsumeGesture();
680   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
681
682   TestView* v2 = new TestViewIgnoreScrollGestures();
683   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
684
685   TestView* v3 = new TestViewIgnoreGesture();
686   v3->SetBoundsRect(gfx::Rect(0, 0, 100, 100));
687
688   scoped_ptr<Widget> widget(new Widget());
689   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
690   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
691   params.bounds = gfx::Rect(50, 50, 650, 650);
692   widget->Init(params);
693   internal::RootView* root =
694       static_cast<internal::RootView*>(widget->GetRootView());
695
696   root->AddChildView(v1);
697   v1->AddChildView(v2);
698   v2->AddChildView(v3);
699
700   // |v3| completely obscures |v2|, but all the gesture events on |v3| should
701   // reach |v2| because |v3| doesn't process any gesture events. However, since
702   // |v2| does process gesture events, gesture events on |v3| or |v2| should not
703   // reach |v1|.
704
705   v1->Reset();
706   v2->Reset();
707   v3->Reset();
708
709   // Gesture on |v3|
710   GestureEventForTest g1(ui::ET_GESTURE_TAP, 110, 110, 0);
711   root->DispatchGestureEvent(&g1);
712   EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_);
713   EXPECT_EQ(gfx::Point(10, 10), v2->location_);
714   EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_);
715
716   v2->Reset();
717
718   // Send scroll gestures on |v3|. The gesture should reach |v2|, however,
719   // since it does not process scroll-gesture events, these events should reach
720   // |v1|.
721   GestureEventForTest gscroll_begin(ui::ET_GESTURE_SCROLL_BEGIN, 115, 115, 0);
722   root->DispatchGestureEvent(&gscroll_begin);
723   EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_);
724   EXPECT_EQ(ui::ET_GESTURE_SCROLL_BEGIN, v1->last_gesture_event_type_);
725   v1->Reset();
726
727   // Send a second tap on |v1|. The event should reach |v2| since it is the
728   // default gesture handler, and not |v1| (even though it is the view under the
729   // point, and is the scroll event handler).
730   GestureEventForTest second_tap(ui::ET_GESTURE_TAP, 70, 70, 0);
731   root->DispatchGestureEvent(&second_tap);
732   EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_);
733   EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_);
734   v2->Reset();
735
736   GestureEventForTest gscroll_end(ui::ET_GESTURE_SCROLL_END, 50, 50, 0);
737   root->DispatchGestureEvent(&gscroll_end);
738   EXPECT_EQ(ui::ET_GESTURE_SCROLL_END, v1->last_gesture_event_type_);
739   v1->Reset();
740
741   // Simulate an up so that RootView is no longer targetting |v3|.
742   GestureEventForTest g1_up(ui::ET_GESTURE_END, 110, 110, 0);
743   root->DispatchGestureEvent(&g1_up);
744   EXPECT_EQ(ui::ET_GESTURE_END, v2->last_gesture_event_type_);
745
746   v1->Reset();
747   v2->Reset();
748   v3->Reset();
749
750   // Gesture on |v1|
751   GestureEventForTest g2(ui::ET_GESTURE_TAP, 80, 80, 0);
752   root->DispatchGestureEvent(&g2);
753   EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
754   EXPECT_EQ(gfx::Point(80, 80), v1->location_);
755   EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_);
756
757   // Send event |g1| again. Even though the coordinates target |v3| it should go
758   // to |v1| as that is the view the touch was initially down on.
759   v1->last_gesture_event_type_ = ui::ET_UNKNOWN;
760   v3->last_gesture_event_type_ = ui::ET_UNKNOWN;
761   root->DispatchGestureEvent(&g1);
762   EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
763   EXPECT_EQ(ui::ET_UNKNOWN, v3->last_gesture_event_type_);
764   EXPECT_EQ("110,110", v1->location_.ToString());
765
766   widget->CloseNow();
767 }
768
769 ////////////////////////////////////////////////////////////////////////////////
770 // Painting
771 ////////////////////////////////////////////////////////////////////////////////
772
773 void TestView::Paint(gfx::Canvas* canvas) {
774   canvas->sk_canvas()->getClipBounds(&last_clip_);
775 }
776
777 void TestView::SchedulePaintInRect(const gfx::Rect& rect) {
778   scheduled_paint_rects_.push_back(rect);
779   View::SchedulePaintInRect(rect);
780 }
781
782 void CheckRect(const SkRect& check_rect, const SkRect& target_rect) {
783   EXPECT_EQ(target_rect.fLeft, check_rect.fLeft);
784   EXPECT_EQ(target_rect.fRight, check_rect.fRight);
785   EXPECT_EQ(target_rect.fTop, check_rect.fTop);
786   EXPECT_EQ(target_rect.fBottom, check_rect.fBottom);
787 }
788
789 /* This test is disabled because it is flakey on some systems.
790 TEST_F(ViewTest, DISABLED_Painting) {
791   // Determine if InvalidateRect generates an empty paint rectangle.
792   EmptyWindow paint_window(CRect(50, 50, 650, 650));
793   paint_window.RedrawWindow(CRect(0, 0, 600, 600), NULL,
794                             RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN);
795   bool empty_paint = paint_window.empty_paint();
796
797   NativeWidgetWin window;
798   window.set_delete_on_destroy(false);
799   window.set_window_style(WS_OVERLAPPEDWINDOW);
800   window.Init(NULL, gfx::Rect(50, 50, 650, 650), NULL);
801   View* root = window.GetRootView();
802
803   TestView* v1 = new TestView();
804   v1->SetBoundsRect(gfx::Rect(0, 0, 650, 650));
805   root->AddChildView(v1);
806
807   TestView* v2 = new TestView();
808   v2->SetBoundsRect(gfx::Rect(10, 10, 80, 80));
809   v1->AddChildView(v2);
810
811   TestView* v3 = new TestView();
812   v3->SetBoundsRect(gfx::Rect(10, 10, 60, 60));
813   v2->AddChildView(v3);
814
815   TestView* v4 = new TestView();
816   v4->SetBoundsRect(gfx::Rect(10, 200, 100, 100));
817   v1->AddChildView(v4);
818
819   // Make sure to paint current rects
820   PaintRootView(root, empty_paint);
821
822
823   v1->Reset();
824   v2->Reset();
825   v3->Reset();
826   v4->Reset();
827   v3->SchedulePaintInRect(gfx::Rect(10, 10, 10, 10));
828   PaintRootView(root, empty_paint);
829
830   SkRect tmp_rect;
831
832   tmp_rect.iset(10, 10, 20, 20);
833   CheckRect(v3->last_clip_, tmp_rect);
834
835   tmp_rect.iset(20, 20, 30, 30);
836   CheckRect(v2->last_clip_, tmp_rect);
837
838   tmp_rect.iset(30, 30, 40, 40);
839   CheckRect(v1->last_clip_, tmp_rect);
840
841   // Make sure v4 was not painted
842   tmp_rect.setEmpty();
843   CheckRect(v4->last_clip_, tmp_rect);
844
845   window.DestroyWindow();
846 }
847 */
848
849 TEST_F(ViewTest, RemoveNotification) {
850   ViewStorage* vs = ViewStorage::GetInstance();
851   Widget* widget = new Widget;
852   widget->Init(CreateParams(Widget::InitParams::TYPE_POPUP));
853   View* root_view = widget->GetRootView();
854
855   View* v1 = new View;
856   int s1 = vs->CreateStorageID();
857   vs->StoreView(s1, v1);
858   root_view->AddChildView(v1);
859   View* v11 = new View;
860   int s11 = vs->CreateStorageID();
861   vs->StoreView(s11, v11);
862   v1->AddChildView(v11);
863   View* v111 = new View;
864   int s111 = vs->CreateStorageID();
865   vs->StoreView(s111, v111);
866   v11->AddChildView(v111);
867   View* v112 = new View;
868   int s112 = vs->CreateStorageID();
869   vs->StoreView(s112, v112);
870   v11->AddChildView(v112);
871   View* v113 = new View;
872   int s113 = vs->CreateStorageID();
873   vs->StoreView(s113, v113);
874   v11->AddChildView(v113);
875   View* v1131 = new View;
876   int s1131 = vs->CreateStorageID();
877   vs->StoreView(s1131, v1131);
878   v113->AddChildView(v1131);
879   View* v12 = new View;
880   int s12 = vs->CreateStorageID();
881   vs->StoreView(s12, v12);
882   v1->AddChildView(v12);
883
884   View* v2 = new View;
885   int s2 = vs->CreateStorageID();
886   vs->StoreView(s2, v2);
887   root_view->AddChildView(v2);
888   View* v21 = new View;
889   int s21 = vs->CreateStorageID();
890   vs->StoreView(s21, v21);
891   v2->AddChildView(v21);
892   View* v211 = new View;
893   int s211 = vs->CreateStorageID();
894   vs->StoreView(s211, v211);
895   v21->AddChildView(v211);
896
897   size_t stored_views = vs->view_count();
898
899   // Try removing a leaf view.
900   v21->RemoveChildView(v211);
901   EXPECT_EQ(stored_views - 1, vs->view_count());
902   EXPECT_EQ(NULL, vs->RetrieveView(s211));
903   delete v211;  // We won't use this one anymore.
904
905   // Now try removing a view with a hierarchy of depth 1.
906   v11->RemoveChildView(v113);
907   EXPECT_EQ(stored_views - 3, vs->view_count());
908   EXPECT_EQ(NULL, vs->RetrieveView(s113));
909   EXPECT_EQ(NULL, vs->RetrieveView(s1131));
910   delete v113;  // We won't use this one anymore.
911
912   // Now remove even more.
913   root_view->RemoveChildView(v1);
914   EXPECT_EQ(NULL, vs->RetrieveView(s1));
915   EXPECT_EQ(NULL, vs->RetrieveView(s11));
916   EXPECT_EQ(NULL, vs->RetrieveView(s12));
917   EXPECT_EQ(NULL, vs->RetrieveView(s111));
918   EXPECT_EQ(NULL, vs->RetrieveView(s112));
919
920   // Put v1 back for more tests.
921   root_view->AddChildView(v1);
922   vs->StoreView(s1, v1);
923
924   // Synchronously closing the window deletes the view hierarchy, which should
925   // remove all its views from ViewStorage.
926   widget->CloseNow();
927   EXPECT_EQ(stored_views - 10, vs->view_count());
928   EXPECT_EQ(NULL, vs->RetrieveView(s1));
929   EXPECT_EQ(NULL, vs->RetrieveView(s12));
930   EXPECT_EQ(NULL, vs->RetrieveView(s11));
931   EXPECT_EQ(NULL, vs->RetrieveView(s12));
932   EXPECT_EQ(NULL, vs->RetrieveView(s21));
933   EXPECT_EQ(NULL, vs->RetrieveView(s111));
934   EXPECT_EQ(NULL, vs->RetrieveView(s112));
935 }
936
937 namespace {
938 class HitTestView : public View {
939  public:
940   explicit HitTestView(bool has_hittest_mask)
941       : has_hittest_mask_(has_hittest_mask) {
942   }
943   virtual ~HitTestView() {}
944
945  protected:
946   // Overridden from View:
947   virtual bool HasHitTestMask() const OVERRIDE {
948     return has_hittest_mask_;
949   }
950   virtual void GetHitTestMask(HitTestSource source,
951                               gfx::Path* mask) const OVERRIDE {
952     DCHECK(has_hittest_mask_);
953     DCHECK(mask);
954
955     SkScalar w = SkIntToScalar(width());
956     SkScalar h = SkIntToScalar(height());
957
958     // Create a triangular mask within the bounds of this View.
959     mask->moveTo(w / 2, 0);
960     mask->lineTo(w, h);
961     mask->lineTo(0, h);
962     mask->close();
963   }
964
965  private:
966   bool has_hittest_mask_;
967
968   DISALLOW_COPY_AND_ASSIGN(HitTestView);
969 };
970
971 gfx::Point ConvertPointToView(View* view, const gfx::Point& p) {
972   gfx::Point tmp(p);
973   View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp);
974   return tmp;
975 }
976
977 gfx::Rect ConvertRectToView(View* view, const gfx::Rect& r) {
978   gfx::Rect tmp(r);
979   tmp.set_origin(ConvertPointToView(view, r.origin()));
980   return tmp;
981 }
982
983 void RotateCounterclockwise(gfx::Transform* transform) {
984   transform->matrix().set3x3(0, -1, 0,
985                              1,  0, 0,
986                              0,  0, 1);
987 }
988
989 void RotateClockwise(gfx::Transform* transform) {
990   transform->matrix().set3x3( 0, 1, 0,
991                              -1, 0, 0,
992                               0, 0, 1);
993 }
994
995 }  // namespace
996
997 TEST_F(ViewTest, HitTestMasks) {
998   Widget* widget = new Widget;
999   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1000   widget->Init(params);
1001   View* root_view = widget->GetRootView();
1002   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
1003
1004   gfx::Rect v1_bounds = gfx::Rect(0, 0, 100, 100);
1005   HitTestView* v1 = new HitTestView(false);
1006   v1->SetBoundsRect(v1_bounds);
1007   root_view->AddChildView(v1);
1008
1009   gfx::Rect v2_bounds = gfx::Rect(105, 0, 100, 100);
1010   HitTestView* v2 = new HitTestView(true);
1011   v2->SetBoundsRect(v2_bounds);
1012   root_view->AddChildView(v2);
1013
1014   gfx::Point v1_centerpoint = v1_bounds.CenterPoint();
1015   gfx::Point v2_centerpoint = v2_bounds.CenterPoint();
1016   gfx::Point v1_origin = v1_bounds.origin();
1017   gfx::Point v2_origin = v2_bounds.origin();
1018
1019   gfx::Rect r1(10, 10, 110, 15);
1020   gfx::Rect r2(106, 1, 98, 98);
1021   gfx::Rect r3(0, 0, 300, 300);
1022   gfx::Rect r4(115, 342, 200, 10);
1023
1024   // Test HitTestPoint
1025   EXPECT_TRUE(v1->HitTestPoint(ConvertPointToView(v1, v1_centerpoint)));
1026   EXPECT_TRUE(v2->HitTestPoint(ConvertPointToView(v2, v2_centerpoint)));
1027
1028   EXPECT_TRUE(v1->HitTestPoint(ConvertPointToView(v1, v1_origin)));
1029   EXPECT_FALSE(v2->HitTestPoint(ConvertPointToView(v2, v2_origin)));
1030
1031   // Test HitTestRect
1032   EXPECT_TRUE(v1->HitTestRect(ConvertRectToView(v1, r1)));
1033   EXPECT_FALSE(v2->HitTestRect(ConvertRectToView(v2, r1)));
1034
1035   EXPECT_FALSE(v1->HitTestRect(ConvertRectToView(v1, r2)));
1036   EXPECT_TRUE(v2->HitTestRect(ConvertRectToView(v2, r2)));
1037
1038   EXPECT_TRUE(v1->HitTestRect(ConvertRectToView(v1, r3)));
1039   EXPECT_TRUE(v2->HitTestRect(ConvertRectToView(v2, r3)));
1040
1041   EXPECT_FALSE(v1->HitTestRect(ConvertRectToView(v1, r4)));
1042   EXPECT_FALSE(v2->HitTestRect(ConvertRectToView(v2, r4)));
1043
1044   // Test GetEventHandlerForPoint
1045   EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_centerpoint));
1046   EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint));
1047
1048   EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin));
1049   EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin));
1050
1051   // Test GetTooltipHandlerForPoint
1052   EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_centerpoint));
1053   EXPECT_EQ(v2, root_view->GetTooltipHandlerForPoint(v2_centerpoint));
1054
1055   EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin));
1056   EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin));
1057
1058   EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin));
1059
1060   widget->CloseNow();
1061 }
1062
1063 // Tests the correctness of the rect-based targeting algorithm implemented in
1064 // View::GetEventHandlerForRect(). See http://goo.gl/3Jp2BD for a description
1065 // of rect-based targeting.
1066 TEST_F(ViewTest, GetEventHandlerForRect) {
1067   Widget* widget = new Widget;
1068   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1069   widget->Init(params);
1070   View* root_view = widget->GetRootView();
1071   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
1072
1073   // Have this hierarchy of views (the coordinates here are all in
1074   // the root view's coordinate space):
1075   // v1 (0, 0, 100, 100)
1076   // v2 (150, 0, 250, 100)
1077   // v3 (0, 200, 150, 100)
1078   //     v31 (10, 210, 80, 80)
1079   //     v32 (110, 210, 30, 80)
1080   // v4 (300, 200, 100, 100)
1081   //     v41 (310, 210, 80, 80)
1082   //         v411 (370, 275, 10, 5)
1083   // v5 (450, 197, 30, 36)
1084   //     v51 (450, 200, 30, 30)
1085
1086   // The coordinates used for SetBounds are in parent coordinates.
1087
1088   TestView* v1 = new TestView;
1089   v1->SetBounds(0, 0, 100, 100);
1090   root_view->AddChildView(v1);
1091
1092   TestView* v2 = new TestView;
1093   v2->SetBounds(150, 0, 250, 100);
1094   root_view->AddChildView(v2);
1095
1096   TestView* v3 = new TestView;
1097   v3->SetBounds(0, 200, 150, 100);
1098   root_view->AddChildView(v3);
1099
1100   TestView* v4 = new TestView;
1101   v4->SetBounds(300, 200, 100, 100);
1102   root_view->AddChildView(v4);
1103
1104   TestView* v31 = new TestView;
1105   v31->SetBounds(10, 10, 80, 80);
1106   v3->AddChildView(v31);
1107
1108   TestView* v32 = new TestView;
1109   v32->SetBounds(110, 10, 30, 80);
1110   v3->AddChildView(v32);
1111
1112   TestView* v41 = new TestView;
1113   v41->SetBounds(10, 10, 80, 80);
1114   v4->AddChildView(v41);
1115
1116   TestView* v411 = new TestView;
1117   v411->SetBounds(60, 65, 10, 5);
1118   v41->AddChildView(v411);
1119
1120   TestView* v5 = new TestView;
1121   v5->SetBounds(450, 197, 30, 36);
1122   root_view->AddChildView(v5);
1123
1124   TestView* v51 = new TestView;
1125   v51->SetBounds(0, 3, 30, 30);
1126   v5->AddChildView(v51);
1127
1128   // |touch_rect| does not intersect any descendant view of |root_view|.
1129   gfx::Rect touch_rect(105, 105, 30, 45);
1130   View* result_view = root_view->GetEventHandlerForRect(touch_rect);
1131   EXPECT_EQ(root_view, result_view);
1132   result_view = NULL;
1133
1134   // Covers |v1| by at least 60%.
1135   touch_rect.SetRect(15, 15, 100, 100);
1136   result_view = root_view->GetEventHandlerForRect(touch_rect);
1137   EXPECT_EQ(v1, result_view);
1138   result_view = NULL;
1139
1140   // Intersects |v1| but does not cover it by at least 60%. The center
1141   // of |touch_rect| is within |v1|.
1142   touch_rect.SetRect(50, 50, 5, 10);
1143   result_view = root_view->GetEventHandlerForRect(touch_rect);
1144   EXPECT_EQ(v1, result_view);
1145   result_view = NULL;
1146
1147   // Intersects |v1| but does not cover it by at least 60%. The center
1148   // of |touch_rect| is not within |v1|.
1149   touch_rect.SetRect(95, 96, 21, 22);
1150   result_view = root_view->GetEventHandlerForRect(touch_rect);
1151   EXPECT_EQ(root_view, result_view);
1152   result_view = NULL;
1153
1154   // Intersects |v1| and |v2|, but only covers |v2| by at least 60%.
1155   touch_rect.SetRect(95, 10, 300, 120);
1156   result_view = root_view->GetEventHandlerForRect(touch_rect);
1157   EXPECT_EQ(v2, result_view);
1158   result_view = NULL;
1159
1160   // Covers both |v1| and |v2| by at least 60%, but the center point
1161   // of |touch_rect| is closer to the center point of |v2|.
1162   touch_rect.SetRect(20, 20, 400, 100);
1163   result_view = root_view->GetEventHandlerForRect(touch_rect);
1164   EXPECT_EQ(v2, result_view);
1165   result_view = NULL;
1166
1167   // Covers both |v1| and |v2| by at least 60%, but the center point
1168   // of |touch_rect| is closer to the center point of |v1|.
1169   touch_rect.SetRect(-700, -15, 1050, 110);
1170   result_view = root_view->GetEventHandlerForRect(touch_rect);
1171   EXPECT_EQ(v1, result_view);
1172   result_view = NULL;
1173
1174   // A mouse click within |v1| will target |v1|.
1175   touch_rect.SetRect(15, 15, 1, 1);
1176   result_view = root_view->GetEventHandlerForRect(touch_rect);
1177   EXPECT_EQ(v1, result_view);
1178   result_view = NULL;
1179
1180   // Intersects |v3| and |v31| by at least 60% and the center point
1181   // of |touch_rect| is closer to the center point of |v31|.
1182   touch_rect.SetRect(0, 200, 110, 100);
1183   result_view = root_view->GetEventHandlerForRect(touch_rect);
1184   EXPECT_EQ(v31, result_view);
1185   result_view = NULL;
1186
1187   // Intersects |v3| and |v31|, but neither by at least 60%. The
1188   // center point of |touch_rect| lies within |v31|.
1189   touch_rect.SetRect(80, 280, 15, 15);
1190   result_view = root_view->GetEventHandlerForRect(touch_rect);
1191   EXPECT_EQ(v31, result_view);
1192   result_view = NULL;
1193
1194   // Covers |v3|, |v31|, and |v32| all by at least 60%, and the
1195   // center point of |touch_rect| is closest to the center point
1196   // of |v32|.
1197   touch_rect.SetRect(0, 200, 200, 100);
1198   result_view = root_view->GetEventHandlerForRect(touch_rect);
1199   EXPECT_EQ(v32, result_view);
1200   result_view = NULL;
1201
1202   // Intersects all of |v3|, |v31|, and |v32|, but only covers
1203   // |v31| and |v32| by at least 60%. The center point of
1204   // |touch_rect| is closest to the center point of |v32|.
1205   touch_rect.SetRect(30, 225, 180, 115);
1206   result_view = root_view->GetEventHandlerForRect(touch_rect);
1207   EXPECT_EQ(v32, result_view);
1208   result_view = NULL;
1209
1210   // A mouse click at the corner of |v3| will target |v3|.
1211   touch_rect.SetRect(0, 200, 1, 1);
1212   result_view = root_view->GetEventHandlerForRect(touch_rect);
1213   EXPECT_EQ(v3, result_view);
1214   result_view = NULL;
1215
1216   // A mouse click within |v32| will target |v32|.
1217   touch_rect.SetRect(112, 211, 1, 1);
1218   result_view = root_view->GetEventHandlerForRect(touch_rect);
1219   EXPECT_EQ(v32, result_view);
1220   result_view = NULL;
1221
1222   // Covers all of |v4|, |v41|, and |v411| by at least 60%.
1223   // The center point of |touch_rect| is equally close to
1224   // the center points of |v4| and |v41|.
1225   touch_rect.SetRect(310, 210, 80, 80);
1226   result_view = root_view->GetEventHandlerForRect(touch_rect);
1227   EXPECT_EQ(v41, result_view);
1228   result_view = NULL;
1229
1230   // Intersects all of |v4|, |v41|, and |v411| but only covers
1231   // |v411| by at least 60%.
1232   touch_rect.SetRect(370, 275, 7, 5);
1233   result_view = root_view->GetEventHandlerForRect(touch_rect);
1234   EXPECT_EQ(v411, result_view);
1235   result_view = NULL;
1236
1237   // Intersects |v4| and |v41| but covers neither by at least 60%.
1238   // The center point of |touch_rect| is equally close to the center
1239   // points of |v4| and |v41|.
1240   touch_rect.SetRect(345, 245, 7, 7);
1241   result_view = root_view->GetEventHandlerForRect(touch_rect);
1242   EXPECT_EQ(v41, result_view);
1243   result_view = NULL;
1244
1245   // Intersects all of |v4|, |v41|, and |v411| and covers none of
1246   // them by at least 60%. The center point of |touch_rect| lies
1247   // within |v411|.
1248   touch_rect.SetRect(368, 272, 4, 6);
1249   result_view = root_view->GetEventHandlerForRect(touch_rect);
1250   EXPECT_EQ(v411, result_view);
1251   result_view = NULL;
1252
1253   // Intersects all of |v4|, |v41|, and |v411| and covers none of
1254   // them by at least 60%. The center point of |touch_rect| lies
1255   // within |v41|.
1256   touch_rect.SetRect(365, 270, 7, 7);
1257   result_view = root_view->GetEventHandlerForRect(touch_rect);
1258   EXPECT_EQ(v41, result_view);
1259   result_view = NULL;
1260
1261   // Intersects all of |v4|, |v41|, and |v411| and covers none of
1262   // them by at least 60%. The center point of |touch_rect| lies
1263   // within |v4|.
1264   touch_rect.SetRect(205, 275, 200, 2);
1265   result_view = root_view->GetEventHandlerForRect(touch_rect);
1266   EXPECT_EQ(v4, result_view);
1267   result_view = NULL;
1268
1269   // Intersects all of |v4|, |v41|, and |v411| but only covers
1270   // |v41| by at least 60%.
1271   touch_rect.SetRect(310, 210, 61, 66);
1272   result_view = root_view->GetEventHandlerForRect(touch_rect);
1273   EXPECT_EQ(v41, result_view);
1274   result_view = NULL;
1275
1276   // A mouse click within |v411| will target |v411|.
1277   touch_rect.SetRect(372, 275, 1, 1);
1278   result_view = root_view->GetEventHandlerForRect(touch_rect);
1279   EXPECT_EQ(v411, result_view);
1280   result_view = NULL;
1281
1282   // A mouse click within |v41| will target |v41|.
1283   touch_rect.SetRect(350, 215, 1, 1);
1284   result_view = root_view->GetEventHandlerForRect(touch_rect);
1285   EXPECT_EQ(v41, result_view);
1286   result_view = NULL;
1287
1288   // Covers |v3|, |v4|, and all of their descendants by at
1289   // least 60%. The center point of |touch_rect| is closest
1290   // to the center point of |v32|.
1291   touch_rect.SetRect(0, 200, 400, 100);
1292   result_view = root_view->GetEventHandlerForRect(touch_rect);
1293   EXPECT_EQ(v32, result_view);
1294   result_view = NULL;
1295
1296   // Intersects all of |v2|, |v3|, |v32|, |v4|, |v41|, and |v411|.
1297   // Covers |v2|, |v32|, |v4|, |v41|, and |v411| by at least 60%.
1298   // The center point of |touch_rect| is closest to the center
1299   // point of |root_view|.
1300   touch_rect.SetRect(110, 15, 375, 450);
1301   result_view = root_view->GetEventHandlerForRect(touch_rect);
1302   EXPECT_EQ(root_view, result_view);
1303   result_view = NULL;
1304
1305   // Covers all views (except |v5| and |v51|) by at least 60%. The
1306   // center point of |touch_rect| is equally close to the center
1307   // points of |v2| and |v32|. One is not a descendant of the other,
1308   // so in this case the view selected is arbitrary (i.e.,
1309   // it depends only on the ordering of nodes in the views
1310   // hierarchy).
1311   touch_rect.SetRect(0, 0, 400, 300);
1312   result_view = root_view->GetEventHandlerForRect(touch_rect);
1313   EXPECT_EQ(v32, result_view);
1314   result_view = NULL;
1315
1316   // Covers |v5| and |v51| by at least 60%, and the center point of
1317   // the touch is located within both views. Since both views share
1318   // the same center point, the child view should be selected.
1319   touch_rect.SetRect(440, 190, 40, 40);
1320   result_view = root_view->GetEventHandlerForRect(touch_rect);
1321   EXPECT_EQ(v51, result_view);
1322   result_view = NULL;
1323
1324   // Covers |v5| and |v51| by at least 60%, but the center point of
1325   // the touch is not located within either view. Since both views
1326   // share the same center point, the child view should be selected.
1327   touch_rect.SetRect(455, 187, 60, 60);
1328   result_view = root_view->GetEventHandlerForRect(touch_rect);
1329   EXPECT_EQ(v51, result_view);
1330   result_view = NULL;
1331
1332   // Covers neither |v5| nor |v51| by at least 60%, but the center
1333   // of the touch is located within |v51|.
1334   touch_rect.SetRect(450, 197, 10, 10);
1335   result_view = root_view->GetEventHandlerForRect(touch_rect);
1336   EXPECT_EQ(v51, result_view);
1337   result_view = NULL;
1338
1339   // Covers neither |v5| nor |v51| by at least 60% but intersects both.
1340   // The center point is located outside of both views.
1341   touch_rect.SetRect(433, 180, 24, 24);
1342   result_view = root_view->GetEventHandlerForRect(touch_rect);
1343   EXPECT_EQ(root_view, result_view);
1344   result_view = NULL;
1345
1346   // Only intersects |v5| but does not cover it by at least 60%. The
1347   // center point of the touch region is located within |v5|.
1348   touch_rect.SetRect(449, 196, 3, 3);
1349   result_view = root_view->GetEventHandlerForRect(touch_rect);
1350   EXPECT_EQ(v5, result_view);
1351   result_view = NULL;
1352
1353   // A mouse click within |v5| (but not |v51|) should target |v5|.
1354   touch_rect.SetRect(462, 199, 1, 1);
1355   result_view = root_view->GetEventHandlerForRect(touch_rect);
1356   EXPECT_EQ(v5, result_view);
1357   result_view = NULL;
1358
1359   // A mouse click |v5| and |v51| should target the child view.
1360   touch_rect.SetRect(452, 226, 1, 1);
1361   result_view = root_view->GetEventHandlerForRect(touch_rect);
1362   EXPECT_EQ(v51, result_view);
1363   result_view = NULL;
1364
1365   // A mouse click on the center of |v5| and |v51| should target
1366   // the child view.
1367   touch_rect.SetRect(465, 215, 1, 1);
1368   result_view = root_view->GetEventHandlerForRect(touch_rect);
1369   EXPECT_EQ(v51, result_view);
1370   result_view = NULL;
1371
1372   widget->CloseNow();
1373 }
1374
1375 TEST_F(ViewTest, NotifyEnterExitOnChild) {
1376   Widget* widget = new Widget;
1377   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1378   widget->Init(params);
1379   View* root_view = widget->GetRootView();
1380   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
1381
1382   // Have this hierarchy of views (the coords here are in root coord):
1383   // v1 (0, 0, 100, 100)
1384   //  - v11 (0, 0, 20, 30)
1385   //    - v111 (5, 5, 5, 15)
1386   //  - v12 (50, 10, 30, 90)
1387   //    - v121 (60, 20, 10, 10)
1388   // v2 (105, 0, 100, 100)
1389   //  - v21 (120, 10, 50, 20)
1390
1391   TestView* v1 = new TestView;
1392   v1->SetBounds(0, 0, 100, 100);
1393   root_view->AddChildView(v1);
1394   v1->set_notify_enter_exit_on_child(true);
1395
1396   TestView* v11 = new TestView;
1397   v11->SetBounds(0, 0, 20, 30);
1398   v1->AddChildView(v11);
1399
1400   TestView* v111 = new TestView;
1401   v111->SetBounds(5, 5, 5, 15);
1402   v11->AddChildView(v111);
1403
1404   TestView* v12 = new TestView;
1405   v12->SetBounds(50, 10, 30, 90);
1406   v1->AddChildView(v12);
1407
1408   TestView* v121 = new TestView;
1409   v121->SetBounds(10, 10, 10, 10);
1410   v12->AddChildView(v121);
1411
1412   TestView* v2 = new TestView;
1413   v2->SetBounds(105, 0, 100, 100);
1414   root_view->AddChildView(v2);
1415
1416   TestView* v21 = new TestView;
1417   v21->SetBounds(15, 10, 50, 20);
1418   v2->AddChildView(v21);
1419
1420   v1->Reset();
1421   v11->Reset();
1422   v111->Reset();
1423   v12->Reset();
1424   v121->Reset();
1425   v2->Reset();
1426   v21->Reset();
1427
1428   // Move the mouse in v111.
1429   gfx::Point p1(6, 6);
1430   ui::MouseEvent move1(ui::ET_MOUSE_MOVED, p1, p1, 0, 0);
1431   root_view->OnMouseMoved(move1);
1432   EXPECT_TRUE(v111->received_mouse_enter_);
1433   EXPECT_FALSE(v11->last_mouse_event_type_);
1434   EXPECT_TRUE(v1->received_mouse_enter_);
1435
1436   v111->Reset();
1437   v1->Reset();
1438
1439   // Now, move into v121.
1440   gfx::Point p2(65, 21);
1441   ui::MouseEvent move2(ui::ET_MOUSE_MOVED, p2, p2, 0, 0);
1442   root_view->OnMouseMoved(move2);
1443   EXPECT_TRUE(v111->received_mouse_exit_);
1444   EXPECT_TRUE(v121->received_mouse_enter_);
1445   EXPECT_FALSE(v1->last_mouse_event_type_);
1446
1447   v111->Reset();
1448   v121->Reset();
1449
1450   // Now, move into v11.
1451   gfx::Point p3(1, 1);
1452   ui::MouseEvent move3(ui::ET_MOUSE_MOVED, p3, p3, 0, 0);
1453   root_view->OnMouseMoved(move3);
1454   EXPECT_TRUE(v121->received_mouse_exit_);
1455   EXPECT_TRUE(v11->received_mouse_enter_);
1456   EXPECT_FALSE(v1->last_mouse_event_type_);
1457
1458   v121->Reset();
1459   v11->Reset();
1460
1461   // Move to v21.
1462   gfx::Point p4(121, 15);
1463   ui::MouseEvent move4(ui::ET_MOUSE_MOVED, p4, p4, 0, 0);
1464   root_view->OnMouseMoved(move4);
1465   EXPECT_TRUE(v21->received_mouse_enter_);
1466   EXPECT_FALSE(v2->last_mouse_event_type_);
1467   EXPECT_TRUE(v11->received_mouse_exit_);
1468   EXPECT_TRUE(v1->received_mouse_exit_);
1469
1470   v21->Reset();
1471   v11->Reset();
1472   v1->Reset();
1473
1474   // Move to v1.
1475   gfx::Point p5(21, 0);
1476   ui::MouseEvent move5(ui::ET_MOUSE_MOVED, p5, p5, 0, 0);
1477   root_view->OnMouseMoved(move5);
1478   EXPECT_TRUE(v21->received_mouse_exit_);
1479   EXPECT_TRUE(v1->received_mouse_enter_);
1480
1481   v21->Reset();
1482   v1->Reset();
1483
1484   // Now, move into v11.
1485   gfx::Point p6(15, 15);
1486   ui::MouseEvent mouse6(ui::ET_MOUSE_MOVED, p6, p6, 0, 0);
1487   root_view->OnMouseMoved(mouse6);
1488   EXPECT_TRUE(v11->received_mouse_enter_);
1489   EXPECT_FALSE(v1->last_mouse_event_type_);
1490
1491   v11->Reset();
1492   v1->Reset();
1493
1494   // Move back into v1. Although |v1| had already received an ENTER for mouse6,
1495   // and the mouse remains inside |v1| the whole time, it receives another ENTER
1496   // when the mouse leaves v11.
1497   gfx::Point p7(21, 0);
1498   ui::MouseEvent mouse7(ui::ET_MOUSE_MOVED, p7, p7, 0, 0);
1499   root_view->OnMouseMoved(mouse7);
1500   EXPECT_TRUE(v11->received_mouse_exit_);
1501   EXPECT_FALSE(v1->received_mouse_enter_);
1502
1503   widget->CloseNow();
1504 }
1505
1506 TEST_F(ViewTest, Textfield) {
1507   const base::string16 kText = ASCIIToUTF16(
1508       "Reality is that which, when you stop believing it, doesn't go away.");
1509   const base::string16 kExtraText = ASCIIToUTF16("Pretty deep, Philip!");
1510   const base::string16 kEmptyString;
1511
1512   Widget* widget = new Widget;
1513   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1514   params.bounds = gfx::Rect(0, 0, 100, 100);
1515   widget->Init(params);
1516   View* root_view = widget->GetRootView();
1517
1518   Textfield* textfield = new Textfield();
1519   root_view->AddChildView(textfield);
1520
1521   // Test setting, appending text.
1522   textfield->SetText(kText);
1523   EXPECT_EQ(kText, textfield->text());
1524   textfield->AppendText(kExtraText);
1525   EXPECT_EQ(kText + kExtraText, textfield->text());
1526   textfield->SetText(base::string16());
1527   EXPECT_EQ(kEmptyString, textfield->text());
1528
1529   // Test selection related methods.
1530   textfield->SetText(kText);
1531   EXPECT_EQ(kEmptyString, textfield->GetSelectedText());
1532   textfield->SelectAll(false);
1533   EXPECT_EQ(kText, textfield->text());
1534   textfield->ClearSelection();
1535   EXPECT_EQ(kEmptyString, textfield->GetSelectedText());
1536
1537   widget->CloseNow();
1538 }
1539
1540 // Tests that the Textfield view respond appropiately to cut/copy/paste.
1541 TEST_F(ViewTest, TextfieldCutCopyPaste) {
1542   const base::string16 kNormalText = ASCIIToUTF16("Normal");
1543   const base::string16 kReadOnlyText = ASCIIToUTF16("Read only");
1544   const base::string16 kPasswordText =
1545       ASCIIToUTF16("Password! ** Secret stuff **");
1546
1547   ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
1548
1549   Widget* widget = new Widget;
1550   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1551   params.bounds = gfx::Rect(0, 0, 100, 100);
1552   widget->Init(params);
1553   View* root_view = widget->GetRootView();
1554
1555   Textfield* normal = new Textfield();
1556   Textfield* read_only = new Textfield();
1557   read_only->SetReadOnly(true);
1558   Textfield* password = new Textfield();
1559   password->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
1560
1561   root_view->AddChildView(normal);
1562   root_view->AddChildView(read_only);
1563   root_view->AddChildView(password);
1564
1565   normal->SetText(kNormalText);
1566   read_only->SetText(kReadOnlyText);
1567   password->SetText(kPasswordText);
1568
1569   //
1570   // Test cut.
1571   //
1572
1573   normal->SelectAll(false);
1574   normal->ExecuteCommand(IDS_APP_CUT);
1575   base::string16 result;
1576   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1577   EXPECT_EQ(kNormalText, result);
1578   normal->SetText(kNormalText);  // Let's revert to the original content.
1579
1580   read_only->SelectAll(false);
1581   read_only->ExecuteCommand(IDS_APP_CUT);
1582   result.clear();
1583   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1584   // Cut should have failed, so the clipboard content should not have changed.
1585   EXPECT_EQ(kNormalText, result);
1586
1587   password->SelectAll(false);
1588   password->ExecuteCommand(IDS_APP_CUT);
1589   result.clear();
1590   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1591   // Cut should have failed, so the clipboard content should not have changed.
1592   EXPECT_EQ(kNormalText, result);
1593
1594   //
1595   // Test copy.
1596   //
1597
1598   // Start with |read_only| to observe a change in clipboard text.
1599   read_only->SelectAll(false);
1600   read_only->ExecuteCommand(IDS_APP_COPY);
1601   result.clear();
1602   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1603   EXPECT_EQ(kReadOnlyText, result);
1604
1605   normal->SelectAll(false);
1606   normal->ExecuteCommand(IDS_APP_COPY);
1607   result.clear();
1608   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1609   EXPECT_EQ(kNormalText, result);
1610
1611   password->SelectAll(false);
1612   password->ExecuteCommand(IDS_APP_COPY);
1613   result.clear();
1614   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1615   // Text cannot be copied from an obscured field; the clipboard won't change.
1616   EXPECT_EQ(kNormalText, result);
1617
1618   //
1619   // Test paste.
1620   //
1621
1622   // Attempting to paste kNormalText in a read-only text-field should fail.
1623   read_only->SelectAll(false);
1624   read_only->ExecuteCommand(IDS_APP_PASTE);
1625   EXPECT_EQ(kReadOnlyText, read_only->text());
1626
1627   password->SelectAll(false);
1628   password->ExecuteCommand(IDS_APP_PASTE);
1629   EXPECT_EQ(kNormalText, password->text());
1630
1631   // Copy from |read_only| to observe a change in the normal textfield text.
1632   read_only->SelectAll(false);
1633   read_only->ExecuteCommand(IDS_APP_COPY);
1634   normal->SelectAll(false);
1635   normal->ExecuteCommand(IDS_APP_PASTE);
1636   EXPECT_EQ(kReadOnlyText, normal->text());
1637   widget->CloseNow();
1638 }
1639
1640 ////////////////////////////////////////////////////////////////////////////////
1641 // Accelerators
1642 ////////////////////////////////////////////////////////////////////////////////
1643 bool TestView::AcceleratorPressed(const ui::Accelerator& accelerator) {
1644   accelerator_count_map_[accelerator]++;
1645   return true;
1646 }
1647
1648 #if defined(OS_WIN) && !defined(USE_AURA)
1649 TEST_F(ViewTest, ActivateAccelerator) {
1650   // Register a keyboard accelerator before the view is added to a window.
1651   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
1652   TestView* view = new TestView();
1653   view->Reset();
1654   view->AddAccelerator(return_accelerator);
1655   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
1656
1657   // Create a window and add the view as its child.
1658   scoped_ptr<Widget> widget(new Widget);
1659   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1660   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1661   params.bounds = gfx::Rect(0, 0, 100, 100);
1662   widget->Init(params);
1663   View* root = widget->GetRootView();
1664   root->AddChildView(view);
1665   widget->Show();
1666
1667   // Get the focus manager.
1668   FocusManager* focus_manager = widget->GetFocusManager();
1669   ASSERT_TRUE(focus_manager);
1670
1671   // Hit the return key and see if it takes effect.
1672   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
1673   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
1674
1675   // Hit the escape key. Nothing should happen.
1676   ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
1677   EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
1678   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
1679   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 0);
1680
1681   // Now register the escape key and hit it again.
1682   view->AddAccelerator(escape_accelerator);
1683   EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
1684   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
1685   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
1686
1687   // Remove the return key accelerator.
1688   view->RemoveAccelerator(return_accelerator);
1689   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
1690   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
1691   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
1692
1693   // Add it again. Hit the return key and the escape key.
1694   view->AddAccelerator(return_accelerator);
1695   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
1696   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
1697   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
1698   EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
1699   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
1700   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
1701
1702   // Remove all the accelerators.
1703   view->ResetAccelerators();
1704   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
1705   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
1706   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
1707   EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
1708   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
1709   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
1710
1711   widget->CloseNow();
1712 }
1713 #endif
1714
1715 #if defined(OS_WIN) && !defined(USE_AURA)
1716 TEST_F(ViewTest, HiddenViewWithAccelerator) {
1717   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
1718   TestView* view = new TestView();
1719   view->Reset();
1720   view->AddAccelerator(return_accelerator);
1721   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
1722
1723   scoped_ptr<Widget> widget(new Widget);
1724   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1725   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1726   params.bounds = gfx::Rect(0, 0, 100, 100);
1727   widget->Init(params);
1728   View* root = widget->GetRootView();
1729   root->AddChildView(view);
1730   widget->Show();
1731
1732   FocusManager* focus_manager = widget->GetFocusManager();
1733   ASSERT_TRUE(focus_manager);
1734
1735   view->SetVisible(false);
1736   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
1737
1738   view->SetVisible(true);
1739   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
1740
1741   widget->CloseNow();
1742 }
1743 #endif
1744
1745 #if defined(OS_WIN) && !defined(USE_AURA)
1746 TEST_F(ViewTest, ViewInHiddenWidgetWithAccelerator) {
1747   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
1748   TestView* view = new TestView();
1749   view->Reset();
1750   view->AddAccelerator(return_accelerator);
1751   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
1752
1753   scoped_ptr<Widget> widget(new Widget);
1754   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1755   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1756   params.bounds = gfx::Rect(0, 0, 100, 100);
1757   widget->Init(params);
1758   View* root = widget->GetRootView();
1759   root->AddChildView(view);
1760
1761   FocusManager* focus_manager = widget->GetFocusManager();
1762   ASSERT_TRUE(focus_manager);
1763
1764   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
1765   EXPECT_EQ(0, view->accelerator_count_map_[return_accelerator]);
1766
1767   widget->Show();
1768   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
1769   EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]);
1770
1771   widget->Hide();
1772   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
1773   EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]);
1774
1775   widget->CloseNow();
1776 }
1777 #endif
1778
1779 #if defined(OS_WIN) && !defined(USE_AURA)
1780 ////////////////////////////////////////////////////////////////////////////////
1781 // Mouse-wheel message rerouting
1782 ////////////////////////////////////////////////////////////////////////////////
1783 class ScrollableTestView : public View {
1784  public:
1785   ScrollableTestView() { }
1786
1787   virtual gfx::Size GetPreferredSize() {
1788     return gfx::Size(100, 10000);
1789   }
1790
1791   virtual void Layout() {
1792     SizeToPreferredSize();
1793   }
1794 };
1795
1796 class TestViewWithControls : public View {
1797  public:
1798   TestViewWithControls() {
1799     text_field_ = new Textfield();
1800     AddChildView(text_field_);
1801   }
1802
1803   Textfield* text_field_;
1804 };
1805
1806 class SimpleWidgetDelegate : public WidgetDelegate {
1807  public:
1808   explicit SimpleWidgetDelegate(View* contents) : contents_(contents) {  }
1809
1810   virtual void DeleteDelegate() { delete this; }
1811
1812   virtual View* GetContentsView() { return contents_; }
1813
1814   virtual Widget* GetWidget() { return contents_->GetWidget(); }
1815   virtual const Widget* GetWidget() const { return contents_->GetWidget(); }
1816
1817  private:
1818   View* contents_;
1819 };
1820
1821 // Tests that the mouse-wheel messages are correctly rerouted to the window
1822 // under the mouse.
1823 // TODO(jcampan): http://crbug.com/10572 Disabled as it fails on the Vista build
1824 //                bot.
1825 // Note that this fails for a variety of reasons:
1826 // - focused view is apparently reset across window activations and never
1827 //   properly restored
1828 // - this test depends on you not having any other window visible open under the
1829 //   area that it opens the test windows. --beng
1830 TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) {
1831   TestViewWithControls* view_with_controls = new TestViewWithControls();
1832   Widget* window1 = Widget::CreateWindowWithBounds(
1833       new SimpleWidgetDelegate(view_with_controls),
1834       gfx::Rect(0, 0, 100, 100));
1835   window1->Show();
1836   ScrollView* scroll_view = new ScrollView();
1837   scroll_view->SetContents(new ScrollableTestView());
1838   Widget* window2 = Widget::CreateWindowWithBounds(
1839       new SimpleWidgetDelegate(scroll_view),
1840       gfx::Rect(200, 200, 100, 100));
1841   window2->Show();
1842   EXPECT_EQ(0, scroll_view->GetVisibleRect().y());
1843
1844   // Make the window1 active, as this is what it would be in real-world.
1845   window1->Activate();
1846
1847   // Let's send a mouse-wheel message to the different controls and check that
1848   // it is rerouted to the window under the mouse (effectively scrolling the
1849   // scroll-view).
1850
1851   // First to the Window's HWND.
1852   ::SendMessage(view_with_controls->GetWidget()->GetNativeView(),
1853                 WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(250, 250));
1854   EXPECT_EQ(20, scroll_view->GetVisibleRect().y());
1855
1856   window1->CloseNow();
1857   window2->CloseNow();
1858 }
1859 #endif
1860
1861 ////////////////////////////////////////////////////////////////////////////////
1862 // Native view hierachy
1863 ////////////////////////////////////////////////////////////////////////////////
1864 class ToplevelWidgetObserverView : public View {
1865  public:
1866   ToplevelWidgetObserverView() : toplevel_(NULL) {
1867   }
1868   virtual ~ToplevelWidgetObserverView() {
1869   }
1870
1871   // View overrides:
1872   virtual void ViewHierarchyChanged(
1873       const ViewHierarchyChangedDetails& details) OVERRIDE {
1874     if (details.is_add) {
1875       toplevel_ = GetWidget() ? GetWidget()->GetTopLevelWidget() : NULL;
1876     } else {
1877       toplevel_ = NULL;
1878     }
1879   }
1880   virtual void NativeViewHierarchyChanged() OVERRIDE {
1881     toplevel_ = GetWidget() ? GetWidget()->GetTopLevelWidget() : NULL;
1882   }
1883
1884   Widget* toplevel() { return toplevel_; }
1885
1886  private:
1887   Widget* toplevel_;
1888
1889   DISALLOW_COPY_AND_ASSIGN(ToplevelWidgetObserverView);
1890 };
1891
1892 // Test that a view can track the current top level widget by overriding
1893 // View::ViewHierarchyChanged() and View::NativeViewHierarchyChanged().
1894 TEST_F(ViewTest, NativeViewHierarchyChanged) {
1895   scoped_ptr<Widget> toplevel1(new Widget);
1896   Widget::InitParams toplevel1_params =
1897       CreateParams(Widget::InitParams::TYPE_POPUP);
1898   toplevel1_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1899   toplevel1->Init(toplevel1_params);
1900
1901   scoped_ptr<Widget> toplevel2(new Widget);
1902   Widget::InitParams toplevel2_params =
1903       CreateParams(Widget::InitParams::TYPE_POPUP);
1904   toplevel2_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1905   toplevel2->Init(toplevel2_params);
1906
1907   Widget* child = new Widget;
1908   Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
1909   child_params.parent = toplevel1->GetNativeView();
1910   child->Init(child_params);
1911
1912   ToplevelWidgetObserverView* observer_view =
1913       new ToplevelWidgetObserverView();
1914   EXPECT_EQ(NULL, observer_view->toplevel());
1915
1916   child->SetContentsView(observer_view);
1917   EXPECT_EQ(toplevel1, observer_view->toplevel());
1918
1919   Widget::ReparentNativeView(child->GetNativeView(),
1920                              toplevel2->GetNativeView());
1921   EXPECT_EQ(toplevel2, observer_view->toplevel());
1922
1923   observer_view->parent()->RemoveChildView(observer_view);
1924   EXPECT_EQ(NULL, observer_view->toplevel());
1925
1926   // Make |observer_view| |child|'s contents view again so that it gets deleted
1927   // with the widget.
1928   child->SetContentsView(observer_view);
1929 }
1930
1931 ////////////////////////////////////////////////////////////////////////////////
1932 // Transformations
1933 ////////////////////////////////////////////////////////////////////////////////
1934
1935 class TransformPaintView : public TestView {
1936  public:
1937   TransformPaintView() {}
1938   virtual ~TransformPaintView() {}
1939
1940   void ClearScheduledPaintRect() {
1941     scheduled_paint_rect_ = gfx::Rect();
1942   }
1943
1944   gfx::Rect scheduled_paint_rect() const { return scheduled_paint_rect_; }
1945
1946   // Overridden from View:
1947   virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE {
1948     gfx::Rect xrect = ConvertRectToParent(rect);
1949     scheduled_paint_rect_.Union(xrect);
1950   }
1951
1952  private:
1953   gfx::Rect scheduled_paint_rect_;
1954
1955   DISALLOW_COPY_AND_ASSIGN(TransformPaintView);
1956 };
1957
1958 TEST_F(ViewTest, TransformPaint) {
1959   TransformPaintView* v1 = new TransformPaintView();
1960   v1->SetBoundsRect(gfx::Rect(0, 0, 500, 300));
1961
1962   TestView* v2 = new TestView();
1963   v2->SetBoundsRect(gfx::Rect(100, 100, 200, 100));
1964
1965   Widget* widget = new Widget;
1966   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1967   params.bounds = gfx::Rect(50, 50, 650, 650);
1968   widget->Init(params);
1969   widget->Show();
1970   View* root = widget->GetRootView();
1971
1972   root->AddChildView(v1);
1973   v1->AddChildView(v2);
1974
1975   // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
1976   v1->ClearScheduledPaintRect();
1977   v2->SchedulePaint();
1978
1979   EXPECT_EQ(gfx::Rect(100, 100, 200, 100), v1->scheduled_paint_rect());
1980
1981   // Rotate |v1| counter-clockwise.
1982   gfx::Transform transform;
1983   RotateCounterclockwise(&transform);
1984   transform.matrix().set(1, 3, 500.0);
1985   v1->SetTransform(transform);
1986
1987   // |v2| now occupies (100, 200) to (200, 400) in |root|.
1988
1989   v1->ClearScheduledPaintRect();
1990   v2->SchedulePaint();
1991
1992   EXPECT_EQ(gfx::Rect(100, 200, 100, 200), v1->scheduled_paint_rect());
1993
1994   widget->CloseNow();
1995 }
1996
1997 TEST_F(ViewTest, TransformEvent) {
1998   TestView* v1 = new TestView();
1999   v1->SetBoundsRect(gfx::Rect(0, 0, 500, 300));
2000
2001   TestView* v2 = new TestView();
2002   v2->SetBoundsRect(gfx::Rect(100, 100, 200, 100));
2003
2004   Widget* widget = new Widget;
2005   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2006   params.bounds = gfx::Rect(50, 50, 650, 650);
2007   widget->Init(params);
2008   View* root = widget->GetRootView();
2009
2010   root->AddChildView(v1);
2011   v1->AddChildView(v2);
2012
2013   // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
2014
2015   // Rotate |v1| counter-clockwise.
2016   gfx::Transform transform(v1->GetTransform());
2017   RotateCounterclockwise(&transform);
2018   transform.matrix().set(1, 3, 500.0);
2019   v1->SetTransform(transform);
2020
2021   // |v2| now occupies (100, 200) to (200, 400) in |root|.
2022   v1->Reset();
2023   v2->Reset();
2024
2025   gfx::Point p1(110, 210);
2026   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
2027                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
2028   root->OnMousePressed(pressed);
2029   EXPECT_EQ(0, v1->last_mouse_event_type_);
2030   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
2031   EXPECT_EQ(190, v2->location_.x());
2032   EXPECT_EQ(10, v2->location_.y());
2033
2034   ui::MouseEvent released(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), 0,
2035                           0);
2036   root->OnMouseReleased(released);
2037
2038   // Now rotate |v2| inside |v1| clockwise.
2039   transform = v2->GetTransform();
2040   RotateClockwise(&transform);
2041   transform.matrix().set(0, 3, 100.f);
2042   v2->SetTransform(transform);
2043
2044   // Now, |v2| occupies (100, 100) to (200, 300) in |v1|, and (100, 300) to
2045   // (300, 400) in |root|.
2046
2047   v1->Reset();
2048   v2->Reset();
2049
2050   gfx::Point point2(110, 320);
2051   ui::MouseEvent p2(ui::ET_MOUSE_PRESSED, point2, point2,
2052                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
2053   root->OnMousePressed(p2);
2054   EXPECT_EQ(0, v1->last_mouse_event_type_);
2055   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
2056   EXPECT_EQ(10, v2->location_.x());
2057   EXPECT_EQ(20, v2->location_.y());
2058
2059   root->OnMouseReleased(released);
2060
2061   v1->SetTransform(gfx::Transform());
2062   v2->SetTransform(gfx::Transform());
2063
2064   TestView* v3 = new TestView();
2065   v3->SetBoundsRect(gfx::Rect(10, 10, 20, 30));
2066   v2->AddChildView(v3);
2067
2068   // Rotate |v3| clockwise with respect to |v2|.
2069   transform = v1->GetTransform();
2070   RotateClockwise(&transform);
2071   transform.matrix().set(0, 3, 30.f);
2072   v3->SetTransform(transform);
2073
2074   // Scale |v2| with respect to |v1| along both axis.
2075   transform = v2->GetTransform();
2076   transform.matrix().set(0, 0, 0.8f);
2077   transform.matrix().set(1, 1, 0.5f);
2078   v2->SetTransform(transform);
2079
2080   // |v3| occupies (108, 105) to (132, 115) in |root|.
2081
2082   v1->Reset();
2083   v2->Reset();
2084   v3->Reset();
2085
2086   gfx::Point point(112, 110);
2087   ui::MouseEvent p3(ui::ET_MOUSE_PRESSED, point, point,
2088                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
2089   root->OnMousePressed(p3);
2090
2091   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
2092   EXPECT_EQ(10, v3->location_.x());
2093   EXPECT_EQ(25, v3->location_.y());
2094
2095   root->OnMouseReleased(released);
2096
2097   v1->SetTransform(gfx::Transform());
2098   v2->SetTransform(gfx::Transform());
2099   v3->SetTransform(gfx::Transform());
2100
2101   v1->Reset();
2102   v2->Reset();
2103   v3->Reset();
2104
2105   // Rotate |v3| clockwise with respect to |v2|, and scale it along both axis.
2106   transform = v3->GetTransform();
2107   RotateClockwise(&transform);
2108   transform.matrix().set(0, 3, 30.f);
2109   // Rotation sets some scaling transformation. Using SetScale would overwrite
2110   // that and pollute the rotation. So combine the scaling with the existing
2111   // transforamtion.
2112   gfx::Transform scale;
2113   scale.Scale(0.8f, 0.5f);
2114   transform.ConcatTransform(scale);
2115   v3->SetTransform(transform);
2116
2117   // Translate |v2| with respect to |v1|.
2118   transform = v2->GetTransform();
2119   transform.matrix().set(0, 3, 10.f);
2120   transform.matrix().set(1, 3, 10.f);
2121   v2->SetTransform(transform);
2122
2123   // |v3| now occupies (120, 120) to (144, 130) in |root|.
2124
2125   gfx::Point point3(124, 125);
2126   ui::MouseEvent p4(ui::ET_MOUSE_PRESSED, point3, point3,
2127                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
2128   root->OnMousePressed(p4);
2129
2130   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
2131   EXPECT_EQ(10, v3->location_.x());
2132   EXPECT_EQ(25, v3->location_.y());
2133
2134   root->OnMouseReleased(released);
2135
2136   widget->CloseNow();
2137 }
2138
2139 TEST_F(ViewTest, TransformVisibleBound) {
2140   gfx::Rect viewport_bounds(0, 0, 100, 100);
2141
2142   scoped_ptr<Widget> widget(new Widget);
2143   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2144   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2145   params.bounds = viewport_bounds;
2146   widget->Init(params);
2147   widget->GetRootView()->SetBoundsRect(viewport_bounds);
2148
2149   View* viewport = new View;
2150   widget->SetContentsView(viewport);
2151   View* contents = new View;
2152   viewport->AddChildView(contents);
2153   viewport->SetBoundsRect(viewport_bounds);
2154   contents->SetBoundsRect(gfx::Rect(0, 0, 100, 200));
2155
2156   View* child = new View;
2157   contents->AddChildView(child);
2158   child->SetBoundsRect(gfx::Rect(10, 90, 50, 50));
2159   EXPECT_EQ(gfx::Rect(0, 0, 50, 10), child->GetVisibleBounds());
2160
2161   // Rotate |child| counter-clockwise
2162   gfx::Transform transform;
2163   RotateCounterclockwise(&transform);
2164   transform.matrix().set(1, 3, 50.f);
2165   child->SetTransform(transform);
2166   EXPECT_EQ(gfx::Rect(40, 0, 10, 50), child->GetVisibleBounds());
2167
2168   widget->CloseNow();
2169 }
2170
2171 ////////////////////////////////////////////////////////////////////////////////
2172 // OnVisibleBoundsChanged()
2173
2174 class VisibleBoundsView : public View {
2175  public:
2176   VisibleBoundsView() : received_notification_(false) {}
2177   virtual ~VisibleBoundsView() {}
2178
2179   bool received_notification() const { return received_notification_; }
2180   void set_received_notification(bool received) {
2181     received_notification_ = received;
2182   }
2183
2184  private:
2185   // Overridden from View:
2186   virtual bool NeedsNotificationWhenVisibleBoundsChange() const OVERRIDE {
2187      return true;
2188   }
2189   virtual void OnVisibleBoundsChanged() OVERRIDE {
2190     received_notification_ = true;
2191   }
2192
2193   bool received_notification_;
2194
2195   DISALLOW_COPY_AND_ASSIGN(VisibleBoundsView);
2196 };
2197
2198 TEST_F(ViewTest, OnVisibleBoundsChanged) {
2199   gfx::Rect viewport_bounds(0, 0, 100, 100);
2200
2201   scoped_ptr<Widget> widget(new Widget);
2202   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2203   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2204   params.bounds = viewport_bounds;
2205   widget->Init(params);
2206   widget->GetRootView()->SetBoundsRect(viewport_bounds);
2207
2208   View* viewport = new View;
2209   widget->SetContentsView(viewport);
2210   View* contents = new View;
2211   viewport->AddChildView(contents);
2212   viewport->SetBoundsRect(viewport_bounds);
2213   contents->SetBoundsRect(gfx::Rect(0, 0, 100, 200));
2214
2215   // Create a view that cares about visible bounds notifications, and position
2216   // it just outside the visible bounds of the viewport.
2217   VisibleBoundsView* child = new VisibleBoundsView;
2218   contents->AddChildView(child);
2219   child->SetBoundsRect(gfx::Rect(10, 110, 50, 50));
2220
2221   // The child bound should be fully clipped.
2222   EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
2223
2224   // Now scroll the contents, but not enough to make the child visible.
2225   contents->SetY(contents->y() - 1);
2226
2227   // We should have received the notification since the visible bounds may have
2228   // changed (even though they didn't).
2229   EXPECT_TRUE(child->received_notification());
2230   EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
2231   child->set_received_notification(false);
2232
2233   // Now scroll the contents, this time by enough to make the child visible by
2234   // one pixel.
2235   contents->SetY(contents->y() - 10);
2236   EXPECT_TRUE(child->received_notification());
2237   EXPECT_EQ(1, child->GetVisibleBounds().height());
2238   child->set_received_notification(false);
2239
2240   widget->CloseNow();
2241 }
2242
2243 TEST_F(ViewTest, SetBoundsPaint) {
2244   TestView top_view;
2245   TestView* child_view = new TestView;
2246
2247   top_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
2248   top_view.scheduled_paint_rects_.clear();
2249   child_view->SetBoundsRect(gfx::Rect(10, 10, 20, 20));
2250   top_view.AddChildView(child_view);
2251
2252   top_view.scheduled_paint_rects_.clear();
2253   child_view->SetBoundsRect(gfx::Rect(30, 30, 20, 20));
2254   EXPECT_EQ(2U, top_view.scheduled_paint_rects_.size());
2255
2256   // There should be 2 rects, spanning from (10, 10) to (50, 50).
2257   gfx::Rect paint_rect = top_view.scheduled_paint_rects_[0];
2258   paint_rect.Union(top_view.scheduled_paint_rects_[1]);
2259   EXPECT_EQ(gfx::Rect(10, 10, 40, 40), paint_rect);
2260 }
2261
2262 // Assertions around painting and focus gain/lost.
2263 TEST_F(ViewTest, FocusBlurPaints) {
2264   TestView parent_view;
2265   TestView* child_view1 = new TestView;  // Owned by |parent_view|.
2266
2267   parent_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
2268
2269   child_view1->SetBoundsRect(gfx::Rect(0, 0, 20, 20));
2270   parent_view.AddChildView(child_view1);
2271
2272   parent_view.scheduled_paint_rects_.clear();
2273   child_view1->scheduled_paint_rects_.clear();
2274
2275   // Focus change shouldn't trigger paints.
2276   child_view1->DoFocus();
2277
2278   EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty());
2279   EXPECT_TRUE(child_view1->scheduled_paint_rects_.empty());
2280
2281   child_view1->DoBlur();
2282   EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty());
2283   EXPECT_TRUE(child_view1->scheduled_paint_rects_.empty());
2284 }
2285
2286 // Verifies SetBounds(same bounds) doesn't trigger a SchedulePaint().
2287 TEST_F(ViewTest, SetBoundsSameBoundsDoesntSchedulePaint) {
2288   TestView view;
2289
2290   view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
2291   view.InvalidateLayout();
2292   view.scheduled_paint_rects_.clear();
2293   view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
2294   EXPECT_TRUE(view.scheduled_paint_rects_.empty());
2295 }
2296
2297 // Verifies AddChildView() and RemoveChildView() schedule appropriate paints.
2298 TEST_F(ViewTest, AddAndRemoveSchedulePaints) {
2299   gfx::Rect viewport_bounds(0, 0, 100, 100);
2300
2301   // We have to put the View hierarchy into a Widget or no paints will be
2302   // scheduled.
2303   scoped_ptr<Widget> widget(new Widget);
2304   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2305   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2306   params.bounds = viewport_bounds;
2307   widget->Init(params);
2308   widget->GetRootView()->SetBoundsRect(viewport_bounds);
2309
2310   TestView* parent_view = new TestView;
2311   widget->SetContentsView(parent_view);
2312   parent_view->SetBoundsRect(viewport_bounds);
2313   parent_view->scheduled_paint_rects_.clear();
2314
2315   View* child_view = new View;
2316   child_view->SetBoundsRect(gfx::Rect(0, 0, 20, 20));
2317   parent_view->AddChildView(child_view);
2318   ASSERT_EQ(1U, parent_view->scheduled_paint_rects_.size());
2319   EXPECT_EQ(child_view->bounds(), parent_view->scheduled_paint_rects_.front());
2320
2321   parent_view->scheduled_paint_rects_.clear();
2322   parent_view->RemoveChildView(child_view);
2323   scoped_ptr<View> child_deleter(child_view);
2324   ASSERT_EQ(1U, parent_view->scheduled_paint_rects_.size());
2325   EXPECT_EQ(child_view->bounds(), parent_view->scheduled_paint_rects_.front());
2326
2327   widget->CloseNow();
2328 }
2329
2330 // Tests conversion methods with a transform.
2331 TEST_F(ViewTest, ConversionsWithTransform) {
2332   TestView top_view;
2333
2334   // View hierarchy used to test scale transforms.
2335   TestView* child = new TestView;
2336   TestView* child_child = new TestView;
2337
2338   // View used to test a rotation transform.
2339   TestView* child_2 = new TestView;
2340
2341   top_view.AddChildView(child);
2342   child->AddChildView(child_child);
2343
2344   top_view.SetBoundsRect(gfx::Rect(0, 0, 1000, 1000));
2345
2346   child->SetBoundsRect(gfx::Rect(7, 19, 500, 500));
2347   gfx::Transform transform;
2348   transform.Scale(3.0, 4.0);
2349   child->SetTransform(transform);
2350
2351   child_child->SetBoundsRect(gfx::Rect(17, 13, 100, 100));
2352   transform.MakeIdentity();
2353   transform.Scale(5.0, 7.0);
2354   child_child->SetTransform(transform);
2355
2356   top_view.AddChildView(child_2);
2357   child_2->SetBoundsRect(gfx::Rect(700, 725, 100, 100));
2358   transform.MakeIdentity();
2359   RotateClockwise(&transform);
2360   child_2->SetTransform(transform);
2361
2362   // Sanity check to make sure basic transforms act as expected.
2363   {
2364     gfx::Transform transform;
2365     transform.Translate(110.0, -110.0);
2366     transform.Scale(100.0, 55.0);
2367     transform.Translate(1.0, 1.0);
2368
2369     // convert to a 3x3 matrix.
2370     const SkMatrix& matrix = transform.matrix();
2371
2372     EXPECT_EQ(210, matrix.getTranslateX());
2373     EXPECT_EQ(-55, matrix.getTranslateY());
2374     EXPECT_EQ(100, matrix.getScaleX());
2375     EXPECT_EQ(55, matrix.getScaleY());
2376     EXPECT_EQ(0, matrix.getSkewX());
2377     EXPECT_EQ(0, matrix.getSkewY());
2378   }
2379
2380   {
2381     gfx::Transform transform;
2382     transform.Translate(1.0, 1.0);
2383     gfx::Transform t2;
2384     t2.Scale(100.0, 55.0);
2385     gfx::Transform t3;
2386     t3.Translate(110.0, -110.0);
2387     transform.ConcatTransform(t2);
2388     transform.ConcatTransform(t3);
2389
2390     // convert to a 3x3 matrix
2391     const SkMatrix& matrix = transform.matrix();
2392
2393     EXPECT_EQ(210, matrix.getTranslateX());
2394     EXPECT_EQ(-55, matrix.getTranslateY());
2395     EXPECT_EQ(100, matrix.getScaleX());
2396     EXPECT_EQ(55, matrix.getScaleY());
2397     EXPECT_EQ(0, matrix.getSkewX());
2398     EXPECT_EQ(0, matrix.getSkewY());
2399   }
2400
2401   // Conversions from child->top and top->child.
2402   {
2403     gfx::Point point(5, 5);
2404     View::ConvertPointToTarget(child, &top_view, &point);
2405     EXPECT_EQ(22, point.x());
2406     EXPECT_EQ(39, point.y());
2407
2408     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
2409     View::ConvertRectToTarget(child, &top_view, &rect);
2410     EXPECT_FLOAT_EQ(22.0f, rect.x());
2411     EXPECT_FLOAT_EQ(39.0f, rect.y());
2412     EXPECT_FLOAT_EQ(30.0f, rect.width());
2413     EXPECT_FLOAT_EQ(80.0f, rect.height());
2414
2415     point.SetPoint(22, 39);
2416     View::ConvertPointToTarget(&top_view, child, &point);
2417     EXPECT_EQ(5, point.x());
2418     EXPECT_EQ(5, point.y());
2419
2420     rect.SetRect(22.0f, 39.0f, 30.0f, 80.0f);
2421     View::ConvertRectToTarget(&top_view, child, &rect);
2422     EXPECT_FLOAT_EQ(5.0f, rect.x());
2423     EXPECT_FLOAT_EQ(5.0f, rect.y());
2424     EXPECT_FLOAT_EQ(10.0f, rect.width());
2425     EXPECT_FLOAT_EQ(20.0f, rect.height());
2426   }
2427
2428   // Conversions from child_child->top and top->child_child.
2429   {
2430     gfx::Point point(5, 5);
2431     View::ConvertPointToTarget(child_child, &top_view, &point);
2432     EXPECT_EQ(133, point.x());
2433     EXPECT_EQ(211, point.y());
2434
2435     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
2436     View::ConvertRectToTarget(child_child, &top_view, &rect);
2437     EXPECT_FLOAT_EQ(133.0f, rect.x());
2438     EXPECT_FLOAT_EQ(211.0f, rect.y());
2439     EXPECT_FLOAT_EQ(150.0f, rect.width());
2440     EXPECT_FLOAT_EQ(560.0f, rect.height());
2441
2442     point.SetPoint(133, 211);
2443     View::ConvertPointToTarget(&top_view, child_child, &point);
2444     EXPECT_EQ(5, point.x());
2445     EXPECT_EQ(5, point.y());
2446
2447     rect.SetRect(133.0f, 211.0f, 150.0f, 560.0f);
2448     View::ConvertRectToTarget(&top_view, child_child, &rect);
2449     EXPECT_FLOAT_EQ(5.0f, rect.x());
2450     EXPECT_FLOAT_EQ(5.0f, rect.y());
2451     EXPECT_FLOAT_EQ(10.0f, rect.width());
2452     EXPECT_FLOAT_EQ(20.0f, rect.height());
2453   }
2454
2455   // Conversions from child_child->child and child->child_child
2456   {
2457     gfx::Point point(5, 5);
2458     View::ConvertPointToTarget(child_child, child, &point);
2459     EXPECT_EQ(42, point.x());
2460     EXPECT_EQ(48, point.y());
2461
2462     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
2463     View::ConvertRectToTarget(child_child, child, &rect);
2464     EXPECT_FLOAT_EQ(42.0f, rect.x());
2465     EXPECT_FLOAT_EQ(48.0f, rect.y());
2466     EXPECT_FLOAT_EQ(50.0f, rect.width());
2467     EXPECT_FLOAT_EQ(140.0f, rect.height());
2468
2469     point.SetPoint(42, 48);
2470     View::ConvertPointToTarget(child, child_child, &point);
2471     EXPECT_EQ(5, point.x());
2472     EXPECT_EQ(5, point.y());
2473
2474     rect.SetRect(42.0f, 48.0f, 50.0f, 140.0f);
2475     View::ConvertRectToTarget(child, child_child, &rect);
2476     EXPECT_FLOAT_EQ(5.0f, rect.x());
2477     EXPECT_FLOAT_EQ(5.0f, rect.y());
2478     EXPECT_FLOAT_EQ(10.0f, rect.width());
2479     EXPECT_FLOAT_EQ(20.0f, rect.height());
2480   }
2481
2482   // Conversions from top_view to child with a value that should be negative.
2483   // This ensures we don't round up with negative numbers.
2484   {
2485     gfx::Point point(6, 18);
2486     View::ConvertPointToTarget(&top_view, child, &point);
2487     EXPECT_EQ(-1, point.x());
2488     EXPECT_EQ(-1, point.y());
2489
2490     float error = 0.01f;
2491     gfx::RectF rect(6.0f, 18.0f, 10.0f, 39.0f);
2492     View::ConvertRectToTarget(&top_view, child, &rect);
2493     EXPECT_NEAR(-0.33f, rect.x(), error);
2494     EXPECT_NEAR(-0.25f, rect.y(), error);
2495     EXPECT_NEAR(3.33f, rect.width(), error);
2496     EXPECT_NEAR(9.75f, rect.height(), error);
2497   }
2498
2499   // Rect conversions from top_view->child_2 and child_2->top_view.
2500   {
2501     gfx::RectF rect(50.0f, 55.0f, 20.0f, 30.0f);
2502     View::ConvertRectToTarget(child_2, &top_view, &rect);
2503     EXPECT_FLOAT_EQ(615.0f, rect.x());
2504     EXPECT_FLOAT_EQ(775.0f, rect.y());
2505     EXPECT_FLOAT_EQ(30.0f, rect.width());
2506     EXPECT_FLOAT_EQ(20.0f, rect.height());
2507
2508     rect.SetRect(615.0f, 775.0f, 30.0f, 20.0f);
2509     View::ConvertRectToTarget(&top_view, child_2, &rect);
2510     EXPECT_FLOAT_EQ(50.0f, rect.x());
2511     EXPECT_FLOAT_EQ(55.0f, rect.y());
2512     EXPECT_FLOAT_EQ(20.0f, rect.width());
2513     EXPECT_FLOAT_EQ(30.0f, rect.height());
2514   }
2515 }
2516
2517 // Tests conversion methods to and from screen coordinates.
2518 TEST_F(ViewTest, ConversionsToFromScreen) {
2519   scoped_ptr<Widget> widget(new Widget);
2520   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2521   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2522   params.bounds = gfx::Rect(50, 50, 650, 650);
2523   widget->Init(params);
2524
2525   View* child = new View;
2526   widget->GetRootView()->AddChildView(child);
2527   child->SetBounds(10, 10, 100, 200);
2528   gfx::Transform t;
2529   t.Scale(0.5, 0.5);
2530   child->SetTransform(t);
2531
2532   gfx::Point point_in_screen(100, 90);
2533   gfx::Point point_in_child(80,60);
2534
2535   gfx::Point point = point_in_screen;
2536   View::ConvertPointFromScreen(child, &point);
2537   EXPECT_EQ(point_in_child.ToString(), point.ToString());
2538
2539   View::ConvertPointToScreen(child, &point);
2540   EXPECT_EQ(point_in_screen.ToString(), point.ToString());
2541 }
2542
2543 // Tests conversion methods for rectangles.
2544 TEST_F(ViewTest, ConvertRectWithTransform) {
2545   scoped_ptr<Widget> widget(new Widget);
2546   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2547   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2548   params.bounds = gfx::Rect(50, 50, 650, 650);
2549   widget->Init(params);
2550   View* root = widget->GetRootView();
2551
2552   TestView* v1 = new TestView;
2553   TestView* v2 = new TestView;
2554   root->AddChildView(v1);
2555   v1->AddChildView(v2);
2556
2557   v1->SetBoundsRect(gfx::Rect(10, 10, 500, 500));
2558   v2->SetBoundsRect(gfx::Rect(20, 20, 100, 200));
2559
2560   // |v2| now occupies (30, 30) to (130, 230) in |widget|
2561   gfx::Rect rect(5, 5, 15, 40);
2562   EXPECT_EQ(gfx::Rect(25, 25, 15, 40), v2->ConvertRectToParent(rect));
2563   EXPECT_EQ(gfx::Rect(35, 35, 15, 40), v2->ConvertRectToWidget(rect));
2564
2565   // Rotate |v2|
2566   gfx::Transform t2;
2567   RotateCounterclockwise(&t2);
2568   t2.matrix().set(1, 3, 100.f);
2569   v2->SetTransform(t2);
2570
2571   // |v2| now occupies (30, 30) to (230, 130) in |widget|
2572   EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
2573   EXPECT_EQ(gfx::Rect(35, 110, 40, 15), v2->ConvertRectToWidget(rect));
2574
2575   // Scale down |v1|
2576   gfx::Transform t1;
2577   t1.Scale(0.5, 0.5);
2578   v1->SetTransform(t1);
2579
2580   // The rectangle should remain the same for |v1|.
2581   EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
2582
2583   // |v2| now occupies (20, 20) to (120, 70) in |widget|
2584   EXPECT_EQ(gfx::Rect(22, 60, 21, 8).ToString(),
2585             v2->ConvertRectToWidget(rect).ToString());
2586
2587   widget->CloseNow();
2588 }
2589
2590 class ObserverView : public View {
2591  public:
2592   ObserverView();
2593   virtual ~ObserverView();
2594
2595   void ResetTestState();
2596
2597   bool has_add_details() const { return has_add_details_; }
2598   bool has_remove_details() const { return has_remove_details_; }
2599
2600   const ViewHierarchyChangedDetails& add_details() const {
2601     return add_details_;
2602   }
2603
2604   const ViewHierarchyChangedDetails& remove_details() const {
2605     return remove_details_;
2606   }
2607
2608  private:
2609   // View:
2610   virtual void ViewHierarchyChanged(
2611       const ViewHierarchyChangedDetails& details) OVERRIDE;
2612
2613   bool has_add_details_;
2614   bool has_remove_details_;
2615   ViewHierarchyChangedDetails add_details_;
2616   ViewHierarchyChangedDetails remove_details_;
2617
2618   DISALLOW_COPY_AND_ASSIGN(ObserverView);
2619 };
2620
2621 ObserverView::ObserverView()
2622     : has_add_details_(false),
2623       has_remove_details_(false) {
2624 }
2625
2626 ObserverView::~ObserverView() {}
2627
2628 void ObserverView::ResetTestState() {
2629   has_add_details_ = false;
2630   has_remove_details_ = false;
2631   add_details_ = ViewHierarchyChangedDetails();
2632   remove_details_ = ViewHierarchyChangedDetails();
2633 }
2634
2635 void ObserverView::ViewHierarchyChanged(
2636     const ViewHierarchyChangedDetails& details) {
2637   if (details.is_add) {
2638     has_add_details_ = true;
2639     add_details_ = details;
2640   } else {
2641     has_remove_details_ = true;
2642     remove_details_ = details;
2643   }
2644 }
2645
2646 // Verifies that the ViewHierarchyChanged() notification is sent correctly when
2647 // a child view is added or removed to all the views in the hierarchy (up and
2648 // down).
2649 // The tree looks like this:
2650 // v1
2651 // +-- v2
2652 //     +-- v3
2653 //     +-- v4 (starts here, then get reparented to v1)
2654 TEST_F(ViewTest, ViewHierarchyChanged) {
2655   ObserverView v1;
2656
2657   ObserverView* v3 = new ObserverView();
2658
2659   // Add |v3| to |v2|.
2660   scoped_ptr<ObserverView> v2(new ObserverView());
2661   v2->AddChildView(v3);
2662
2663   // Make sure both |v2| and |v3| receive the ViewHierarchyChanged()
2664   // notification.
2665   EXPECT_TRUE(v2->has_add_details());
2666   EXPECT_FALSE(v2->has_remove_details());
2667   EXPECT_EQ(v2.get(), v2->add_details().parent);
2668   EXPECT_EQ(v3, v2->add_details().child);
2669   EXPECT_EQ(NULL, v2->add_details().move_view);
2670
2671   EXPECT_TRUE(v3->has_add_details());
2672   EXPECT_FALSE(v3->has_remove_details());
2673   EXPECT_EQ(v2.get(), v3->add_details().parent);
2674   EXPECT_EQ(v3, v3->add_details().child);
2675   EXPECT_EQ(NULL, v3->add_details().move_view);
2676
2677   // Reset everything to the initial state.
2678   v2->ResetTestState();
2679   v3->ResetTestState();
2680
2681   // Add |v2| to v1.
2682   v1.AddChildView(v2.get());
2683
2684   // Verifies that |v2| is the child view *added* and the parent view is |v1|.
2685   // Make sure all the views (v1, v2, v3) received _that_ information.
2686   EXPECT_TRUE(v1.has_add_details());
2687   EXPECT_FALSE(v1.has_remove_details());
2688   EXPECT_EQ(&v1, v1.add_details().parent);
2689   EXPECT_EQ(v2.get(), v1.add_details().child);
2690   EXPECT_EQ(NULL, v1.add_details().move_view);
2691
2692   EXPECT_TRUE(v2->has_add_details());
2693   EXPECT_FALSE(v2->has_remove_details());
2694   EXPECT_EQ(&v1, v2->add_details().parent);
2695   EXPECT_EQ(v2.get(), v2->add_details().child);
2696   EXPECT_EQ(NULL, v2->add_details().move_view);
2697
2698   EXPECT_TRUE(v3->has_add_details());
2699   EXPECT_FALSE(v3->has_remove_details());
2700   EXPECT_EQ(&v1, v3->add_details().parent);
2701   EXPECT_EQ(v2.get(), v3->add_details().child);
2702   EXPECT_EQ(NULL, v3->add_details().move_view);
2703
2704   // Reset everything to the initial state.
2705   v1.ResetTestState();
2706   v2->ResetTestState();
2707   v3->ResetTestState();
2708
2709   // Remove |v2| from |v1|.
2710   v1.RemoveChildView(v2.get());
2711
2712   // Verifies that |v2| is the child view *removed* and the parent view is |v1|.
2713   // Make sure all the views (v1, v2, v3) received _that_ information.
2714   EXPECT_FALSE(v1.has_add_details());
2715   EXPECT_TRUE(v1.has_remove_details());
2716   EXPECT_EQ(&v1, v1.remove_details().parent);
2717   EXPECT_EQ(v2.get(), v1.remove_details().child);
2718   EXPECT_EQ(NULL, v1.remove_details().move_view);
2719
2720   EXPECT_FALSE(v2->has_add_details());
2721   EXPECT_TRUE(v2->has_remove_details());
2722   EXPECT_EQ(&v1, v2->remove_details().parent);
2723   EXPECT_EQ(v2.get(), v2->remove_details().child);
2724   EXPECT_EQ(NULL, v2->remove_details().move_view);
2725
2726   EXPECT_FALSE(v3->has_add_details());
2727   EXPECT_TRUE(v3->has_remove_details());
2728   EXPECT_EQ(&v1, v3->remove_details().parent);
2729   EXPECT_EQ(v3, v3->remove_details().child);
2730   EXPECT_EQ(NULL, v3->remove_details().move_view);
2731
2732   // Verifies notifications when reparenting a view.
2733   ObserverView* v4 = new ObserverView();
2734   // Add |v4| to |v2|.
2735   v2->AddChildView(v4);
2736
2737   // Reset everything to the initial state.
2738   v1.ResetTestState();
2739   v2->ResetTestState();
2740   v3->ResetTestState();
2741   v4->ResetTestState();
2742
2743   // Reparent |v4| to |v1|.
2744   v1.AddChildView(v4);
2745
2746   // Verifies that all views receive the correct information for all the child,
2747   // parent and move views.
2748
2749   // |v1| is the new parent, |v4| is the child for add, |v2| is the old parent.
2750   EXPECT_TRUE(v1.has_add_details());
2751   EXPECT_FALSE(v1.has_remove_details());
2752   EXPECT_EQ(&v1, v1.add_details().parent);
2753   EXPECT_EQ(v4, v1.add_details().child);
2754   EXPECT_EQ(v2.get(), v1.add_details().move_view);
2755
2756   // |v2| is the old parent, |v4| is the child for remove, |v1| is the new
2757   // parent.
2758   EXPECT_FALSE(v2->has_add_details());
2759   EXPECT_TRUE(v2->has_remove_details());
2760   EXPECT_EQ(v2.get(), v2->remove_details().parent);
2761   EXPECT_EQ(v4, v2->remove_details().child);
2762   EXPECT_EQ(&v1, v2->remove_details().move_view);
2763
2764   // |v3| is not impacted by this operation, and hence receives no notification.
2765   EXPECT_FALSE(v3->has_add_details());
2766   EXPECT_FALSE(v3->has_remove_details());
2767
2768   // |v4| is the reparented child, so it receives notifications for the remove
2769   // and then the add.  |v2| is its old parent, |v1| is its new parent.
2770   EXPECT_TRUE(v4->has_remove_details());
2771   EXPECT_TRUE(v4->has_add_details());
2772   EXPECT_EQ(v2.get(), v4->remove_details().parent);
2773   EXPECT_EQ(&v1, v4->add_details().parent);
2774   EXPECT_EQ(v4, v4->add_details().child);
2775   EXPECT_EQ(v4, v4->remove_details().child);
2776   EXPECT_EQ(&v1, v4->remove_details().move_view);
2777   EXPECT_EQ(v2.get(), v4->add_details().move_view);
2778 }
2779
2780 // Verifies if the child views added under the root are all deleted when calling
2781 // RemoveAllChildViews.
2782 // The tree looks like this:
2783 // root
2784 // +-- child1
2785 //     +-- foo
2786 //         +-- bar0
2787 //         +-- bar1
2788 //         +-- bar2
2789 // +-- child2
2790 // +-- child3
2791 TEST_F(ViewTest, RemoveAllChildViews) {
2792   View root;
2793
2794   View* child1 = new View;
2795   root.AddChildView(child1);
2796
2797   for (int i = 0; i < 2; ++i)
2798     root.AddChildView(new View);
2799
2800   View* foo = new View;
2801   child1->AddChildView(foo);
2802
2803   // Add some nodes to |foo|.
2804   for (int i = 0; i < 3; ++i)
2805     foo->AddChildView(new View);
2806
2807   EXPECT_EQ(3, root.child_count());
2808   EXPECT_EQ(1, child1->child_count());
2809   EXPECT_EQ(3, foo->child_count());
2810
2811   // Now remove all child views from root.
2812   root.RemoveAllChildViews(true);
2813
2814   EXPECT_EQ(0, root.child_count());
2815   EXPECT_FALSE(root.has_children());
2816 }
2817
2818 TEST_F(ViewTest, Contains) {
2819   View v1;
2820   View* v2 = new View;
2821   View* v3 = new View;
2822
2823   v1.AddChildView(v2);
2824   v2->AddChildView(v3);
2825
2826   EXPECT_FALSE(v1.Contains(NULL));
2827   EXPECT_TRUE(v1.Contains(&v1));
2828   EXPECT_TRUE(v1.Contains(v2));
2829   EXPECT_TRUE(v1.Contains(v3));
2830
2831   EXPECT_FALSE(v2->Contains(NULL));
2832   EXPECT_TRUE(v2->Contains(v2));
2833   EXPECT_FALSE(v2->Contains(&v1));
2834   EXPECT_TRUE(v2->Contains(v3));
2835
2836   EXPECT_FALSE(v3->Contains(NULL));
2837   EXPECT_TRUE(v3->Contains(v3));
2838   EXPECT_FALSE(v3->Contains(&v1));
2839   EXPECT_FALSE(v3->Contains(v2));
2840 }
2841
2842 // Verifies if GetIndexOf() returns the correct index for the specified child
2843 // view.
2844 // The tree looks like this:
2845 // root
2846 // +-- child1
2847 //     +-- foo1
2848 // +-- child2
2849 TEST_F(ViewTest, GetIndexOf) {
2850   View root;
2851
2852   View* child1 = new View;
2853   root.AddChildView(child1);
2854
2855   View* child2 = new View;
2856   root.AddChildView(child2);
2857
2858   View* foo1 = new View;
2859   child1->AddChildView(foo1);
2860
2861   EXPECT_EQ(-1, root.GetIndexOf(NULL));
2862   EXPECT_EQ(-1, root.GetIndexOf(&root));
2863   EXPECT_EQ(0, root.GetIndexOf(child1));
2864   EXPECT_EQ(1, root.GetIndexOf(child2));
2865   EXPECT_EQ(-1, root.GetIndexOf(foo1));
2866
2867   EXPECT_EQ(-1, child1->GetIndexOf(NULL));
2868   EXPECT_EQ(-1, child1->GetIndexOf(&root));
2869   EXPECT_EQ(-1, child1->GetIndexOf(child1));
2870   EXPECT_EQ(-1, child1->GetIndexOf(child2));
2871   EXPECT_EQ(0, child1->GetIndexOf(foo1));
2872
2873   EXPECT_EQ(-1, child2->GetIndexOf(NULL));
2874   EXPECT_EQ(-1, child2->GetIndexOf(&root));
2875   EXPECT_EQ(-1, child2->GetIndexOf(child2));
2876   EXPECT_EQ(-1, child2->GetIndexOf(child1));
2877   EXPECT_EQ(-1, child2->GetIndexOf(foo1));
2878 }
2879
2880 // Verifies that the child views can be reordered correctly.
2881 TEST_F(ViewTest, ReorderChildren) {
2882   View root;
2883
2884   View* child = new View();
2885   root.AddChildView(child);
2886
2887   View* foo1 = new View();
2888   child->AddChildView(foo1);
2889   View* foo2 = new View();
2890   child->AddChildView(foo2);
2891   View* foo3 = new View();
2892   child->AddChildView(foo3);
2893   foo1->SetFocusable(true);
2894   foo2->SetFocusable(true);
2895   foo3->SetFocusable(true);
2896
2897   ASSERT_EQ(0, child->GetIndexOf(foo1));
2898   ASSERT_EQ(1, child->GetIndexOf(foo2));
2899   ASSERT_EQ(2, child->GetIndexOf(foo3));
2900   ASSERT_EQ(foo2, foo1->GetNextFocusableView());
2901   ASSERT_EQ(foo3, foo2->GetNextFocusableView());
2902   ASSERT_EQ(NULL, foo3->GetNextFocusableView());
2903
2904   // Move |foo2| at the end.
2905   child->ReorderChildView(foo2, -1);
2906   ASSERT_EQ(0, child->GetIndexOf(foo1));
2907   ASSERT_EQ(1, child->GetIndexOf(foo3));
2908   ASSERT_EQ(2, child->GetIndexOf(foo2));
2909   ASSERT_EQ(foo3, foo1->GetNextFocusableView());
2910   ASSERT_EQ(foo2, foo3->GetNextFocusableView());
2911   ASSERT_EQ(NULL, foo2->GetNextFocusableView());
2912
2913   // Move |foo1| at the end.
2914   child->ReorderChildView(foo1, -1);
2915   ASSERT_EQ(0, child->GetIndexOf(foo3));
2916   ASSERT_EQ(1, child->GetIndexOf(foo2));
2917   ASSERT_EQ(2, child->GetIndexOf(foo1));
2918   ASSERT_EQ(NULL, foo1->GetNextFocusableView());
2919   ASSERT_EQ(foo2, foo1->GetPreviousFocusableView());
2920   ASSERT_EQ(foo2, foo3->GetNextFocusableView());
2921   ASSERT_EQ(foo1, foo2->GetNextFocusableView());
2922
2923   // Move |foo2| to the front.
2924   child->ReorderChildView(foo2, 0);
2925   ASSERT_EQ(0, child->GetIndexOf(foo2));
2926   ASSERT_EQ(1, child->GetIndexOf(foo3));
2927   ASSERT_EQ(2, child->GetIndexOf(foo1));
2928   ASSERT_EQ(NULL, foo1->GetNextFocusableView());
2929   ASSERT_EQ(foo3, foo1->GetPreviousFocusableView());
2930   ASSERT_EQ(foo3, foo2->GetNextFocusableView());
2931   ASSERT_EQ(foo1, foo3->GetNextFocusableView());
2932 }
2933
2934 // Verifies that GetViewByID returns the correctly child view from the specified
2935 // ID.
2936 // The tree looks like this:
2937 // v1
2938 // +-- v2
2939 //     +-- v3
2940 //     +-- v4
2941 TEST_F(ViewTest, GetViewByID) {
2942   View v1;
2943   const int kV1ID = 1;
2944   v1.set_id(kV1ID);
2945
2946   View v2;
2947   const int kV2ID = 2;
2948   v2.set_id(kV2ID);
2949
2950   View v3;
2951   const int kV3ID = 3;
2952   v3.set_id(kV3ID);
2953
2954   View v4;
2955   const int kV4ID = 4;
2956   v4.set_id(kV4ID);
2957
2958   const int kV5ID = 5;
2959
2960   v1.AddChildView(&v2);
2961   v2.AddChildView(&v3);
2962   v2.AddChildView(&v4);
2963
2964   EXPECT_EQ(&v1, v1.GetViewByID(kV1ID));
2965   EXPECT_EQ(&v2, v1.GetViewByID(kV2ID));
2966   EXPECT_EQ(&v4, v1.GetViewByID(kV4ID));
2967
2968   EXPECT_EQ(NULL, v1.GetViewByID(kV5ID));  // No V5 exists.
2969   EXPECT_EQ(NULL, v2.GetViewByID(kV1ID));  // It can get only from child views.
2970
2971   const int kGroup = 1;
2972   v3.SetGroup(kGroup);
2973   v4.SetGroup(kGroup);
2974
2975   View::Views views;
2976   v1.GetViewsInGroup(kGroup, &views);
2977   EXPECT_EQ(2U, views.size());
2978
2979   View::Views::const_iterator i(std::find(views.begin(), views.end(), &v3));
2980   EXPECT_NE(views.end(), i);
2981
2982   i = std::find(views.begin(), views.end(), &v4);
2983   EXPECT_NE(views.end(), i);
2984 }
2985
2986 TEST_F(ViewTest, AddExistingChild) {
2987   View v1, v2, v3;
2988
2989   v1.AddChildView(&v2);
2990   v1.AddChildView(&v3);
2991   EXPECT_EQ(0, v1.GetIndexOf(&v2));
2992   EXPECT_EQ(1, v1.GetIndexOf(&v3));
2993
2994   // Check that there's no change in order when adding at same index.
2995   v1.AddChildViewAt(&v2, 0);
2996   EXPECT_EQ(0, v1.GetIndexOf(&v2));
2997   EXPECT_EQ(1, v1.GetIndexOf(&v3));
2998   v1.AddChildViewAt(&v3, 1);
2999   EXPECT_EQ(0, v1.GetIndexOf(&v2));
3000   EXPECT_EQ(1, v1.GetIndexOf(&v3));
3001
3002   // Add it at a different index and check for change in order.
3003   v1.AddChildViewAt(&v2, 1);
3004   EXPECT_EQ(1, v1.GetIndexOf(&v2));
3005   EXPECT_EQ(0, v1.GetIndexOf(&v3));
3006   v1.AddChildViewAt(&v2, 0);
3007   EXPECT_EQ(0, v1.GetIndexOf(&v2));
3008   EXPECT_EQ(1, v1.GetIndexOf(&v3));
3009
3010   // Check that calling |AddChildView()| does not change the order.
3011   v1.AddChildView(&v2);
3012   EXPECT_EQ(0, v1.GetIndexOf(&v2));
3013   EXPECT_EQ(1, v1.GetIndexOf(&v3));
3014   v1.AddChildView(&v3);
3015   EXPECT_EQ(0, v1.GetIndexOf(&v2));
3016   EXPECT_EQ(1, v1.GetIndexOf(&v3));
3017 }
3018
3019 ////////////////////////////////////////////////////////////////////////////////
3020 // Layers
3021 ////////////////////////////////////////////////////////////////////////////////
3022
3023 #if defined(USE_AURA)
3024
3025 namespace {
3026
3027 // Test implementation of LayerAnimator.
3028 class TestLayerAnimator : public ui::LayerAnimator {
3029  public:
3030   TestLayerAnimator();
3031
3032   const gfx::Rect& last_bounds() const { return last_bounds_; }
3033
3034   // LayerAnimator.
3035   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
3036
3037  protected:
3038   virtual ~TestLayerAnimator() { }
3039
3040  private:
3041   gfx::Rect last_bounds_;
3042
3043   DISALLOW_COPY_AND_ASSIGN(TestLayerAnimator);
3044 };
3045
3046 TestLayerAnimator::TestLayerAnimator()
3047     : ui::LayerAnimator(base::TimeDelta::FromMilliseconds(0)) {
3048 }
3049
3050 void TestLayerAnimator::SetBounds(const gfx::Rect& bounds) {
3051   last_bounds_ = bounds;
3052 }
3053
3054 }  // namespace
3055
3056 class ViewLayerTest : public ViewsTestBase {
3057  public:
3058   ViewLayerTest() : widget_(NULL), old_use_acceleration_(false) {}
3059
3060   virtual ~ViewLayerTest() {
3061   }
3062
3063   // Returns the Layer used by the RootView.
3064   ui::Layer* GetRootLayer() {
3065     return widget()->GetLayer();
3066   }
3067
3068   virtual void SetUp() OVERRIDE {
3069     ViewTest::SetUp();
3070     old_use_acceleration_ = View::get_use_acceleration_when_possible();
3071     View::set_use_acceleration_when_possible(true);
3072
3073     widget_ = new Widget;
3074     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
3075     params.bounds = gfx::Rect(50, 50, 200, 200);
3076     widget_->Init(params);
3077     widget_->Show();
3078     widget_->GetRootView()->SetBounds(0, 0, 200, 200);
3079   }
3080
3081   virtual void TearDown() OVERRIDE {
3082     View::set_use_acceleration_when_possible(old_use_acceleration_);
3083     widget_->CloseNow();
3084     ViewsTestBase::TearDown();
3085   }
3086
3087   Widget* widget() { return widget_; }
3088
3089  private:
3090   Widget* widget_;
3091   bool old_use_acceleration_;
3092 };
3093
3094
3095 TEST_F(ViewLayerTest, LayerToggling) {
3096   // Because we lazily create textures the calls to DrawTree are necessary to
3097   // ensure we trigger creation of textures.
3098   ui::Layer* root_layer = widget()->GetLayer();
3099   View* content_view = new View;
3100   widget()->SetContentsView(content_view);
3101
3102   // Create v1, give it a bounds and verify everything is set up correctly.
3103   View* v1 = new View;
3104   v1->SetPaintToLayer(true);
3105   EXPECT_TRUE(v1->layer() != NULL);
3106   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
3107   content_view->AddChildView(v1);
3108   ASSERT_TRUE(v1->layer() != NULL);
3109   EXPECT_EQ(root_layer, v1->layer()->parent());
3110   EXPECT_EQ(gfx::Rect(20, 30, 140, 150), v1->layer()->bounds());
3111
3112   // Create v2 as a child of v1 and do basic assertion testing.
3113   View* v2 = new View;
3114   v1->AddChildView(v2);
3115   EXPECT_TRUE(v2->layer() == NULL);
3116   v2->SetBoundsRect(gfx::Rect(10, 20, 30, 40));
3117   v2->SetPaintToLayer(true);
3118   ASSERT_TRUE(v2->layer() != NULL);
3119   EXPECT_EQ(v1->layer(), v2->layer()->parent());
3120   EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
3121
3122   // Turn off v1s layer. v2 should still have a layer but its parent should have
3123   // changed.
3124   v1->SetPaintToLayer(false);
3125   EXPECT_TRUE(v1->layer() == NULL);
3126   EXPECT_TRUE(v2->layer() != NULL);
3127   EXPECT_EQ(root_layer, v2->layer()->parent());
3128   ASSERT_EQ(1u, root_layer->children().size());
3129   EXPECT_EQ(root_layer->children()[0], v2->layer());
3130   // The bounds of the layer should have changed to be relative to the root view
3131   // now.
3132   EXPECT_EQ(gfx::Rect(30, 50, 30, 40), v2->layer()->bounds());
3133
3134   // Make v1 have a layer again and verify v2s layer is wired up correctly.
3135   gfx::Transform transform;
3136   transform.Scale(2.0, 2.0);
3137   v1->SetTransform(transform);
3138   EXPECT_TRUE(v1->layer() != NULL);
3139   EXPECT_TRUE(v2->layer() != NULL);
3140   EXPECT_EQ(root_layer, v1->layer()->parent());
3141   EXPECT_EQ(v1->layer(), v2->layer()->parent());
3142   ASSERT_EQ(1u, root_layer->children().size());
3143   EXPECT_EQ(root_layer->children()[0], v1->layer());
3144   ASSERT_EQ(1u, v1->layer()->children().size());
3145   EXPECT_EQ(v1->layer()->children()[0], v2->layer());
3146   EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
3147 }
3148
3149 // Verifies turning on a layer wires up children correctly.
3150 TEST_F(ViewLayerTest, NestedLayerToggling) {
3151   View* content_view = new View;
3152   widget()->SetContentsView(content_view);
3153
3154   // Create v1, give it a bounds and verify everything is set up correctly.
3155   View* v1 = new View;
3156   content_view->AddChildView(v1);
3157   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
3158
3159   View* v2 = new View;
3160   v1->AddChildView(v2);
3161
3162   View* v3 = new View;
3163   v3->SetPaintToLayer(true);
3164   v2->AddChildView(v3);
3165   ASSERT_TRUE(v3->layer() != NULL);
3166
3167   // At this point we have v1-v2-v3. v3 has a layer, v1 and v2 don't.
3168
3169   v1->SetPaintToLayer(true);
3170   EXPECT_EQ(v1->layer(), v3->layer()->parent());
3171 }
3172
3173 TEST_F(ViewLayerTest, LayerAnimator) {
3174   View* content_view = new View;
3175   widget()->SetContentsView(content_view);
3176
3177   View* v1 = new View;
3178   content_view->AddChildView(v1);
3179   v1->SetPaintToLayer(true);
3180   EXPECT_TRUE(v1->layer() != NULL);
3181
3182   TestLayerAnimator* animator = new TestLayerAnimator();
3183   v1->layer()->SetAnimator(animator);
3184
3185   gfx::Rect bounds(1, 2, 3, 4);
3186   v1->SetBoundsRect(bounds);
3187   EXPECT_EQ(bounds, animator->last_bounds());
3188   // TestLayerAnimator doesn't update the layer.
3189   EXPECT_NE(bounds, v1->layer()->bounds());
3190 }
3191
3192 // Verifies the bounds of a layer are updated if the bounds of ancestor that
3193 // doesn't have a layer change.
3194 TEST_F(ViewLayerTest, BoundsChangeWithLayer) {
3195   View* content_view = new View;
3196   widget()->SetContentsView(content_view);
3197
3198   View* v1 = new View;
3199   content_view->AddChildView(v1);
3200   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
3201
3202   View* v2 = new View;
3203   v2->SetBoundsRect(gfx::Rect(10, 11, 40, 50));
3204   v1->AddChildView(v2);
3205   v2->SetPaintToLayer(true);
3206   ASSERT_TRUE(v2->layer() != NULL);
3207   EXPECT_EQ(gfx::Rect(30, 41, 40, 50), v2->layer()->bounds());
3208
3209   v1->SetPosition(gfx::Point(25, 36));
3210   EXPECT_EQ(gfx::Rect(35, 47, 40, 50), v2->layer()->bounds());
3211
3212   v2->SetPosition(gfx::Point(11, 12));
3213   EXPECT_EQ(gfx::Rect(36, 48, 40, 50), v2->layer()->bounds());
3214
3215   // Bounds of the layer should change even if the view is not invisible.
3216   v1->SetVisible(false);
3217   v1->SetPosition(gfx::Point(20, 30));
3218   EXPECT_EQ(gfx::Rect(31, 42, 40, 50), v2->layer()->bounds());
3219
3220   v2->SetVisible(false);
3221   v2->SetBoundsRect(gfx::Rect(10, 11, 20, 30));
3222   EXPECT_EQ(gfx::Rect(30, 41, 20, 30), v2->layer()->bounds());
3223 }
3224
3225 // Make sure layers are positioned correctly in RTL.
3226 TEST_F(ViewLayerTest, BoundInRTL) {
3227   std::string locale = l10n_util::GetApplicationLocale(std::string());
3228   base::i18n::SetICUDefaultLocale("he");
3229
3230   View* view = new View;
3231   widget()->SetContentsView(view);
3232
3233   int content_width = view->width();
3234
3235   // |v1| is initially not attached to anything. So its layer will have the same
3236   // bounds as the view.
3237   View* v1 = new View;
3238   v1->SetPaintToLayer(true);
3239   v1->SetBounds(10, 10, 20, 10);
3240   EXPECT_EQ(gfx::Rect(10, 10, 20, 10),
3241             v1->layer()->bounds());
3242
3243   // Once |v1| is attached to the widget, its layer will get RTL-appropriate
3244   // bounds.
3245   view->AddChildView(v1);
3246   EXPECT_EQ(gfx::Rect(content_width - 30, 10, 20, 10),
3247             v1->layer()->bounds());
3248   gfx::Rect l1bounds = v1->layer()->bounds();
3249
3250   // Now attach a View to the widget first, then create a layer for it. Make
3251   // sure the bounds are correct.
3252   View* v2 = new View;
3253   v2->SetBounds(50, 10, 30, 10);
3254   EXPECT_FALSE(v2->layer());
3255   view->AddChildView(v2);
3256   v2->SetPaintToLayer(true);
3257   EXPECT_EQ(gfx::Rect(content_width - 80, 10, 30, 10),
3258             v2->layer()->bounds());
3259   gfx::Rect l2bounds = v2->layer()->bounds();
3260
3261   view->SetPaintToLayer(true);
3262   EXPECT_EQ(l1bounds, v1->layer()->bounds());
3263   EXPECT_EQ(l2bounds, v2->layer()->bounds());
3264
3265   // Move one of the views. Make sure the layer is positioned correctly
3266   // afterwards.
3267   v1->SetBounds(v1->x() - 5, v1->y(), v1->width(), v1->height());
3268   l1bounds.set_x(l1bounds.x() + 5);
3269   EXPECT_EQ(l1bounds, v1->layer()->bounds());
3270
3271   view->SetPaintToLayer(false);
3272   EXPECT_EQ(l1bounds, v1->layer()->bounds());
3273   EXPECT_EQ(l2bounds, v2->layer()->bounds());
3274
3275   // Move a view again.
3276   v2->SetBounds(v2->x() + 5, v2->y(), v2->width(), v2->height());
3277   l2bounds.set_x(l2bounds.x() - 5);
3278   EXPECT_EQ(l2bounds, v2->layer()->bounds());
3279
3280   // Reset locale.
3281   base::i18n::SetICUDefaultLocale(locale);
3282 }
3283
3284 // Makes sure a transform persists after toggling the visibility.
3285 TEST_F(ViewLayerTest, ToggleVisibilityWithTransform) {
3286   View* view = new View;
3287   gfx::Transform transform;
3288   transform.Scale(2.0, 2.0);
3289   view->SetTransform(transform);
3290   widget()->SetContentsView(view);
3291   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
3292
3293   view->SetVisible(false);
3294   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
3295
3296   view->SetVisible(true);
3297   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
3298 }
3299
3300 // Verifies a transform persists after removing/adding a view with a transform.
3301 TEST_F(ViewLayerTest, ResetTransformOnLayerAfterAdd) {
3302   View* view = new View;
3303   gfx::Transform transform;
3304   transform.Scale(2.0, 2.0);
3305   view->SetTransform(transform);
3306   widget()->SetContentsView(view);
3307   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
3308   ASSERT_TRUE(view->layer() != NULL);
3309   EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
3310
3311   View* parent = view->parent();
3312   parent->RemoveChildView(view);
3313   parent->AddChildView(view);
3314
3315   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
3316   ASSERT_TRUE(view->layer() != NULL);
3317   EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
3318 }
3319
3320 // Makes sure that layer visibility is correct after toggling View visibility.
3321 TEST_F(ViewLayerTest, ToggleVisibilityWithLayer) {
3322   View* content_view = new View;
3323   widget()->SetContentsView(content_view);
3324
3325   // The view isn't attached to a widget or a parent view yet. But it should
3326   // still have a layer, but the layer should not be attached to the root
3327   // layer.
3328   View* v1 = new View;
3329   v1->SetPaintToLayer(true);
3330   EXPECT_TRUE(v1->layer());
3331   EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
3332                                v1->layer()));
3333
3334   // Once the view is attached to a widget, its layer should be attached to the
3335   // root layer and visible.
3336   content_view->AddChildView(v1);
3337   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
3338                               v1->layer()));
3339   EXPECT_TRUE(v1->layer()->IsDrawn());
3340
3341   v1->SetVisible(false);
3342   EXPECT_FALSE(v1->layer()->IsDrawn());
3343
3344   v1->SetVisible(true);
3345   EXPECT_TRUE(v1->layer()->IsDrawn());
3346
3347   widget()->Hide();
3348   EXPECT_FALSE(v1->layer()->IsDrawn());
3349
3350   widget()->Show();
3351   EXPECT_TRUE(v1->layer()->IsDrawn());
3352 }
3353
3354 // Tests that the layers in the subtree are orphaned after a View is removed
3355 // from the parent.
3356 TEST_F(ViewLayerTest, OrphanLayerAfterViewRemove) {
3357   View* content_view = new View;
3358   widget()->SetContentsView(content_view);
3359
3360   View* v1 = new View;
3361   content_view->AddChildView(v1);
3362
3363   View* v2 = new View;
3364   v1->AddChildView(v2);
3365   v2->SetPaintToLayer(true);
3366   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
3367                               v2->layer()));
3368   EXPECT_TRUE(v2->layer()->IsDrawn());
3369
3370   content_view->RemoveChildView(v1);
3371
3372   EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
3373                                v2->layer()));
3374
3375   // Reparent |v2|.
3376   content_view->AddChildView(v2);
3377   delete v1;
3378   v1 = NULL;
3379   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
3380                               v2->layer()));
3381   EXPECT_TRUE(v2->layer()->IsDrawn());
3382 }
3383
3384 class PaintTrackingView : public View {
3385  public:
3386   PaintTrackingView() : painted_(false) {
3387   }
3388
3389   bool painted() const { return painted_; }
3390   void set_painted(bool value) { painted_ = value; }
3391
3392   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
3393     painted_ = true;
3394   }
3395
3396  private:
3397   bool painted_;
3398
3399   DISALLOW_COPY_AND_ASSIGN(PaintTrackingView);
3400 };
3401
3402 // Makes sure child views with layers aren't painted when paint starts at an
3403 // ancestor.
3404 TEST_F(ViewLayerTest, DontPaintChildrenWithLayers) {
3405   PaintTrackingView* content_view = new PaintTrackingView;
3406   widget()->SetContentsView(content_view);
3407   content_view->SetPaintToLayer(true);
3408   GetRootLayer()->GetCompositor()->ScheduleDraw();
3409   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
3410   GetRootLayer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
3411   content_view->set_painted(false);
3412   // content_view no longer has a dirty rect. Paint from the root and make sure
3413   // PaintTrackingView isn't painted.
3414   GetRootLayer()->GetCompositor()->ScheduleDraw();
3415   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
3416   EXPECT_FALSE(content_view->painted());
3417
3418   // Make content_view have a dirty rect, paint the layers and make sure
3419   // PaintTrackingView is painted.
3420   content_view->layer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
3421   GetRootLayer()->GetCompositor()->ScheduleDraw();
3422   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
3423   EXPECT_TRUE(content_view->painted());
3424 }
3425
3426 // Tests that the visibility of child layers are updated correctly when a View's
3427 // visibility changes.
3428 TEST_F(ViewLayerTest, VisibilityChildLayers) {
3429   View* v1 = new View;
3430   v1->SetPaintToLayer(true);
3431   widget()->SetContentsView(v1);
3432
3433   View* v2 = new View;
3434   v1->AddChildView(v2);
3435
3436   View* v3 = new View;
3437   v2->AddChildView(v3);
3438   v3->SetVisible(false);
3439
3440   View* v4 = new View;
3441   v4->SetPaintToLayer(true);
3442   v3->AddChildView(v4);
3443
3444   EXPECT_TRUE(v1->layer()->IsDrawn());
3445   EXPECT_FALSE(v4->layer()->IsDrawn());
3446
3447   v2->SetVisible(false);
3448   EXPECT_TRUE(v1->layer()->IsDrawn());
3449   EXPECT_FALSE(v4->layer()->IsDrawn());
3450
3451   v2->SetVisible(true);
3452   EXPECT_TRUE(v1->layer()->IsDrawn());
3453   EXPECT_FALSE(v4->layer()->IsDrawn());
3454
3455   v2->SetVisible(false);
3456   EXPECT_TRUE(v1->layer()->IsDrawn());
3457   EXPECT_FALSE(v4->layer()->IsDrawn());
3458   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
3459
3460   v3->SetVisible(true);
3461   EXPECT_TRUE(v1->layer()->IsDrawn());
3462   EXPECT_FALSE(v4->layer()->IsDrawn());
3463   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
3464
3465   // Reparent |v3| to |v1|.
3466   v1->AddChildView(v3);
3467   EXPECT_TRUE(v1->layer()->IsDrawn());
3468   EXPECT_TRUE(v4->layer()->IsDrawn());
3469   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
3470 }
3471
3472 // This test creates a random View tree, and then randomly reorders child views,
3473 // reparents views etc. Unrelated changes can appear to break this test. So
3474 // marking this as FLAKY.
3475 TEST_F(ViewLayerTest, DISABLED_ViewLayerTreesInSync) {
3476   View* content = new View;
3477   content->SetPaintToLayer(true);
3478   widget()->SetContentsView(content);
3479   widget()->Show();
3480
3481   ConstructTree(content, 5);
3482   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
3483
3484   ScrambleTree(content);
3485   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
3486
3487   ScrambleTree(content);
3488   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
3489
3490   ScrambleTree(content);
3491   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
3492 }
3493
3494 // Verifies when views are reordered the layer is also reordered. The widget is
3495 // providing the parent layer.
3496 TEST_F(ViewLayerTest, ReorderUnderWidget) {
3497   View* content = new View;
3498   widget()->SetContentsView(content);
3499   View* c1 = new View;
3500   c1->SetPaintToLayer(true);
3501   content->AddChildView(c1);
3502   View* c2 = new View;
3503   c2->SetPaintToLayer(true);
3504   content->AddChildView(c2);
3505
3506   ui::Layer* parent_layer = c1->layer()->parent();
3507   ASSERT_TRUE(parent_layer);
3508   ASSERT_EQ(2u, parent_layer->children().size());
3509   EXPECT_EQ(c1->layer(), parent_layer->children()[0]);
3510   EXPECT_EQ(c2->layer(), parent_layer->children()[1]);
3511
3512   // Move c1 to the front. The layers should have moved too.
3513   content->ReorderChildView(c1, -1);
3514   EXPECT_EQ(c1->layer(), parent_layer->children()[1]);
3515   EXPECT_EQ(c2->layer(), parent_layer->children()[0]);
3516 }
3517
3518 // Verifies that the layer of a view can be acquired properly.
3519 TEST_F(ViewLayerTest, AcquireLayer) {
3520   View* content = new View;
3521   widget()->SetContentsView(content);
3522   scoped_ptr<View> c1(new View);
3523   c1->SetPaintToLayer(true);
3524   EXPECT_TRUE(c1->layer());
3525   content->AddChildView(c1.get());
3526
3527   scoped_ptr<ui::Layer> layer(c1->AcquireLayer());
3528   EXPECT_EQ(layer.get(), c1->layer());
3529
3530   scoped_ptr<ui::Layer> layer2(c1->RecreateLayer());
3531   EXPECT_NE(c1->layer(), layer2.get());
3532
3533   // Destroy view before destroying layer.
3534   c1.reset();
3535 }
3536
3537 // Verify that new layer scales content only if the old layer does.
3538 TEST_F(ViewLayerTest, RecreateLayerScaling) {
3539   scoped_ptr<View> v(new View());
3540   v->SetPaintToLayer(true);
3541   // Set to non default value.
3542   v->layer()->set_scale_content(false);
3543   scoped_ptr<ui::Layer> old_layer(v->RecreateLayer());
3544   ui::Layer* new_layer = v->layer();
3545   EXPECT_FALSE(new_layer->scale_content());
3546 }
3547
3548 // Verify the z-order of the layers as a result of calling RecreateLayer().
3549 TEST_F(ViewLayerTest, RecreateLayerZOrder) {
3550   scoped_ptr<View> v(new View());
3551   v->SetPaintToLayer(true);
3552
3553   View* v1 = new View();
3554   v1->SetPaintToLayer(true);
3555   v->AddChildView(v1);
3556   View* v2 = new View();
3557   v2->SetPaintToLayer(true);
3558   v->AddChildView(v2);
3559
3560   // Test the initial z-order.
3561   const std::vector<ui::Layer*>& child_layers_pre = v->layer()->children();
3562   ASSERT_EQ(2u, child_layers_pre.size());
3563   EXPECT_EQ(v1->layer(), child_layers_pre[0]);
3564   EXPECT_EQ(v2->layer(), child_layers_pre[1]);
3565
3566   scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
3567
3568   // Test the new layer order. |v1_old_layer| should be above the layers
3569   // for |v1| and |v2|.
3570   const std::vector<ui::Layer*>& child_layers_post = v->layer()->children();
3571   ASSERT_EQ(3u, child_layers_post.size());
3572   EXPECT_EQ(v1->layer(), child_layers_post[0]);
3573   EXPECT_EQ(v2->layer(), child_layers_post[1]);
3574   EXPECT_EQ(v1_old_layer, child_layers_post[2]);
3575 }
3576
3577 // Verify the z-order of the layers as a result of calling RecreateLayer when
3578 // the widget is the parent with the layer.
3579 TEST_F(ViewLayerTest, RecreateLayerZOrderWidgetParent) {
3580   View* v = new View();
3581   widget()->SetContentsView(v);
3582
3583   View* v1 = new View();
3584   v1->SetPaintToLayer(true);
3585   v->AddChildView(v1);
3586   View* v2 = new View();
3587   v2->SetPaintToLayer(true);
3588   v->AddChildView(v2);
3589
3590   ui::Layer* root_layer = GetRootLayer();
3591
3592   // Test the initial z-order.
3593   const std::vector<ui::Layer*>& child_layers_pre = root_layer->children();
3594   ASSERT_EQ(2u, child_layers_pre.size());
3595   EXPECT_EQ(v1->layer(), child_layers_pre[0]);
3596   EXPECT_EQ(v2->layer(), child_layers_pre[1]);
3597
3598   scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
3599
3600   // Test the new layer order. |v1_old_layer| should be above the layers
3601   // for |v1| and |v2|.
3602   const std::vector<ui::Layer*>& child_layers_post = root_layer->children();
3603   ASSERT_EQ(3u, child_layers_post.size());
3604   EXPECT_EQ(v1->layer(), child_layers_post[0]);
3605   EXPECT_EQ(v2->layer(), child_layers_post[1]);
3606   EXPECT_EQ(v1_old_layer, child_layers_post[2]);
3607 }
3608
3609 #endif  // USE_AURA
3610
3611 TEST_F(ViewTest, FocusableAssertions) {
3612   // View subclasses may change insets based on whether they are focusable,
3613   // which effects the preferred size. To avoid preferred size changing around
3614   // these Views need to key off the last value set to SetFocusable(), not
3615   // whether the View is focusable right now. For this reason it's important
3616   // that focusable() return the last value passed to SetFocusable and not
3617   // whether the View is focusable right now.
3618   TestView view;
3619   view.SetFocusable(true);
3620   EXPECT_TRUE(view.focusable());
3621   view.SetEnabled(false);
3622   EXPECT_TRUE(view.focusable());
3623   view.SetFocusable(false);
3624   EXPECT_FALSE(view.focusable());
3625 }
3626
3627 }  // namespace views