OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; | 233 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; |
234 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; | 234 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; |
235 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; | 235 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; |
236 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; | 236 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; |
237 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; | 237 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; |
238 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; | 238 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; |
239 | 239 |
240 // Ignores GestureEvent by default. | 240 // Ignores GestureEvent by default. |
241 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; | 241 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; |
242 | 242 |
243 virtual void Paint(gfx::Canvas* canvas) OVERRIDE; | 243 virtual void Paint(gfx::Canvas* canvas, const CullSet& cull_set) OVERRIDE; |
244 virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; | 244 virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; |
245 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; | 245 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; |
246 | 246 |
247 virtual void OnNativeThemeChanged(const ui::NativeTheme* native_theme) | 247 virtual void OnNativeThemeChanged(const ui::NativeTheme* native_theme) |
248 OVERRIDE; | 248 OVERRIDE; |
249 | 249 |
250 // OnBoundsChanged. | 250 // OnBoundsChanged. |
251 bool did_change_bounds_; | 251 bool did_change_bounds_; |
252 gfx::Rect new_bounds_; | 252 gfx::Rect new_bounds_; |
253 | 253 |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 EXPECT_EQ(ui::ET_UNKNOWN, v3->last_gesture_event_type_); | 663 EXPECT_EQ(ui::ET_UNKNOWN, v3->last_gesture_event_type_); |
664 EXPECT_EQ("110,110", v1->location_.ToString()); | 664 EXPECT_EQ("110,110", v1->location_.ToString()); |
665 | 665 |
666 widget->CloseNow(); | 666 widget->CloseNow(); |
667 } | 667 } |
668 | 668 |
669 //////////////////////////////////////////////////////////////////////////////// | 669 //////////////////////////////////////////////////////////////////////////////// |
670 // Painting | 670 // Painting |
671 //////////////////////////////////////////////////////////////////////////////// | 671 //////////////////////////////////////////////////////////////////////////////// |
672 | 672 |
673 void TestView::Paint(gfx::Canvas* canvas) { | 673 void TestView::Paint(gfx::Canvas* canvas, const CullSet& cull_set) { |
674 canvas->sk_canvas()->getClipBounds(&last_clip_); | 674 canvas->sk_canvas()->getClipBounds(&last_clip_); |
675 } | 675 } |
676 | 676 |
677 void TestView::SchedulePaintInRect(const gfx::Rect& rect) { | 677 void TestView::SchedulePaintInRect(const gfx::Rect& rect) { |
678 scheduled_paint_rects_.push_back(rect); | 678 scheduled_paint_rects_.push_back(rect); |
679 View::SchedulePaintInRect(rect); | 679 View::SchedulePaintInRect(rect); |
680 } | 680 } |
681 | 681 |
682 void CheckRect(const SkRect& check_rect, const SkRect& target_rect) { | 682 void CheckRect(const SkRect& check_rect, const SkRect& target_rect) { |
683 EXPECT_EQ(target_rect.fLeft, check_rect.fLeft); | 683 EXPECT_EQ(target_rect.fLeft, check_rect.fLeft); |
(...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3456 ASSERT_TRUE(old_layer.get() != NULL); | 3456 ASSERT_TRUE(old_layer.get() != NULL); |
3457 EXPECT_TRUE(old_layer->children().empty()); | 3457 EXPECT_TRUE(old_layer->children().empty()); |
3458 | 3458 |
3459 // And new layer should have the two children. | 3459 // And new layer should have the two children. |
3460 ASSERT_TRUE(v.layer() != NULL); | 3460 ASSERT_TRUE(v.layer() != NULL); |
3461 ASSERT_EQ(2u, v.layer()->children().size()); | 3461 ASSERT_EQ(2u, v.layer()->children().size()); |
3462 EXPECT_EQ(v.layer()->children()[0], &layer); | 3462 EXPECT_EQ(v.layer()->children()[0], &layer); |
3463 EXPECT_EQ(v.layer()->children()[1], child.layer()); | 3463 EXPECT_EQ(v.layer()->children()[1], child.layer()); |
3464 } | 3464 } |
3465 | 3465 |
| 3466 class BoundsTreeTestView : public View { |
| 3467 public: |
| 3468 BoundsTreeTestView() {} |
| 3469 |
| 3470 virtual void PaintChildren(gfx::Canvas* canvas, |
| 3471 const CullSet& cull_set) OVERRIDE { |
| 3472 // Save out a copy of the cull_set before calling the base implementation. |
| 3473 last_cull_set_.clear(); |
| 3474 if (cull_set.cull_set_) { |
| 3475 for (base::hash_set<intptr_t>::iterator it = cull_set.cull_set_->begin(); |
| 3476 it != cull_set.cull_set_->end(); |
| 3477 ++it) { |
| 3478 last_cull_set_.insert(reinterpret_cast<View*>(*it)); |
| 3479 } |
| 3480 } |
| 3481 View::PaintChildren(canvas, cull_set); |
| 3482 } |
| 3483 |
| 3484 std::set<View*> last_cull_set_; |
| 3485 }; |
| 3486 |
| 3487 TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) { |
| 3488 BoundsTreeTestView* test_view = new BoundsTreeTestView; |
| 3489 widget()->SetContentsView(test_view); |
| 3490 |
| 3491 View* v1 = new View(); |
| 3492 v1->SetBoundsRect(gfx::Rect(10, 15, 150, 151)); |
| 3493 test_view->AddChildView(v1); |
| 3494 |
| 3495 View* v2 = new View(); |
| 3496 v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50)); |
| 3497 v1->AddChildView(v2); |
| 3498 |
| 3499 // Schedule a full-view paint to get everyone's rectangles updated. |
| 3500 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3501 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3502 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3503 |
| 3504 // Now we have test_view - v1 - v2. Damage to only test_view should only |
| 3505 // return root_view and test_view. |
| 3506 test_view->SchedulePaintInRect(gfx::Rect(0, 0, 1, 1)); |
| 3507 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3508 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3509 EXPECT_EQ(2U, test_view->last_cull_set_.size()); |
| 3510 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3511 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3512 |
| 3513 // Damage to v1 only should only return root_view, test_view, and v1. |
| 3514 test_view->SchedulePaintInRect(gfx::Rect(11, 16, 1, 1)); |
| 3515 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3516 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3517 EXPECT_EQ(3U, test_view->last_cull_set_.size()); |
| 3518 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3519 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3520 EXPECT_EQ(1U, test_view->last_cull_set_.count(v1)); |
| 3521 |
| 3522 // A Damage rect inside v2 should get all 3 views back in the |last_cull_set_| |
| 3523 // on call to TestView::Paint(), along with the widget root view. |
| 3524 test_view->SchedulePaintInRect(gfx::Rect(31, 49, 1, 1)); |
| 3525 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3526 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3527 EXPECT_EQ(4U, test_view->last_cull_set_.size()); |
| 3528 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3529 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3530 EXPECT_EQ(1U, test_view->last_cull_set_.count(v1)); |
| 3531 EXPECT_EQ(1U, test_view->last_cull_set_.count(v2)); |
| 3532 } |
| 3533 |
| 3534 TEST_F(ViewLayerTest, BoundsTreeSetBoundsChangesCullSet) { |
| 3535 BoundsTreeTestView* test_view = new BoundsTreeTestView; |
| 3536 widget()->SetContentsView(test_view); |
| 3537 |
| 3538 View* v1 = new View; |
| 3539 v1->SetBoundsRect(gfx::Rect(5, 6, 100, 101)); |
| 3540 test_view->AddChildView(v1); |
| 3541 |
| 3542 View* v2 = new View; |
| 3543 v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50)); |
| 3544 v1->AddChildView(v2); |
| 3545 |
| 3546 // Schedule a full-view paint to get everyone's rectangles updated. |
| 3547 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3548 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3549 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3550 |
| 3551 // Move v1 to a new origin out of the way of our next query. |
| 3552 v1->SetBoundsRect(gfx::Rect(50, 60, 100, 101)); |
| 3553 // The move will force a repaint. |
| 3554 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3555 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3556 |
| 3557 // Schedule a paint with damage rect where v1 used to be. |
| 3558 test_view->SchedulePaintInRect(gfx::Rect(5, 6, 10, 11)); |
| 3559 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3560 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3561 |
| 3562 // Should only have picked up root_view and test_view. |
| 3563 EXPECT_EQ(2U, test_view->last_cull_set_.size()); |
| 3564 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3565 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3566 } |
| 3567 |
| 3568 TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) { |
| 3569 BoundsTreeTestView* test_view = new BoundsTreeTestView; |
| 3570 widget()->SetContentsView(test_view); |
| 3571 |
| 3572 View* v1 = new View; |
| 3573 v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20)); |
| 3574 test_view->AddChildView(v1); |
| 3575 |
| 3576 View* v2 = new View; |
| 3577 v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4)); |
| 3578 v1->AddChildView(v2); |
| 3579 |
| 3580 // Schedule a full-view paint to get everyone's rectangles updated. |
| 3581 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3582 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3583 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3584 |
| 3585 // Set v1 to paint to its own layer, it should remove itself from the |
| 3586 // test_view heiarchy and no longer intersect with damage rects in that cull |
| 3587 // set. |
| 3588 v1->SetPaintToLayer(true); |
| 3589 |
| 3590 // Schedule another full-view paint. |
| 3591 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3592 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3593 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3594 // v1 and v2 should no longer be present in the test_view cull_set. |
| 3595 EXPECT_EQ(2U, test_view->last_cull_set_.size()); |
| 3596 EXPECT_EQ(0U, test_view->last_cull_set_.count(v1)); |
| 3597 EXPECT_EQ(0U, test_view->last_cull_set_.count(v2)); |
| 3598 |
| 3599 // Now set v1 back to not painting to a layer. |
| 3600 v1->SetPaintToLayer(false); |
| 3601 // Schedule another full-view paint. |
| 3602 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3603 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3604 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3605 // We should be back to the full cull set including v1 and v2. |
| 3606 EXPECT_EQ(4U, test_view->last_cull_set_.size()); |
| 3607 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3608 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3609 EXPECT_EQ(1U, test_view->last_cull_set_.count(v1)); |
| 3610 EXPECT_EQ(1U, test_view->last_cull_set_.count(v2)); |
| 3611 } |
| 3612 |
| 3613 TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) { |
| 3614 BoundsTreeTestView* test_view = new BoundsTreeTestView; |
| 3615 widget()->SetContentsView(test_view); |
| 3616 |
| 3617 View* v1 = new View; |
| 3618 v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20)); |
| 3619 test_view->AddChildView(v1); |
| 3620 |
| 3621 View* v2 = new View; |
| 3622 v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4)); |
| 3623 v1->AddChildView(v2); |
| 3624 |
| 3625 // Schedule a full-view paint to get everyone's rectangles updated. |
| 3626 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3627 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3628 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3629 |
| 3630 // Now remove v1 from the root view. |
| 3631 test_view->RemoveChildView(v1); |
| 3632 |
| 3633 // Schedule another full-view paint. |
| 3634 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3635 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3636 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3637 // v1 and v2 should no longer be present in the test_view cull_set. |
| 3638 EXPECT_EQ(2U, test_view->last_cull_set_.size()); |
| 3639 EXPECT_EQ(0U, test_view->last_cull_set_.count(v1)); |
| 3640 EXPECT_EQ(0U, test_view->last_cull_set_.count(v2)); |
| 3641 |
| 3642 // View v1 and v2 are no longer part of view hierarchy and therefore won't be |
| 3643 // deleted with that hierarchy. |
| 3644 delete v1; |
| 3645 } |
| 3646 |
| 3647 TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) { |
| 3648 BoundsTreeTestView* test_view = new BoundsTreeTestView; |
| 3649 widget()->SetContentsView(test_view); |
| 3650 |
| 3651 // Build hierarchy v1 - v2 - v3. |
| 3652 View* v1 = new View; |
| 3653 v1->SetBoundsRect(gfx::Rect(20, 30, 150, 160)); |
| 3654 test_view->AddChildView(v1); |
| 3655 |
| 3656 View* v2 = new View; |
| 3657 v2->SetBoundsRect(gfx::Rect(5, 10, 40, 50)); |
| 3658 v1->AddChildView(v2); |
| 3659 |
| 3660 View* v3 = new View; |
| 3661 v3->SetBoundsRect(gfx::Rect(1, 2, 3, 4)); |
| 3662 v2->AddChildView(v3); |
| 3663 |
| 3664 // Schedule a full-view paint and ensure all views are present in the cull. |
| 3665 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3666 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3667 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3668 EXPECT_EQ(5U, test_view->last_cull_set_.size()); |
| 3669 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3670 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3671 EXPECT_EQ(1U, test_view->last_cull_set_.count(v1)); |
| 3672 EXPECT_EQ(1U, test_view->last_cull_set_.count(v2)); |
| 3673 EXPECT_EQ(1U, test_view->last_cull_set_.count(v3)); |
| 3674 |
| 3675 // Build an unrelated view hierarchy and move v2 in to it. |
| 3676 scoped_ptr<Widget> test_widget(new Widget); |
| 3677 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
| 3678 params.bounds = gfx::Rect(10, 10, 500, 500); |
| 3679 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 3680 test_widget->Init(params); |
| 3681 test_widget->Show(); |
| 3682 BoundsTreeTestView* widget_view = new BoundsTreeTestView; |
| 3683 test_widget->SetContentsView(widget_view); |
| 3684 widget_view->AddChildView(v2); |
| 3685 |
| 3686 // Now schedule full-view paints in both widgets. |
| 3687 test_view->SchedulePaintInRect(test_view->bounds()); |
| 3688 widget_view->SchedulePaintInRect(widget_view->bounds()); |
| 3689 GetRootLayer()->GetCompositor()->ScheduleDraw(); |
| 3690 ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); |
| 3691 |
| 3692 // Only v1 should be present in the first cull set. |
| 3693 EXPECT_EQ(3U, test_view->last_cull_set_.size()); |
| 3694 EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); |
| 3695 EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); |
| 3696 EXPECT_EQ(1U, test_view->last_cull_set_.count(v1)); |
| 3697 |
| 3698 // We should find v2 and v3 in the widget_view cull_set. |
| 3699 EXPECT_EQ(4U, widget_view->last_cull_set_.size()); |
| 3700 EXPECT_EQ(1U, widget_view->last_cull_set_.count(test_widget->GetRootView())); |
| 3701 EXPECT_EQ(1U, widget_view->last_cull_set_.count(widget_view)); |
| 3702 EXPECT_EQ(1U, widget_view->last_cull_set_.count(v2)); |
| 3703 EXPECT_EQ(1U, widget_view->last_cull_set_.count(v3)); |
| 3704 } |
| 3705 |
3466 TEST_F(ViewTest, FocusableAssertions) { | 3706 TEST_F(ViewTest, FocusableAssertions) { |
3467 // View subclasses may change insets based on whether they are focusable, | 3707 // View subclasses may change insets based on whether they are focusable, |
3468 // which effects the preferred size. To avoid preferred size changing around | 3708 // which effects the preferred size. To avoid preferred size changing around |
3469 // these Views need to key off the last value set to SetFocusable(), not | 3709 // these Views need to key off the last value set to SetFocusable(), not |
3470 // whether the View is focusable right now. For this reason it's important | 3710 // whether the View is focusable right now. For this reason it's important |
3471 // that focusable() return the last value passed to SetFocusable and not | 3711 // that focusable() return the last value passed to SetFocusable and not |
3472 // whether the View is focusable right now. | 3712 // whether the View is focusable right now. |
3473 TestView view; | 3713 TestView view; |
3474 view.SetFocusable(true); | 3714 view.SetFocusable(true); |
3475 EXPECT_TRUE(view.focusable()); | 3715 EXPECT_TRUE(view.focusable()); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3658 // notification. | 3898 // notification. |
3659 TestView* test_view_child_2 = new TestView(); | 3899 TestView* test_view_child_2 = new TestView(); |
3660 test_view->AddChildView(test_view_child_2); | 3900 test_view->AddChildView(test_view_child_2); |
3661 EXPECT_TRUE(test_view_child_2->native_theme_); | 3901 EXPECT_TRUE(test_view_child_2->native_theme_); |
3662 EXPECT_EQ(widget->GetNativeTheme(), test_view_child_2->native_theme_); | 3902 EXPECT_EQ(widget->GetNativeTheme(), test_view_child_2->native_theme_); |
3663 | 3903 |
3664 widget->CloseNow(); | 3904 widget->CloseNow(); |
3665 } | 3905 } |
3666 | 3906 |
3667 } // namespace views | 3907 } // namespace views |
OLD | NEW |