| 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 "ui/views/focus/focus_manager.h" | 5 #include "ui/views/focus/focus_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 } | 36 } |
| 37 | 37 |
| 38 FocusTestEventType type; | 38 FocusTestEventType type; |
| 39 int view_id; | 39 int view_id; |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 class SimpleTestView : public View { | 42 class SimpleTestView : public View { |
| 43 public: | 43 public: |
| 44 SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id) | 44 SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id) |
| 45 : event_list_(event_list) { | 45 : event_list_(event_list) { |
| 46 SetFocusable(true); | 46 SetFocusBehavior(FocusBehavior::ALWAYS); |
| 47 set_id(view_id); | 47 set_id(view_id); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void OnFocus() override { | 50 void OnFocus() override { |
| 51 event_list_->push_back(FocusTestEvent(ON_FOCUS, id())); | 51 event_list_->push_back(FocusTestEvent(ON_FOCUS, id())); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void OnBlur() override { | 54 void OnBlur() override { |
| 55 event_list_->push_back(FocusTestEvent(ON_BLUR, id())); | 55 event_list_->push_back(FocusTestEvent(ON_BLUR, id())); |
| 56 } | 56 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 88 |
| 89 event_list.clear(); | 89 event_list.clear(); |
| 90 GetFocusManager()->ClearFocus(); | 90 GetFocusManager()->ClearFocus(); |
| 91 ASSERT_EQ(1, static_cast<int>(event_list.size())); | 91 ASSERT_EQ(1, static_cast<int>(event_list.size())); |
| 92 EXPECT_EQ(ON_BLUR, event_list[0].type); | 92 EXPECT_EQ(ON_BLUR, event_list[0].type); |
| 93 EXPECT_EQ(kView2ID, event_list[0].view_id); | 93 EXPECT_EQ(kView2ID, event_list[0].view_id); |
| 94 } | 94 } |
| 95 | 95 |
| 96 TEST_F(FocusManagerTest, FocusChangeListener) { | 96 TEST_F(FocusManagerTest, FocusChangeListener) { |
| 97 View* view1 = new View(); | 97 View* view1 = new View(); |
| 98 view1->SetFocusable(true); | 98 view1->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 99 View* view2 = new View(); | 99 View* view2 = new View(); |
| 100 view2->SetFocusable(true); | 100 view2->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 101 GetContentsView()->AddChildView(view1); | 101 GetContentsView()->AddChildView(view1); |
| 102 GetContentsView()->AddChildView(view2); | 102 GetContentsView()->AddChildView(view2); |
| 103 | 103 |
| 104 TestFocusChangeListener listener; | 104 TestFocusChangeListener listener; |
| 105 AddFocusChangeListener(&listener); | 105 AddFocusChangeListener(&listener); |
| 106 | 106 |
| 107 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | 107 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair |
| 108 views::View* null_view = NULL; | 108 views::View* null_view = NULL; |
| 109 | 109 |
| 110 view1->RequestFocus(); | 110 view1->RequestFocus(); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView); | 552 DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView); |
| 553 }; | 553 }; |
| 554 } // namespace | 554 } // namespace |
| 555 | 555 |
| 556 // Verifies a focus change done during a call to | 556 // Verifies a focus change done during a call to |
| 557 // AboutToRequestFocusFromTabTraversal() is honored. | 557 // AboutToRequestFocusFromTabTraversal() is honored. |
| 558 TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) { | 558 TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) { |
| 559 // Create 3 views focuses the 3 and advances to the second. The 2nd views | 559 // Create 3 views focuses the 3 and advances to the second. The 2nd views |
| 560 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first. | 560 // implementation of AboutToRequestFocusFromTabTraversal() focuses the first. |
| 561 views::View* v1 = new View; | 561 views::View* v1 = new View; |
| 562 v1->SetFocusable(true); | 562 v1->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 563 GetContentsView()->AddChildView(v1); | 563 GetContentsView()->AddChildView(v1); |
| 564 | 564 |
| 565 FocusInAboutToRequestFocusFromTabTraversalView* v2 = | 565 FocusInAboutToRequestFocusFromTabTraversalView* v2 = |
| 566 new FocusInAboutToRequestFocusFromTabTraversalView; | 566 new FocusInAboutToRequestFocusFromTabTraversalView; |
| 567 v2->SetFocusable(true); | 567 v2->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 568 v2->set_view_to_focus(v1); | 568 v2->set_view_to_focus(v1); |
| 569 GetContentsView()->AddChildView(v2); | 569 GetContentsView()->AddChildView(v2); |
| 570 | 570 |
| 571 views::View* v3 = new View; | 571 views::View* v3 = new View; |
| 572 v3->SetFocusable(true); | 572 v3->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 573 GetContentsView()->AddChildView(v3); | 573 GetContentsView()->AddChildView(v3); |
| 574 | 574 |
| 575 v3->RequestFocus(); | 575 v3->RequestFocus(); |
| 576 GetWidget()->GetFocusManager()->AdvanceFocus(true); | 576 GetWidget()->GetFocusManager()->AdvanceFocus(true); |
| 577 EXPECT_TRUE(v1->HasFocus()); | 577 EXPECT_TRUE(v1->HasFocus()); |
| 578 } | 578 } |
| 579 | 579 |
| 580 TEST_F(FocusManagerTest, RotatePaneFocus) { | 580 TEST_F(FocusManagerTest, RotatePaneFocus) { |
| 581 views::AccessiblePaneView* pane1 = new AccessiblePaneView(); | 581 views::AccessiblePaneView* pane1 = new AccessiblePaneView(); |
| 582 GetContentsView()->AddChildView(pane1); | 582 GetContentsView()->AddChildView(pane1); |
| 583 | 583 |
| 584 views::View* v1 = new View; | 584 views::View* v1 = new View; |
| 585 v1->SetFocusable(true); | 585 v1->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 586 pane1->AddChildView(v1); | 586 pane1->AddChildView(v1); |
| 587 | 587 |
| 588 views::View* v2 = new View; | 588 views::View* v2 = new View; |
| 589 v2->SetFocusable(true); | 589 v2->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 590 pane1->AddChildView(v2); | 590 pane1->AddChildView(v2); |
| 591 | 591 |
| 592 views::AccessiblePaneView* pane2 = new AccessiblePaneView(); | 592 views::AccessiblePaneView* pane2 = new AccessiblePaneView(); |
| 593 GetContentsView()->AddChildView(pane2); | 593 GetContentsView()->AddChildView(pane2); |
| 594 | 594 |
| 595 views::View* v3 = new View; | 595 views::View* v3 = new View; |
| 596 v3->SetFocusable(true); | 596 v3->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 597 pane2->AddChildView(v3); | 597 pane2->AddChildView(v3); |
| 598 | 598 |
| 599 views::View* v4 = new View; | 599 views::View* v4 = new View; |
| 600 v4->SetFocusable(true); | 600 v4->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 601 pane2->AddChildView(v4); | 601 pane2->AddChildView(v4); |
| 602 | 602 |
| 603 std::vector<views::View*> panes; | 603 std::vector<views::View*> panes; |
| 604 panes.push_back(pane1); | 604 panes.push_back(pane1); |
| 605 panes.push_back(pane2); | 605 panes.push_back(pane2); |
| 606 SetAccessiblePanes(panes); | 606 SetAccessiblePanes(panes); |
| 607 | 607 |
| 608 FocusManager* focus_manager = GetWidget()->GetFocusManager(); | 608 FocusManager* focus_manager = GetWidget()->GetFocusManager(); |
| 609 | 609 |
| 610 // Advance forwards. Focus should stay trapped within each pane. | 610 // Advance forwards. Focus should stay trapped within each pane. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 EXPECT_EQ(v3, focus_manager->GetFocusedView()); | 645 EXPECT_EQ(v3, focus_manager->GetFocusedView()); |
| 646 | 646 |
| 647 EXPECT_FALSE(focus_manager->RotatePaneFocus( | 647 EXPECT_FALSE(focus_manager->RotatePaneFocus( |
| 648 FocusManager::kForward, FocusManager::kNoWrap)); | 648 FocusManager::kForward, FocusManager::kNoWrap)); |
| 649 EXPECT_EQ(v3, focus_manager->GetFocusedView()); | 649 EXPECT_EQ(v3, focus_manager->GetFocusedView()); |
| 650 } | 650 } |
| 651 | 651 |
| 652 // Verifies the stored focus view tracks the focused view. | 652 // Verifies the stored focus view tracks the focused view. |
| 653 TEST_F(FocusManagerTest, ImplicitlyStoresFocus) { | 653 TEST_F(FocusManagerTest, ImplicitlyStoresFocus) { |
| 654 views::View* v1 = new View; | 654 views::View* v1 = new View; |
| 655 v1->SetFocusable(true); | 655 v1->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 656 GetContentsView()->AddChildView(v1); | 656 GetContentsView()->AddChildView(v1); |
| 657 | 657 |
| 658 views::View* v2 = new View; | 658 views::View* v2 = new View; |
| 659 v2->SetFocusable(true); | 659 v2->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 660 GetContentsView()->AddChildView(v2); | 660 GetContentsView()->AddChildView(v2); |
| 661 | 661 |
| 662 // Verify a focus request on |v1| implicitly updates the stored focus view. | 662 // Verify a focus request on |v1| implicitly updates the stored focus view. |
| 663 v1->RequestFocus(); | 663 v1->RequestFocus(); |
| 664 EXPECT_TRUE(v1->HasFocus()); | 664 EXPECT_TRUE(v1->HasFocus()); |
| 665 EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView()); | 665 EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView()); |
| 666 | 666 |
| 667 // Verify a focus request on |v2| implicitly updates the stored focus view. | 667 // Verify a focus request on |v2| implicitly updates the stored focus view. |
| 668 v2->RequestFocus(); | 668 v2->RequestFocus(); |
| 669 EXPECT_TRUE(v2->HasFocus()); | 669 EXPECT_TRUE(v2->HasFocus()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) { | 703 TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) { |
| 704 FocusManager* focus_manager = GetFocusManager(); | 704 FocusManager* focus_manager = GetFocusManager(); |
| 705 const ui::KeyEvent left_key(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE); | 705 const ui::KeyEvent left_key(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE); |
| 706 const ui::KeyEvent right_key(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE); | 706 const ui::KeyEvent right_key(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE); |
| 707 const ui::KeyEvent up_key(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE); | 707 const ui::KeyEvent up_key(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE); |
| 708 const ui::KeyEvent down_key(ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE); | 708 const ui::KeyEvent down_key(ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE); |
| 709 | 709 |
| 710 std::vector<views::View*> v; | 710 std::vector<views::View*> v; |
| 711 for (size_t i = 0; i < 2; ++i) { | 711 for (size_t i = 0; i < 2; ++i) { |
| 712 views::View* view = new View; | 712 views::View* view = new View; |
| 713 view->SetFocusable(true); | 713 view->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 714 GetContentsView()->AddChildView(view); | 714 GetContentsView()->AddChildView(view); |
| 715 v.push_back(view); | 715 v.push_back(view); |
| 716 } | 716 } |
| 717 | 717 |
| 718 // Arrow key traversal is off and arrow key does not change focus. | 718 // Arrow key traversal is off and arrow key does not change focus. |
| 719 FocusManager::set_arrow_key_traversal_enabled(false); | 719 FocusManager::set_arrow_key_traversal_enabled(false); |
| 720 v[0]->RequestFocus(); | 720 v[0]->RequestFocus(); |
| 721 focus_manager->OnKeyEvent(right_key); | 721 focus_manager->OnKeyEvent(right_key); |
| 722 EXPECT_EQ(v[0], focus_manager->GetFocusedView()); | 722 EXPECT_EQ(v[0], focus_manager->GetFocusedView()); |
| 723 focus_manager->OnKeyEvent(left_key); | 723 focus_manager->OnKeyEvent(left_key); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 | 784 |
| 785 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate); | 785 DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate); |
| 786 }; | 786 }; |
| 787 | 787 |
| 788 } // namespace | 788 } // namespace |
| 789 | 789 |
| 790 // Verifies focus wrapping happens in the same widget. | 790 // Verifies focus wrapping happens in the same widget. |
| 791 TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) { | 791 TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) { |
| 792 // Add |widget_view| as a child of the Widget. | 792 // Add |widget_view| as a child of the Widget. |
| 793 View* widget_view = new View; | 793 View* widget_view = new View; |
| 794 widget_view->SetFocusable(true); | 794 widget_view->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 795 widget_view->SetBounds(20, 0, 20, 20); | 795 widget_view->SetBounds(20, 0, 20, 20); |
| 796 GetContentsView()->AddChildView(widget_view); | 796 GetContentsView()->AddChildView(widget_view); |
| 797 | 797 |
| 798 // Create a widget with two views, focus the second. | 798 // Create a widget with two views, focus the second. |
| 799 std::unique_ptr<AdvanceFocusWidgetDelegate> delegate; | 799 std::unique_ptr<AdvanceFocusWidgetDelegate> delegate; |
| 800 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); | 800 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
| 801 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 801 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 802 params.child = true; | 802 params.child = true; |
| 803 params.bounds = gfx::Rect(10, 10, 100, 100); | 803 params.bounds = gfx::Rect(10, 10, 100, 100); |
| 804 params.parent = GetWidget()->GetNativeView(); | 804 params.parent = GetWidget()->GetNativeView(); |
| 805 Widget child_widget; | 805 Widget child_widget; |
| 806 delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget)); | 806 delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget)); |
| 807 params.delegate = delegate.get(); | 807 params.delegate = delegate.get(); |
| 808 child_widget.Init(params); | 808 child_widget.Init(params); |
| 809 View* view1 = new View; | 809 View* view1 = new View; |
| 810 view1->SetFocusable(true); | 810 view1->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 811 view1->SetBounds(0, 0, 20, 20); | 811 view1->SetBounds(0, 0, 20, 20); |
| 812 View* view2 = new View; | 812 View* view2 = new View; |
| 813 view2->SetFocusable(true); | 813 view2->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 814 view2->SetBounds(20, 0, 20, 20); | 814 view2->SetBounds(20, 0, 20, 20); |
| 815 child_widget.client_view()->AddChildView(view1); | 815 child_widget.client_view()->AddChildView(view1); |
| 816 child_widget.client_view()->AddChildView(view2); | 816 child_widget.client_view()->AddChildView(view2); |
| 817 child_widget.Show(); | 817 child_widget.Show(); |
| 818 view2->RequestFocus(); | 818 view2->RequestFocus(); |
| 819 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView()); | 819 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView()); |
| 820 | 820 |
| 821 // Advance focus backwards, which should focus the first. | 821 // Advance focus backwards, which should focus the first. |
| 822 GetFocusManager()->AdvanceFocus(false); | 822 GetFocusManager()->AdvanceFocus(false); |
| 823 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView()); | 823 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView()); |
| 824 | 824 |
| 825 // Focus forward to |view2|. | 825 // Focus forward to |view2|. |
| 826 GetFocusManager()->AdvanceFocus(true); | 826 GetFocusManager()->AdvanceFocus(true); |
| 827 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView()); | 827 EXPECT_EQ(view2, GetFocusManager()->GetFocusedView()); |
| 828 | 828 |
| 829 // And forward again, wrapping back to |view1|. | 829 // And forward again, wrapping back to |view1|. |
| 830 GetFocusManager()->AdvanceFocus(true); | 830 GetFocusManager()->AdvanceFocus(true); |
| 831 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView()); | 831 EXPECT_EQ(view1, GetFocusManager()->GetFocusedView()); |
| 832 | 832 |
| 833 // Allow focus to go to the parent, and focus backwards which should now move | 833 // Allow focus to go to the parent, and focus backwards which should now move |
| 834 // up |widget_view| (in the parent). | 834 // up |widget_view| (in the parent). |
| 835 delegate->set_should_advance_focus_to_parent(true); | 835 delegate->set_should_advance_focus_to_parent(true); |
| 836 GetFocusManager()->AdvanceFocus(true); | 836 GetFocusManager()->AdvanceFocus(true); |
| 837 EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView()); | 837 EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView()); |
| 838 } | 838 } |
| 839 | 839 |
| 840 } // namespace views | 840 } // namespace views |
| OLD | NEW |