Chromium Code Reviews| 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" |
| 11 #include "grit/ui_strings.h" | 11 #include "grit/ui_strings.h" |
| 12 #include "ui/aura/window_event_dispatcher.h" | |
| 12 #include "ui/base/accelerators/accelerator.h" | 13 #include "ui/base/accelerators/accelerator.h" |
| 13 #include "ui/base/clipboard/clipboard.h" | 14 #include "ui/base/clipboard/clipboard.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/compositor/compositor.h" | 16 #include "ui/compositor/compositor.h" |
| 16 #include "ui/compositor/layer.h" | 17 #include "ui/compositor/layer.h" |
| 17 #include "ui/compositor/layer_animator.h" | 18 #include "ui/compositor/layer_animator.h" |
| 18 #include "ui/compositor/test/draw_waiter_for_test.h" | 19 #include "ui/compositor/test/draw_waiter_for_test.h" |
| 19 #include "ui/events/event.h" | 20 #include "ui/events/event.h" |
| 21 #include "ui/events/gestures/gesture_recognizer.h" | |
| 20 #include "ui/events/keycodes/keyboard_codes.h" | 22 #include "ui/events/keycodes/keyboard_codes.h" |
| 21 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/path.h" | 24 #include "ui/gfx/path.h" |
| 23 #include "ui/gfx/transform.h" | 25 #include "ui/gfx/transform.h" |
| 24 #include "ui/views/background.h" | 26 #include "ui/views/background.h" |
| 25 #include "ui/views/controls/native/native_view_host.h" | 27 #include "ui/views/controls/native/native_view_host.h" |
| 26 #include "ui/views/controls/scroll_view.h" | 28 #include "ui/views/controls/scroll_view.h" |
| 27 #include "ui/views/controls/textfield/textfield.h" | 29 #include "ui/views/controls/textfield/textfield.h" |
| 28 #include "ui/views/focus/view_storage.h" | 30 #include "ui/views/focus/view_storage.h" |
| 29 #include "ui/views/test/views_test_base.h" | 31 #include "ui/views/test/views_test_base.h" |
| 30 #include "ui/views/view.h" | 32 #include "ui/views/view.h" |
| 31 #include "ui/views/views_delegate.h" | 33 #include "ui/views/views_delegate.h" |
| 32 #include "ui/views/widget/native_widget.h" | 34 #include "ui/views/widget/native_widget.h" |
| 33 #include "ui/views/widget/root_view.h" | 35 #include "ui/views/widget/root_view.h" |
| 34 #include "ui/views/window/dialog_client_view.h" | 36 #include "ui/views/window/dialog_client_view.h" |
| 35 #include "ui/views/window/dialog_delegate.h" | 37 #include "ui/views/window/dialog_delegate.h" |
| 36 | 38 |
| 37 #if defined(OS_WIN) | 39 #if defined(OS_WIN) |
| 38 #include "ui/views/test/test_views_delegate.h" | 40 #include "ui/views/test/test_views_delegate.h" |
| 39 #endif | 41 #endif |
| 40 #if defined(USE_AURA) | |
| 41 #include "ui/aura/window_event_dispatcher.h" | |
| 42 #include "ui/events/gestures/gesture_recognizer.h" | |
| 43 #endif | |
| 44 | 42 |
| 45 using base::ASCIIToUTF16; | 43 using base::ASCIIToUTF16; |
| 46 | 44 |
| 47 namespace { | 45 namespace { |
| 48 | 46 |
| 49 // Returns true if |ancestor| is an ancestor of |layer|. | 47 // Returns true if |ancestor| is an ancestor of |layer|. |
| 50 bool LayerIsAncestor(const ui::Layer* ancestor, const ui::Layer* layer) { | 48 bool LayerIsAncestor(const ui::Layer* ancestor, const ui::Layer* layer) { |
| 51 while (layer && layer != ancestor) | 49 while (layer && layer != ancestor) |
| 52 layer = layer->parent(); | 50 layer = layer->parent(); |
| 53 return layer == ancestor; | 51 return layer == ancestor; |
| (...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1578 } | 1576 } |
| 1579 | 1577 |
| 1580 //////////////////////////////////////////////////////////////////////////////// | 1578 //////////////////////////////////////////////////////////////////////////////// |
| 1581 // Accelerators | 1579 // Accelerators |
| 1582 //////////////////////////////////////////////////////////////////////////////// | 1580 //////////////////////////////////////////////////////////////////////////////// |
| 1583 bool TestView::AcceleratorPressed(const ui::Accelerator& accelerator) { | 1581 bool TestView::AcceleratorPressed(const ui::Accelerator& accelerator) { |
| 1584 accelerator_count_map_[accelerator]++; | 1582 accelerator_count_map_[accelerator]++; |
| 1585 return true; | 1583 return true; |
| 1586 } | 1584 } |
| 1587 | 1585 |
| 1588 #if defined(OS_WIN) && !defined(USE_AURA) | |
|
msw
2014/03/08 01:04:50
nit: these were added in http://crrev.com/99278, p
sky
2014/03/08 01:30:28
Not sure. I'll leave them for now.
| |
| 1589 TEST_F(ViewTest, ActivateAccelerator) { | |
| 1590 // Register a keyboard accelerator before the view is added to a window. | |
| 1591 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); | |
| 1592 TestView* view = new TestView(); | |
| 1593 view->Reset(); | |
| 1594 view->AddAccelerator(return_accelerator); | |
| 1595 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0); | |
| 1596 | |
| 1597 // Create a window and add the view as its child. | |
| 1598 scoped_ptr<Widget> widget(new Widget); | |
| 1599 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | |
| 1600 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 1601 params.bounds = gfx::Rect(0, 0, 100, 100); | |
| 1602 widget->Init(params); | |
| 1603 View* root = widget->GetRootView(); | |
| 1604 root->AddChildView(view); | |
| 1605 widget->Show(); | |
| 1606 | |
| 1607 // Get the focus manager. | |
| 1608 FocusManager* focus_manager = widget->GetFocusManager(); | |
| 1609 ASSERT_TRUE(focus_manager); | |
| 1610 | |
| 1611 // Hit the return key and see if it takes effect. | |
| 1612 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1613 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); | |
| 1614 | |
| 1615 // Hit the escape key. Nothing should happen. | |
| 1616 ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE); | |
| 1617 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator)); | |
| 1618 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); | |
| 1619 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 0); | |
| 1620 | |
| 1621 // Now register the escape key and hit it again. | |
| 1622 view->AddAccelerator(escape_accelerator); | |
| 1623 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); | |
| 1624 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); | |
| 1625 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1); | |
| 1626 | |
| 1627 // Remove the return key accelerator. | |
| 1628 view->RemoveAccelerator(return_accelerator); | |
| 1629 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1630 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1); | |
| 1631 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1); | |
| 1632 | |
| 1633 // Add it again. Hit the return key and the escape key. | |
| 1634 view->AddAccelerator(return_accelerator); | |
| 1635 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1636 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2); | |
| 1637 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1); | |
| 1638 EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator)); | |
| 1639 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2); | |
| 1640 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2); | |
| 1641 | |
| 1642 // Remove all the accelerators. | |
| 1643 view->ResetAccelerators(); | |
| 1644 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1645 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2); | |
| 1646 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2); | |
| 1647 EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator)); | |
| 1648 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2); | |
| 1649 EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2); | |
| 1650 | |
| 1651 widget->CloseNow(); | |
| 1652 } | |
| 1653 #endif | |
| 1654 | |
| 1655 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 1656 TEST_F(ViewTest, HiddenViewWithAccelerator) { | |
| 1657 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); | |
| 1658 TestView* view = new TestView(); | |
| 1659 view->Reset(); | |
| 1660 view->AddAccelerator(return_accelerator); | |
| 1661 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0); | |
| 1662 | |
| 1663 scoped_ptr<Widget> widget(new Widget); | |
| 1664 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | |
| 1665 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 1666 params.bounds = gfx::Rect(0, 0, 100, 100); | |
| 1667 widget->Init(params); | |
| 1668 View* root = widget->GetRootView(); | |
| 1669 root->AddChildView(view); | |
| 1670 widget->Show(); | |
| 1671 | |
| 1672 FocusManager* focus_manager = widget->GetFocusManager(); | |
| 1673 ASSERT_TRUE(focus_manager); | |
| 1674 | |
| 1675 view->SetVisible(false); | |
| 1676 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1677 | |
| 1678 view->SetVisible(true); | |
| 1679 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1680 | |
| 1681 widget->CloseNow(); | |
| 1682 } | |
| 1683 #endif | |
| 1684 | |
| 1685 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 1686 TEST_F(ViewTest, ViewInHiddenWidgetWithAccelerator) { | |
| 1687 ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE); | |
| 1688 TestView* view = new TestView(); | |
| 1689 view->Reset(); | |
| 1690 view->AddAccelerator(return_accelerator); | |
| 1691 EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0); | |
| 1692 | |
| 1693 scoped_ptr<Widget> widget(new Widget); | |
| 1694 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | |
| 1695 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 1696 params.bounds = gfx::Rect(0, 0, 100, 100); | |
| 1697 widget->Init(params); | |
| 1698 View* root = widget->GetRootView(); | |
| 1699 root->AddChildView(view); | |
| 1700 | |
| 1701 FocusManager* focus_manager = widget->GetFocusManager(); | |
| 1702 ASSERT_TRUE(focus_manager); | |
| 1703 | |
| 1704 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1705 EXPECT_EQ(0, view->accelerator_count_map_[return_accelerator]); | |
| 1706 | |
| 1707 widget->Show(); | |
| 1708 EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1709 EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]); | |
| 1710 | |
| 1711 widget->Hide(); | |
| 1712 EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator)); | |
| 1713 EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]); | |
| 1714 | |
| 1715 widget->CloseNow(); | |
| 1716 } | |
| 1717 #endif | |
| 1718 | |
| 1719 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 1720 //////////////////////////////////////////////////////////////////////////////// | |
| 1721 // Mouse-wheel message rerouting | |
| 1722 //////////////////////////////////////////////////////////////////////////////// | |
| 1723 class ScrollableTestView : public View { | |
| 1724 public: | |
| 1725 ScrollableTestView() { } | |
| 1726 | |
| 1727 virtual gfx::Size GetPreferredSize() { | |
| 1728 return gfx::Size(100, 10000); | |
| 1729 } | |
| 1730 | |
| 1731 virtual void Layout() { | |
| 1732 SizeToPreferredSize(); | |
| 1733 } | |
| 1734 }; | |
| 1735 | |
| 1736 class TestViewWithControls : public View { | |
| 1737 public: | |
| 1738 TestViewWithControls() { | |
| 1739 text_field_ = new Textfield(); | |
| 1740 AddChildView(text_field_); | |
| 1741 } | |
| 1742 | |
| 1743 Textfield* text_field_; | |
| 1744 }; | |
| 1745 | |
| 1746 class SimpleWidgetDelegate : public WidgetDelegate { | |
| 1747 public: | |
| 1748 explicit SimpleWidgetDelegate(View* contents) : contents_(contents) { } | |
| 1749 | |
| 1750 virtual void DeleteDelegate() { delete this; } | |
| 1751 | |
| 1752 virtual View* GetContentsView() { return contents_; } | |
| 1753 | |
| 1754 virtual Widget* GetWidget() { return contents_->GetWidget(); } | |
| 1755 virtual const Widget* GetWidget() const { return contents_->GetWidget(); } | |
| 1756 | |
| 1757 private: | |
| 1758 View* contents_; | |
| 1759 }; | |
| 1760 | |
| 1761 // Tests that the mouse-wheel messages are correctly rerouted to the window | |
| 1762 // under the mouse. | |
| 1763 // TODO(jcampan): http://crbug.com/10572 Disabled as it fails on the Vista build | |
| 1764 // bot. | |
| 1765 // Note that this fails for a variety of reasons: | |
| 1766 // - focused view is apparently reset across window activations and never | |
| 1767 // properly restored | |
| 1768 // - this test depends on you not having any other window visible open under the | |
| 1769 // area that it opens the test windows. --beng | |
| 1770 TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) { | |
| 1771 TestViewWithControls* view_with_controls = new TestViewWithControls(); | |
| 1772 Widget* window1 = Widget::CreateWindowWithBounds( | |
| 1773 new SimpleWidgetDelegate(view_with_controls), | |
| 1774 gfx::Rect(0, 0, 100, 100)); | |
| 1775 window1->Show(); | |
| 1776 ScrollView* scroll_view = new ScrollView(); | |
| 1777 scroll_view->SetContents(new ScrollableTestView()); | |
| 1778 Widget* window2 = Widget::CreateWindowWithBounds( | |
| 1779 new SimpleWidgetDelegate(scroll_view), | |
| 1780 gfx::Rect(200, 200, 100, 100)); | |
| 1781 window2->Show(); | |
| 1782 EXPECT_EQ(0, scroll_view->GetVisibleRect().y()); | |
| 1783 | |
| 1784 // Make the window1 active, as this is what it would be in real-world. | |
| 1785 window1->Activate(); | |
| 1786 | |
| 1787 // Let's send a mouse-wheel message to the different controls and check that | |
| 1788 // it is rerouted to the window under the mouse (effectively scrolling the | |
| 1789 // scroll-view). | |
| 1790 | |
| 1791 // First to the Window's HWND. | |
| 1792 ::SendMessage(view_with_controls->GetWidget()->GetNativeView(), | |
| 1793 WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(250, 250)); | |
| 1794 EXPECT_EQ(20, scroll_view->GetVisibleRect().y()); | |
| 1795 | |
| 1796 window1->CloseNow(); | |
| 1797 window2->CloseNow(); | |
| 1798 } | |
| 1799 #endif | |
| 1800 | 1586 |
| 1801 //////////////////////////////////////////////////////////////////////////////// | 1587 //////////////////////////////////////////////////////////////////////////////// |
| 1802 // Native view hierachy | 1588 // Native view hierachy |
| 1803 //////////////////////////////////////////////////////////////////////////////// | 1589 //////////////////////////////////////////////////////////////////////////////// |
| 1804 class ToplevelWidgetObserverView : public View { | 1590 class ToplevelWidgetObserverView : public View { |
| 1805 public: | 1591 public: |
| 1806 ToplevelWidgetObserverView() : toplevel_(NULL) { | 1592 ToplevelWidgetObserverView() : toplevel_(NULL) { |
| 1807 } | 1593 } |
| 1808 virtual ~ToplevelWidgetObserverView() { | 1594 virtual ~ToplevelWidgetObserverView() { |
| 1809 } | 1595 } |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2953 EXPECT_EQ(1, v1.GetIndexOf(&v3)); | 2739 EXPECT_EQ(1, v1.GetIndexOf(&v3)); |
| 2954 v1.AddChildView(&v3); | 2740 v1.AddChildView(&v3); |
| 2955 EXPECT_EQ(0, v1.GetIndexOf(&v2)); | 2741 EXPECT_EQ(0, v1.GetIndexOf(&v2)); |
| 2956 EXPECT_EQ(1, v1.GetIndexOf(&v3)); | 2742 EXPECT_EQ(1, v1.GetIndexOf(&v3)); |
| 2957 } | 2743 } |
| 2958 | 2744 |
| 2959 //////////////////////////////////////////////////////////////////////////////// | 2745 //////////////////////////////////////////////////////////////////////////////// |
| 2960 // Layers | 2746 // Layers |
| 2961 //////////////////////////////////////////////////////////////////////////////// | 2747 //////////////////////////////////////////////////////////////////////////////// |
| 2962 | 2748 |
| 2963 #if defined(USE_AURA) | |
| 2964 | |
| 2965 namespace { | 2749 namespace { |
| 2966 | 2750 |
| 2967 // Test implementation of LayerAnimator. | 2751 // Test implementation of LayerAnimator. |
| 2968 class TestLayerAnimator : public ui::LayerAnimator { | 2752 class TestLayerAnimator : public ui::LayerAnimator { |
| 2969 public: | 2753 public: |
| 2970 TestLayerAnimator(); | 2754 TestLayerAnimator(); |
| 2971 | 2755 |
| 2972 const gfx::Rect& last_bounds() const { return last_bounds_; } | 2756 const gfx::Rect& last_bounds() const { return last_bounds_; } |
| 2973 | 2757 |
| 2974 // LayerAnimator. | 2758 // LayerAnimator. |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3539 | 3323 |
| 3540 // Test the new layer order. |v1_old_layer| should be above the layers | 3324 // Test the new layer order. |v1_old_layer| should be above the layers |
| 3541 // for |v1| and |v2|. | 3325 // for |v1| and |v2|. |
| 3542 const std::vector<ui::Layer*>& child_layers_post = root_layer->children(); | 3326 const std::vector<ui::Layer*>& child_layers_post = root_layer->children(); |
| 3543 ASSERT_EQ(3u, child_layers_post.size()); | 3327 ASSERT_EQ(3u, child_layers_post.size()); |
| 3544 EXPECT_EQ(v1->layer(), child_layers_post[0]); | 3328 EXPECT_EQ(v1->layer(), child_layers_post[0]); |
| 3545 EXPECT_EQ(v2->layer(), child_layers_post[1]); | 3329 EXPECT_EQ(v2->layer(), child_layers_post[1]); |
| 3546 EXPECT_EQ(v1_old_layer, child_layers_post[2]); | 3330 EXPECT_EQ(v1_old_layer, child_layers_post[2]); |
| 3547 } | 3331 } |
| 3548 | 3332 |
| 3549 #endif // USE_AURA | |
| 3550 | |
| 3551 TEST_F(ViewTest, FocusableAssertions) { | 3333 TEST_F(ViewTest, FocusableAssertions) { |
| 3552 // View subclasses may change insets based on whether they are focusable, | 3334 // View subclasses may change insets based on whether they are focusable, |
| 3553 // which effects the preferred size. To avoid preferred size changing around | 3335 // which effects the preferred size. To avoid preferred size changing around |
| 3554 // these Views need to key off the last value set to SetFocusable(), not | 3336 // these Views need to key off the last value set to SetFocusable(), not |
| 3555 // whether the View is focusable right now. For this reason it's important | 3337 // whether the View is focusable right now. For this reason it's important |
| 3556 // that focusable() return the last value passed to SetFocusable and not | 3338 // that focusable() return the last value passed to SetFocusable and not |
| 3557 // whether the View is focusable right now. | 3339 // whether the View is focusable right now. |
| 3558 TestView view; | 3340 TestView view; |
| 3559 view.SetFocusable(true); | 3341 view.SetFocusable(true); |
| 3560 EXPECT_TRUE(view.focusable()); | 3342 EXPECT_TRUE(view.focusable()); |
| 3561 view.SetEnabled(false); | 3343 view.SetEnabled(false); |
| 3562 EXPECT_TRUE(view.focusable()); | 3344 EXPECT_TRUE(view.focusable()); |
| 3563 view.SetFocusable(false); | 3345 view.SetFocusable(false); |
| 3564 EXPECT_FALSE(view.focusable()); | 3346 EXPECT_FALSE(view.focusable()); |
| 3565 } | 3347 } |
| 3566 | 3348 |
| 3567 } // namespace views | 3349 } // namespace views |
| OLD | NEW |