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 <stddef.h> |
6 | 6 |
7 #include <stddef.h> | 7 #include <iterator> |
tapted
2016/05/04 06:47:38
nit: no longer needed. (maybe bring back stddef.h
karandeepb
2016/05/04 07:13:03
Done. stddef.h is still here. Had to move focus_ma
| |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "ui/base/models/combobox_model.h" | 13 #include "ui/base/models/combobox_model.h" |
14 #include "ui/views/background.h" | 14 #include "ui/views/background.h" |
15 #include "ui/views/border.h" | 15 #include "ui/views/border.h" |
16 #include "ui/views/controls/button/checkbox.h" | 16 #include "ui/views/controls/button/checkbox.h" |
17 #include "ui/views/controls/button/label_button.h" | 17 #include "ui/views/controls/button/label_button.h" |
18 #include "ui/views/controls/button/radio_button.h" | 18 #include "ui/views/controls/button/radio_button.h" |
19 #include "ui/views/controls/combobox/combobox.h" | 19 #include "ui/views/controls/combobox/combobox.h" |
20 #include "ui/views/controls/label.h" | 20 #include "ui/views/controls/label.h" |
21 #include "ui/views/controls/link.h" | 21 #include "ui/views/controls/link.h" |
22 #include "ui/views/controls/native/native_view_host.h" | 22 #include "ui/views/controls/native/native_view_host.h" |
23 #include "ui/views/controls/scroll_view.h" | 23 #include "ui/views/controls/scroll_view.h" |
24 #include "ui/views/controls/tabbed_pane/tabbed_pane.h" | 24 #include "ui/views/controls/tabbed_pane/tabbed_pane.h" |
25 #include "ui/views/controls/textfield/textfield.h" | 25 #include "ui/views/controls/textfield/textfield.h" |
26 #include "ui/views/focus/focus_manager.h" | |
26 #include "ui/views/test/focus_manager_test.h" | 27 #include "ui/views/test/focus_manager_test.h" |
27 #include "ui/views/widget/root_view.h" | 28 #include "ui/views/widget/root_view.h" |
28 #include "ui/views/widget/widget.h" | 29 #include "ui/views/widget/widget.h" |
29 | 30 |
30 using base::ASCIIToUTF16; | 31 using base::ASCIIToUTF16; |
31 | 32 |
32 namespace views { | 33 namespace views { |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 view = style_tab_->GetSelectedTab()->GetViewByID(id); | 196 view = style_tab_->GetSelectedTab()->GetViewByID(id); |
196 if (view) | 197 if (view) |
197 return view; | 198 return view; |
198 view = search_border_view_->GetContentsRootView()->GetViewByID(id); | 199 view = search_border_view_->GetContentsRootView()->GetViewByID(id); |
199 if (view) | 200 if (view) |
200 return view; | 201 return view; |
201 return NULL; | 202 return NULL; |
202 } | 203 } |
203 | 204 |
204 protected: | 205 protected: |
206 // Helper function to advance focus multiple times in a loop. |traversal_ids| | |
207 // is an array of view ids of length |N|. |reverse| denotes the direction in | |
208 // which focus should be advanced. | |
209 template <size_t N> | |
210 void AdvanceEntireFocusLoop(const int (&traversal_ids)[N], bool reverse) { | |
211 for (size_t i = 0; i < 3; ++i) { | |
212 for (size_t j = 0; j < N; j++) { | |
213 SCOPED_TRACE(testing::Message() << "reverse:" << reverse << " i:" << i | |
214 << " j:" << j); | |
215 GetFocusManager()->AdvanceFocus(reverse); | |
216 View* focused_view = GetFocusManager()->GetFocusedView(); | |
217 EXPECT_NE(nullptr, focused_view); | |
218 if (focused_view) | |
219 EXPECT_EQ(traversal_ids[reverse ? N - j - 1 : j], focused_view->id()); | |
220 } | |
221 } | |
222 } | |
223 | |
205 TabbedPane* style_tab_; | 224 TabbedPane* style_tab_; |
206 BorderView* search_border_view_; | 225 BorderView* search_border_view_; |
207 DummyComboboxModel combobox_model_; | 226 DummyComboboxModel combobox_model_; |
208 PaneView* left_container_; | 227 PaneView* left_container_; |
209 PaneView* right_container_; | 228 PaneView* right_container_; |
210 | 229 |
211 DISALLOW_COPY_AND_ASSIGN(FocusTraversalTest); | 230 DISALLOW_COPY_AND_ASSIGN(FocusTraversalTest); |
212 }; | 231 }; |
213 | 232 |
214 FocusTraversalTest::FocusTraversalTest() | 233 FocusTraversalTest::FocusTraversalTest() |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 kFruitButtonID, kFruitCheckBoxID, kComboboxID, kBroccoliButtonID, | 589 kFruitButtonID, kFruitCheckBoxID, kComboboxID, kBroccoliButtonID, |
571 kRosettaLinkID, kStupeurEtTremblementLinkID, | 590 kRosettaLinkID, kStupeurEtTremblementLinkID, |
572 kDinerGameLinkID, kRidiculeLinkID, kClosetLinkID, kVisitingLinkID, | 591 kDinerGameLinkID, kRidiculeLinkID, kClosetLinkID, kVisitingLinkID, |
573 kAmelieLinkID, kJoyeuxNoelLinkID, kCampingLinkID, kBriceDeNiceLinkID, | 592 kAmelieLinkID, kJoyeuxNoelLinkID, kCampingLinkID, kBriceDeNiceLinkID, |
574 kTaxiLinkID, kAsterixLinkID, kOKButtonID, kCancelButtonID, kHelpButtonID, | 593 kTaxiLinkID, kAsterixLinkID, kOKButtonID, kCancelButtonID, kHelpButtonID, |
575 kStyleContainerID, kBoldCheckBoxID, kItalicCheckBoxID, | 594 kStyleContainerID, kBoldCheckBoxID, kItalicCheckBoxID, |
576 kUnderlinedCheckBoxID, kStyleHelpLinkID, kStyleTextEditID, | 595 kUnderlinedCheckBoxID, kStyleHelpLinkID, kStyleTextEditID, |
577 kSearchTextfieldID, kSearchButtonID, kHelpLinkID, | 596 kSearchTextfieldID, kSearchButtonID, kHelpLinkID, |
578 kThumbnailContainerID, kThumbnailStarID, kThumbnailSuperStarID }; | 597 kThumbnailContainerID, kThumbnailStarID, kThumbnailSuperStarID }; |
579 | 598 |
599 SCOPED_TRACE("NormalTraversal"); | |
600 | |
580 // Let's traverse the whole focus hierarchy (several times, to make sure it | 601 // Let's traverse the whole focus hierarchy (several times, to make sure it |
581 // loops OK). | 602 // loops OK). |
582 GetFocusManager()->ClearFocus(); | 603 GetFocusManager()->ClearFocus(); |
583 for (int i = 0; i < 3; ++i) { | 604 AdvanceEntireFocusLoop(kTraversalIDs, false); |
584 for (size_t j = 0; j < arraysize(kTraversalIDs); j++) { | |
585 GetFocusManager()->AdvanceFocus(false); | |
586 View* focused_view = GetFocusManager()->GetFocusedView(); | |
587 EXPECT_TRUE(focused_view != NULL); | |
588 if (focused_view) | |
589 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
590 } | |
591 } | |
592 | 605 |
593 // Let's traverse in reverse order. | 606 // Let's traverse in reverse order. |
594 GetFocusManager()->ClearFocus(); | 607 GetFocusManager()->ClearFocus(); |
595 for (int i = 0; i < 3; ++i) { | 608 AdvanceEntireFocusLoop(kTraversalIDs, true); |
596 for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) { | |
597 GetFocusManager()->AdvanceFocus(true); | |
598 View* focused_view = GetFocusManager()->GetFocusedView(); | |
599 EXPECT_TRUE(focused_view != NULL); | |
600 if (focused_view) | |
601 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
602 } | |
603 } | |
604 } | 609 } |
605 | 610 |
611 #if defined(OS_MACOSX) | |
612 // Test focus traversal with full keyboard access off on Mac. | |
613 TEST_F(FocusTraversalTest, NormalTraversalMac) { | |
614 GetFocusManager()->SetKeyboardAccessible(false); | |
615 | |
616 // Now only views with FocusBehavior of ALWAYS will be focusable. | |
617 const int kTraversalIDs[] = {kAppleTextfieldID, kOrangeTextfieldID, | |
618 kBananaTextfieldID, kKiwiTextfieldID, | |
619 kStyleTextEditID, kSearchTextfieldID, | |
620 kThumbnailContainerID}; | |
621 | |
622 SCOPED_TRACE("NormalTraversalMac"); | |
623 | |
624 // Let's traverse the whole focus hierarchy (several times, to make sure it | |
625 // loops OK). | |
626 GetFocusManager()->ClearFocus(); | |
627 AdvanceEntireFocusLoop(kTraversalIDs, false); | |
628 | |
629 // Let's traverse in reverse order. | |
630 GetFocusManager()->ClearFocus(); | |
631 AdvanceEntireFocusLoop(kTraversalIDs, true); | |
632 } | |
633 | |
634 // Test toggling full keyboard access correctly changes the focused view on Mac. | |
635 TEST_F(FocusTraversalTest, FullKeyboardToggle) { | |
636 // Give focus to kTopCheckBoxID . | |
637 FindViewByID(kTopCheckBoxID)->RequestFocus(); | |
638 EXPECT_EQ(kTopCheckBoxID, GetFocusManager()->GetFocusedView()->id()); | |
639 | |
640 // Turn off full keyboard access. Focus should move to next view with ALWAYS | |
641 // focus behavior. | |
642 GetFocusManager()->SetKeyboardAccessible(false); | |
643 EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id()); | |
644 | |
645 // Turning on full keyboard access should not change the focused view. | |
646 GetFocusManager()->SetKeyboardAccessible(true); | |
647 EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id()); | |
648 | |
649 // Give focus to kSearchButtonID. | |
650 FindViewByID(kSearchButtonID)->RequestFocus(); | |
651 EXPECT_EQ(kSearchButtonID, GetFocusManager()->GetFocusedView()->id()); | |
652 | |
653 // Turn off full keyboard access. Focus should move to next view with ALWAYS | |
654 // focus behavior. | |
655 GetFocusManager()->SetKeyboardAccessible(false); | |
656 EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id()); | |
657 | |
658 // See focus advances correctly in both directions. | |
659 GetFocusManager()->AdvanceFocus(false); | |
660 EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id()); | |
661 | |
662 GetFocusManager()->AdvanceFocus(true); | |
663 EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id()); | |
664 } | |
665 #endif // OS_MACOSX | |
666 | |
606 TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) { | 667 TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) { |
607 const int kDisabledIDs[] = { | 668 const int kDisabledIDs[] = { |
608 kBananaTextfieldID, kFruitCheckBoxID, kComboboxID, kAsparagusButtonID, | 669 kBananaTextfieldID, kFruitCheckBoxID, kComboboxID, kAsparagusButtonID, |
609 kCauliflowerButtonID, kClosetLinkID, kVisitingLinkID, kBriceDeNiceLinkID, | 670 kCauliflowerButtonID, kClosetLinkID, kVisitingLinkID, kBriceDeNiceLinkID, |
610 kTaxiLinkID, kAsterixLinkID, kHelpButtonID, kBoldCheckBoxID, | 671 kTaxiLinkID, kAsterixLinkID, kHelpButtonID, kBoldCheckBoxID, |
611 kSearchTextfieldID, kHelpLinkID }; | 672 kSearchTextfieldID, kHelpLinkID }; |
612 | 673 |
613 const int kTraversalIDs[] = { kTopCheckBoxID, kAppleTextfieldID, | 674 const int kTraversalIDs[] = { kTopCheckBoxID, kAppleTextfieldID, |
614 kOrangeTextfieldID, kKiwiTextfieldID, kFruitButtonID, kBroccoliButtonID, | 675 kOrangeTextfieldID, kKiwiTextfieldID, kFruitButtonID, kBroccoliButtonID, |
615 kRosettaLinkID, kStupeurEtTremblementLinkID, kDinerGameLinkID, | 676 kRosettaLinkID, kStupeurEtTremblementLinkID, kDinerGameLinkID, |
616 kRidiculeLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, kCampingLinkID, | 677 kRidiculeLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, kCampingLinkID, |
617 kOKButtonID, kCancelButtonID, kStyleContainerID, kItalicCheckBoxID, | 678 kOKButtonID, kCancelButtonID, kStyleContainerID, kItalicCheckBoxID, |
618 kUnderlinedCheckBoxID, kStyleHelpLinkID, kStyleTextEditID, | 679 kUnderlinedCheckBoxID, kStyleHelpLinkID, kStyleTextEditID, |
619 kSearchButtonID, kThumbnailContainerID, kThumbnailStarID, | 680 kSearchButtonID, kThumbnailContainerID, kThumbnailStarID, |
620 kThumbnailSuperStarID }; | 681 kThumbnailSuperStarID }; |
621 | 682 |
683 SCOPED_TRACE("TraversalWithNonEnabledViews"); | |
684 | |
622 // Let's disable some views. | 685 // Let's disable some views. |
623 for (size_t i = 0; i < arraysize(kDisabledIDs); i++) { | 686 for (size_t i = 0; i < arraysize(kDisabledIDs); i++) { |
624 View* v = FindViewByID(kDisabledIDs[i]); | 687 View* v = FindViewByID(kDisabledIDs[i]); |
625 ASSERT_TRUE(v != NULL); | 688 ASSERT_TRUE(v != NULL); |
626 v->SetEnabled(false); | 689 v->SetEnabled(false); |
627 } | 690 } |
628 | 691 |
629 View* focused_view; | |
630 // Let's do one traversal (several times, to make sure it loops ok). | 692 // Let's do one traversal (several times, to make sure it loops ok). |
631 GetFocusManager()->ClearFocus(); | 693 GetFocusManager()->ClearFocus(); |
632 for (int i = 0; i < 3; ++i) { | 694 AdvanceEntireFocusLoop(kTraversalIDs, false); |
633 for (size_t j = 0; j < arraysize(kTraversalIDs); j++) { | |
634 GetFocusManager()->AdvanceFocus(false); | |
635 focused_view = GetFocusManager()->GetFocusedView(); | |
636 EXPECT_TRUE(focused_view != NULL); | |
637 if (focused_view) | |
638 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
639 } | |
640 } | |
641 | 695 |
642 // Same thing in reverse. | 696 // Same thing in reverse. |
643 GetFocusManager()->ClearFocus(); | 697 GetFocusManager()->ClearFocus(); |
644 for (int i = 0; i < 3; ++i) { | 698 AdvanceEntireFocusLoop(kTraversalIDs, true); |
645 for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) { | |
646 GetFocusManager()->AdvanceFocus(true); | |
647 focused_view = GetFocusManager()->GetFocusedView(); | |
648 EXPECT_TRUE(focused_view != NULL); | |
649 if (focused_view) | |
650 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
651 } | |
652 } | |
653 } | 699 } |
654 | 700 |
655 TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) { | 701 TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) { |
656 const int kInvisibleIDs[] = { kTopCheckBoxID, kOKButtonID, | 702 const int kInvisibleIDs[] = { kTopCheckBoxID, kOKButtonID, |
657 kThumbnailContainerID }; | 703 kThumbnailContainerID }; |
658 | 704 |
659 const int kTraversalIDs[] = { kAppleTextfieldID, kOrangeTextfieldID, | 705 const int kTraversalIDs[] = { kAppleTextfieldID, kOrangeTextfieldID, |
660 kBananaTextfieldID, kKiwiTextfieldID, kFruitButtonID, kFruitCheckBoxID, | 706 kBananaTextfieldID, kKiwiTextfieldID, kFruitButtonID, kFruitCheckBoxID, |
661 kComboboxID, kBroccoliButtonID, kRosettaLinkID, | 707 kComboboxID, kBroccoliButtonID, kRosettaLinkID, |
662 kStupeurEtTremblementLinkID, kDinerGameLinkID, kRidiculeLinkID, | 708 kStupeurEtTremblementLinkID, kDinerGameLinkID, kRidiculeLinkID, |
663 kClosetLinkID, kVisitingLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, | 709 kClosetLinkID, kVisitingLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, |
664 kCampingLinkID, kBriceDeNiceLinkID, kTaxiLinkID, kAsterixLinkID, | 710 kCampingLinkID, kBriceDeNiceLinkID, kTaxiLinkID, kAsterixLinkID, |
665 kCancelButtonID, kHelpButtonID, kStyleContainerID, kBoldCheckBoxID, | 711 kCancelButtonID, kHelpButtonID, kStyleContainerID, kBoldCheckBoxID, |
666 kItalicCheckBoxID, kUnderlinedCheckBoxID, kStyleHelpLinkID, | 712 kItalicCheckBoxID, kUnderlinedCheckBoxID, kStyleHelpLinkID, |
667 kStyleTextEditID, kSearchTextfieldID, kSearchButtonID, kHelpLinkID }; | 713 kStyleTextEditID, kSearchTextfieldID, kSearchButtonID, kHelpLinkID }; |
668 | 714 |
715 SCOPED_TRACE("TraversalWithInvisibleViews"); | |
669 | 716 |
670 // Let's make some views invisible. | 717 // Let's make some views invisible. |
671 for (size_t i = 0; i < arraysize(kInvisibleIDs); i++) { | 718 for (size_t i = 0; i < arraysize(kInvisibleIDs); i++) { |
672 View* v = FindViewByID(kInvisibleIDs[i]); | 719 View* v = FindViewByID(kInvisibleIDs[i]); |
673 ASSERT_TRUE(v != NULL); | 720 ASSERT_TRUE(v != NULL); |
674 v->SetVisible(false); | 721 v->SetVisible(false); |
675 } | 722 } |
676 | 723 |
677 View* focused_view; | |
678 // Let's do one traversal (several times, to make sure it loops ok). | 724 // Let's do one traversal (several times, to make sure it loops ok). |
679 GetFocusManager()->ClearFocus(); | 725 GetFocusManager()->ClearFocus(); |
680 for (int i = 0; i < 3; ++i) { | 726 AdvanceEntireFocusLoop(kTraversalIDs, false); |
681 for (size_t j = 0; j < arraysize(kTraversalIDs); j++) { | |
682 GetFocusManager()->AdvanceFocus(false); | |
683 focused_view = GetFocusManager()->GetFocusedView(); | |
684 EXPECT_TRUE(focused_view != NULL); | |
685 if (focused_view) | |
686 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
687 } | |
688 } | |
689 | 727 |
690 // Same thing in reverse. | 728 // Same thing in reverse. |
691 GetFocusManager()->ClearFocus(); | 729 GetFocusManager()->ClearFocus(); |
692 for (int i = 0; i < 3; ++i) { | 730 AdvanceEntireFocusLoop(kTraversalIDs, true); |
693 for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) { | |
694 GetFocusManager()->AdvanceFocus(true); | |
695 focused_view = GetFocusManager()->GetFocusedView(); | |
696 EXPECT_TRUE(focused_view != NULL); | |
697 if (focused_view) | |
698 EXPECT_EQ(kTraversalIDs[j], focused_view->id()); | |
699 } | |
700 } | |
701 } | 731 } |
702 | 732 |
703 TEST_F(FocusTraversalTest, PaneTraversal) { | 733 TEST_F(FocusTraversalTest, PaneTraversal) { |
704 // Tests trapping the traversal within a pane - useful for full | 734 // Tests trapping the traversal within a pane - useful for full |
705 // keyboard accessibility for toolbars. | 735 // keyboard accessibility for toolbars. |
706 | 736 |
707 // First test the left container. | 737 // First test the left container. |
708 const int kLeftTraversalIDs[] = { | 738 const int kLeftTraversalIDs[] = { |
709 kAppleTextfieldID, | 739 kAppleTextfieldID, |
710 kOrangeTextfieldID, kBananaTextfieldID, kKiwiTextfieldID, | 740 kOrangeTextfieldID, kBananaTextfieldID, kKiwiTextfieldID, |
711 kFruitButtonID, kFruitCheckBoxID, kComboboxID }; | 741 kFruitButtonID, kFruitCheckBoxID, kComboboxID }; |
712 | 742 |
743 SCOPED_TRACE("PaneTraversal"); | |
744 | |
713 FocusSearch focus_search_left(left_container_, true, false); | 745 FocusSearch focus_search_left(left_container_, true, false); |
714 left_container_->EnablePaneFocus(&focus_search_left); | 746 left_container_->EnablePaneFocus(&focus_search_left); |
715 FindViewByID(kComboboxID)->RequestFocus(); | 747 FindViewByID(kComboboxID)->RequestFocus(); |
716 | 748 |
717 // Traverse the focus hierarchy within the pane several times. | 749 // Traverse the focus hierarchy within the pane several times. |
718 for (int i = 0; i < 3; ++i) { | 750 AdvanceEntireFocusLoop(kLeftTraversalIDs, false); |
719 for (size_t j = 0; j < arraysize(kLeftTraversalIDs); j++) { | |
720 GetFocusManager()->AdvanceFocus(false); | |
721 View* focused_view = GetFocusManager()->GetFocusedView(); | |
722 EXPECT_TRUE(focused_view != NULL); | |
723 if (focused_view) | |
724 EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id()); | |
725 } | |
726 } | |
727 | 751 |
728 // Traverse in reverse order. | 752 // Traverse in reverse order. |
729 FindViewByID(kAppleTextfieldID)->RequestFocus(); | 753 FindViewByID(kAppleTextfieldID)->RequestFocus(); |
730 for (int i = 0; i < 3; ++i) { | 754 AdvanceEntireFocusLoop(kLeftTraversalIDs, true); |
731 for (int j = arraysize(kLeftTraversalIDs) - 1; j >= 0; --j) { | |
732 GetFocusManager()->AdvanceFocus(true); | |
733 View* focused_view = GetFocusManager()->GetFocusedView(); | |
734 EXPECT_TRUE(focused_view != NULL); | |
735 if (focused_view) | |
736 EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id()); | |
737 } | |
738 } | |
739 | 755 |
740 // Now test the right container, but this time with accessibility mode. | 756 // Now test the right container, but this time with accessibility mode. |
741 // Make some links not focusable, but mark one of them as | 757 // Make some links not focusable, but mark one of them as |
742 // "accessibility focusable", so it should show up in the traversal. | 758 // "accessibility focusable", so it should show up in the traversal. |
743 const int kRightTraversalIDs[] = { | 759 const int kRightTraversalIDs[] = { |
744 kBroccoliButtonID, kDinerGameLinkID, kRidiculeLinkID, | 760 kBroccoliButtonID, kDinerGameLinkID, kRidiculeLinkID, |
745 kClosetLinkID, kVisitingLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, | 761 kClosetLinkID, kVisitingLinkID, kAmelieLinkID, kJoyeuxNoelLinkID, |
746 kCampingLinkID, kBriceDeNiceLinkID, kTaxiLinkID, kAsterixLinkID }; | 762 kCampingLinkID, kBriceDeNiceLinkID, kTaxiLinkID, kAsterixLinkID }; |
747 | 763 |
748 FocusSearch focus_search_right(right_container_, true, true); | 764 FocusSearch focus_search_right(right_container_, true, true); |
749 right_container_->EnablePaneFocus(&focus_search_right); | 765 right_container_->EnablePaneFocus(&focus_search_right); |
750 FindViewByID(kRosettaLinkID)->SetFocusBehavior(View::FocusBehavior::NEVER); | 766 FindViewByID(kRosettaLinkID)->SetFocusBehavior(View::FocusBehavior::NEVER); |
751 FindViewByID(kStupeurEtTremblementLinkID) | 767 FindViewByID(kStupeurEtTremblementLinkID) |
752 ->SetFocusBehavior(View::FocusBehavior::NEVER); | 768 ->SetFocusBehavior(View::FocusBehavior::NEVER); |
753 FindViewByID(kDinerGameLinkID) | 769 FindViewByID(kDinerGameLinkID) |
754 ->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY); | 770 ->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY); |
755 FindViewByID(kAsterixLinkID)->RequestFocus(); | 771 FindViewByID(kAsterixLinkID)->RequestFocus(); |
756 | 772 |
757 // Traverse the focus hierarchy within the pane several times. | 773 // Traverse the focus hierarchy within the pane several times. |
758 for (int i = 0; i < 3; ++i) { | 774 AdvanceEntireFocusLoop(kRightTraversalIDs, false); |
759 for (size_t j = 0; j < arraysize(kRightTraversalIDs); j++) { | |
760 GetFocusManager()->AdvanceFocus(false); | |
761 View* focused_view = GetFocusManager()->GetFocusedView(); | |
762 EXPECT_TRUE(focused_view != NULL); | |
763 if (focused_view) | |
764 EXPECT_EQ(kRightTraversalIDs[j], focused_view->id()); | |
765 } | |
766 } | |
767 | 775 |
768 // Traverse in reverse order. | 776 // Traverse in reverse order. |
769 FindViewByID(kBroccoliButtonID)->RequestFocus(); | 777 FindViewByID(kBroccoliButtonID)->RequestFocus(); |
770 for (int i = 0; i < 3; ++i) { | 778 AdvanceEntireFocusLoop(kRightTraversalIDs, true); |
771 for (int j = arraysize(kRightTraversalIDs) - 1; j >= 0; --j) { | |
772 GetFocusManager()->AdvanceFocus(true); | |
773 View* focused_view = GetFocusManager()->GetFocusedView(); | |
774 EXPECT_TRUE(focused_view != NULL); | |
775 if (focused_view) | |
776 EXPECT_EQ(kRightTraversalIDs[j], focused_view->id()); | |
777 } | |
778 } | |
779 } | 779 } |
780 | 780 |
781 class FocusTraversalNonFocusableTest : public FocusManagerTest { | 781 class FocusTraversalNonFocusableTest : public FocusManagerTest { |
782 public: | 782 public: |
783 ~FocusTraversalNonFocusableTest() override {} | 783 ~FocusTraversalNonFocusableTest() override {} |
784 | 784 |
785 void InitContentView() override; | 785 void InitContentView() override; |
786 | 786 |
787 protected: | 787 protected: |
788 FocusTraversalNonFocusableTest() {} | 788 FocusTraversalNonFocusableTest() {} |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 GetFocusManager()->AdvanceFocus(false); | 847 GetFocusManager()->AdvanceFocus(false); |
848 EXPECT_FALSE(GetFocusManager()->GetFocusedView()); | 848 EXPECT_FALSE(GetFocusManager()->GetFocusedView()); |
849 | 849 |
850 // Advance backwards from the root node. | 850 // Advance backwards from the root node. |
851 GetFocusManager()->ClearFocus(); | 851 GetFocusManager()->ClearFocus(); |
852 GetFocusManager()->AdvanceFocus(true); | 852 GetFocusManager()->AdvanceFocus(true); |
853 EXPECT_FALSE(GetFocusManager()->GetFocusedView()); | 853 EXPECT_FALSE(GetFocusManager()->GetFocusedView()); |
854 } | 854 } |
855 | 855 |
856 } // namespace views | 856 } // namespace views |
OLD | NEW |