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.
5 #include "ui/views/accessible_pane_view.h"
7 #include "ui/base/accelerators/accelerator.h"
8 #include "ui/views/controls/button/label_button.h"
9 #include "ui/views/layout/fill_layout.h"
10 #include "ui/views/test/views_test_base.h"
11 #include "ui/views/widget/widget.h"
13 #if defined(OS_MACOSX)
14 #include "ui/base/test/scoped_fake_nswindow_focus.h"
19 // TODO(alicet): bring pane rotation into views and add tests.
20 // See browser_view.cc for details.
22 typedef ViewsTestBase AccessiblePaneViewTest
;
24 class TestBarView
: public AccessiblePaneView
,
25 public ButtonListener
{
28 ~TestBarView() override
;
30 void ButtonPressed(Button
* sender
, const ui::Event
& event
) override
;
31 LabelButton
* child_button() const { return child_button_
.get(); }
32 LabelButton
* second_child_button() const {
33 return second_child_button_
.get();
35 LabelButton
* third_child_button() const { return third_child_button_
.get(); }
36 LabelButton
* not_child_button() const { return not_child_button_
.get(); }
38 View
* GetDefaultFocusableChild() override
;
43 scoped_ptr
<LabelButton
> child_button_
;
44 scoped_ptr
<LabelButton
> second_child_button_
;
45 scoped_ptr
<LabelButton
> third_child_button_
;
46 scoped_ptr
<LabelButton
> not_child_button_
;
48 DISALLOW_COPY_AND_ASSIGN(TestBarView
);
51 TestBarView::TestBarView() {
53 set_allow_deactivate_on_esc(true);
56 TestBarView::~TestBarView() {}
58 void TestBarView::ButtonPressed(Button
* sender
, const ui::Event
& event
) {
61 void TestBarView::Init() {
62 SetLayoutManager(new FillLayout());
64 child_button_
.reset(new LabelButton(this, label
));
65 AddChildView(child_button_
.get());
66 second_child_button_
.reset(new LabelButton(this, label
));
67 AddChildView(second_child_button_
.get());
68 third_child_button_
.reset(new LabelButton(this, label
));
69 AddChildView(third_child_button_
.get());
70 not_child_button_
.reset(new LabelButton(this, label
));
73 View
* TestBarView::GetDefaultFocusableChild() {
74 return child_button_
.get();
77 TEST_F(AccessiblePaneViewTest
, SimpleSetPaneFocus
) {
78 TestBarView
* test_view
= new TestBarView();
79 scoped_ptr
<Widget
> widget(new Widget());
80 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_POPUP
);
81 params
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
82 params
.bounds
= gfx::Rect(50, 50, 650, 650);
84 View
* root
= widget
->GetRootView();
85 root
->AddChildView(test_view
);
89 // Set pane focus succeeds, focus on child.
90 EXPECT_TRUE(test_view
->SetPaneFocusAndFocusDefault());
91 EXPECT_EQ(test_view
, test_view
->GetPaneFocusTraversable());
92 EXPECT_EQ(test_view
->child_button(),
93 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
95 // Set focus on non child view, focus failed, stays on pane.
96 EXPECT_TRUE(test_view
->SetPaneFocus(test_view
->not_child_button()));
97 EXPECT_FALSE(test_view
->not_child_button() ==
98 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
99 EXPECT_EQ(test_view
->child_button(),
100 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
105 TEST_F(AccessiblePaneViewTest
, SetPaneFocusAndRestore
) {
106 #if defined(OS_MACOSX)
107 // On Aura platforms, this test creates Ash windows and only interacts with
108 // the Ash window manager. On Mac, it creates native windows, but since unit
109 // tests cannot gain key status, fake it out here.
110 ui::test::ScopedFakeNSWindowFocus fake_focus
;
113 View
* test_view_main
= new View();
114 scoped_ptr
<Widget
> widget_main(new Widget());
115 Widget::InitParams params_main
= CreateParams(Widget::InitParams::TYPE_POPUP
);
116 params_main
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
117 // By default, TYPE_POPUP is not activatable.
118 params_main
.activatable
= Widget::InitParams::ACTIVATABLE_YES
;
119 params_main
.bounds
= gfx::Rect(0, 0, 20, 20);
120 widget_main
->Init(params_main
);
121 View
* root_main
= widget_main
->GetRootView();
122 root_main
->AddChildView(test_view_main
);
123 widget_main
->Activate();
124 test_view_main
->GetFocusManager()->SetFocusedView(test_view_main
);
125 EXPECT_TRUE(widget_main
->IsActive());
126 EXPECT_TRUE(test_view_main
->HasFocus());
128 TestBarView
* test_view_bar
= new TestBarView();
129 scoped_ptr
<Widget
> widget_bar(new Widget());
130 Widget::InitParams params_bar
= CreateParams(Widget::InitParams::TYPE_POPUP
);
131 params_bar
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
132 params_bar
.activatable
= Widget::InitParams::ACTIVATABLE_YES
;
133 params_bar
.bounds
= gfx::Rect(50, 50, 650, 650);
134 widget_bar
->Init(params_bar
);
135 View
* root_bar
= widget_bar
->GetRootView();
136 root_bar
->AddChildView(test_view_bar
);
138 widget_bar
->Activate();
140 // Set pane focus succeeds, focus on child.
141 EXPECT_TRUE(test_view_bar
->SetPaneFocusAndFocusDefault());
142 EXPECT_FALSE(test_view_main
->HasFocus());
143 EXPECT_FALSE(widget_main
->IsActive());
144 EXPECT_EQ(test_view_bar
, test_view_bar
->GetPaneFocusTraversable());
145 EXPECT_EQ(test_view_bar
->child_button(),
146 test_view_bar
->GetWidget()->GetFocusManager()->GetFocusedView());
148 // Deactivate() is only reliable on Ash. On Windows it uses ::GetNextWindow()
149 // to simply activate another window, and which one is not predictable. On
150 // Mac, Deactivate() is not implemented. Note that TestBarView calls
151 // set_allow_deactivate_on_esc(true), which is only otherwise used in Ash.
152 #if !defined(OS_MACOSX) || defined(USE_ASH)
153 // Esc should deactivate the widget.
154 test_view_bar
->AcceleratorPressed(test_view_bar
->escape_key());
155 EXPECT_TRUE(widget_main
->IsActive());
156 EXPECT_FALSE(widget_bar
->IsActive());
159 widget_bar
->CloseNow();
162 widget_main
->CloseNow();
166 TEST_F(AccessiblePaneViewTest
, TwoSetPaneFocus
) {
167 TestBarView
* test_view
= new TestBarView();
168 TestBarView
* test_view_2
= new TestBarView();
169 scoped_ptr
<Widget
> widget(new Widget());
170 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_POPUP
);
171 params
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
172 params
.bounds
= gfx::Rect(50, 50, 650, 650);
173 widget
->Init(params
);
174 View
* root
= widget
->GetRootView();
175 root
->AddChildView(test_view
);
176 root
->AddChildView(test_view_2
);
180 // Set pane focus succeeds, focus on child.
181 EXPECT_TRUE(test_view
->SetPaneFocusAndFocusDefault());
182 EXPECT_EQ(test_view
, test_view
->GetPaneFocusTraversable());
183 EXPECT_EQ(test_view
->child_button(),
184 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
186 // Set focus on another test_view, focus move to that pane.
187 EXPECT_TRUE(test_view_2
->SetPaneFocus(test_view_2
->second_child_button()));
188 EXPECT_FALSE(test_view
->child_button() ==
189 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
190 EXPECT_EQ(test_view_2
->second_child_button(),
191 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
196 TEST_F(AccessiblePaneViewTest
, PaneFocusTraversal
) {
197 TestBarView
* test_view
= new TestBarView();
198 TestBarView
* original_test_view
= new TestBarView();
199 scoped_ptr
<Widget
> widget(new Widget());
200 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_POPUP
);
201 params
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
202 params
.bounds
= gfx::Rect(50, 50, 650, 650);
203 widget
->Init(params
);
204 View
* root
= widget
->GetRootView();
205 root
->AddChildView(original_test_view
);
206 root
->AddChildView(test_view
);
210 // Set pane focus on first view.
211 EXPECT_TRUE(original_test_view
->SetPaneFocus(
212 original_test_view
->third_child_button()));
214 // Test travesal in second view.
215 // Set pane focus on second child.
216 EXPECT_TRUE(test_view
->SetPaneFocus(test_view
->second_child_button()));
218 test_view
->AcceleratorPressed(test_view
->home_key());
219 EXPECT_EQ(test_view
->child_button(),
220 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
222 test_view
->AcceleratorPressed(test_view
->end_key());
223 EXPECT_EQ(test_view
->third_child_button(),
224 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
226 test_view
->AcceleratorPressed(test_view
->left_key());
227 EXPECT_EQ(test_view
->second_child_button(),
228 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
230 test_view
->AcceleratorPressed(test_view
->right_key());
231 test_view
->AcceleratorPressed(test_view
->right_key());
232 EXPECT_EQ(test_view
->child_button(),
233 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());
236 test_view
->AcceleratorPressed(test_view
->escape_key());
237 EXPECT_EQ(original_test_view
->third_child_button(),
238 test_view
->GetWidget()->GetFocusManager()->GetFocusedView());