OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "ui/base/hit_test.h" | 9 #include "ui/base/hit_test.h" |
10 #include "ui/events/event_processor.h" | 10 #include "ui/events/event_processor.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 // not dependent on the order of AddAccelerator calls. | 42 // not dependent on the order of AddAccelerator calls. |
43 EXPECT_FALSE(GetWidget()); | 43 EXPECT_FALSE(GetWidget()); |
44 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 44 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
45 } | 45 } |
46 | 46 |
47 // WidgetDelegate overrides: | 47 // WidgetDelegate overrides: |
48 bool ShouldShowWindowTitle() const override { | 48 bool ShouldShowWindowTitle() const override { |
49 return !title_.empty(); | 49 return !title_.empty(); |
50 } | 50 } |
51 | 51 |
52 bool ShouldShowCloseButton() const override { return false; } | |
53 | |
52 // DialogDelegateView overrides: | 54 // DialogDelegateView overrides: |
53 bool Cancel() override { | 55 bool Cancel() override { |
54 canceled_ = true; | 56 canceled_ = true; |
55 return closeable_; | 57 return closeable_; |
56 } | 58 } |
57 bool Accept() override { | 59 bool Accept() override { |
58 accepted_ = true; | 60 accepted_ = true; |
59 return closeable_; | 61 return closeable_; |
60 } | 62 } |
61 bool Close() override { | 63 bool Close() override { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 | 123 |
122 class DialogTest : public ViewsTestBase { | 124 class DialogTest : public ViewsTestBase { |
123 public: | 125 public: |
124 DialogTest() : dialog_(nullptr) {} | 126 DialogTest() : dialog_(nullptr) {} |
125 ~DialogTest() override {} | 127 ~DialogTest() override {} |
126 | 128 |
127 void SetUp() override { | 129 void SetUp() override { |
128 ViewsTestBase::SetUp(); | 130 ViewsTestBase::SetUp(); |
129 dialog_ = new TestDialog(); | 131 dialog_ = new TestDialog(); |
130 dialog_->Init(); | 132 dialog_->Init(); |
131 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr)->Show(); | 133 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr); |
132 } | 134 } |
133 | 135 |
134 void TearDown() override { | 136 void TearDown() override { |
135 dialog_->TearDown(); | 137 dialog_->TearDown(); |
136 ViewsTestBase::TearDown(); | 138 ViewsTestBase::TearDown(); |
137 } | 139 } |
138 | 140 |
139 void SimulateKeyEvent(const ui::KeyEvent& event) { | 141 void SimulateKeyEvent(const ui::KeyEvent& event) { |
140 ui::KeyEvent event_copy = event; | 142 ui::KeyEvent event_copy = event; |
141 if (dialog()->GetFocusManager()->OnKeyEvent(event_copy)) | 143 if (dialog()->GetFocusManager()->OnKeyEvent(event_copy)) |
142 dialog()->GetWidget()->OnKeyEvent(&event_copy); | 144 dialog()->GetWidget()->OnKeyEvent(&event_copy); |
143 } | 145 } |
144 | 146 |
147 void ShowDialog() { dialog()->GetWidget()->Show(); } | |
148 | |
145 TestDialog* dialog() const { return dialog_; } | 149 TestDialog* dialog() const { return dialog_; } |
146 | 150 |
147 private: | 151 private: |
148 TestDialog* dialog_; | 152 TestDialog* dialog_; |
149 | 153 |
150 DISALLOW_COPY_AND_ASSIGN(DialogTest); | 154 DISALLOW_COPY_AND_ASSIGN(DialogTest); |
151 }; | 155 }; |
152 | 156 |
153 } // namespace | 157 } // namespace |
154 | 158 |
155 TEST_F(DialogTest, AcceptAndCancel) { | 159 TEST_F(DialogTest, AcceptAndCancel) { |
160 ShowDialog(); | |
156 DialogClientView* client_view = dialog()->GetDialogClientView(); | 161 DialogClientView* client_view = dialog()->GetDialogClientView(); |
157 LabelButton* ok_button = client_view->ok_button(); | 162 LabelButton* ok_button = client_view->ok_button(); |
158 LabelButton* cancel_button = client_view->cancel_button(); | 163 LabelButton* cancel_button = client_view->cancel_button(); |
159 | 164 |
160 // Check that return/escape accelerators accept/close dialogs. | 165 // Check that return/escape accelerators accept/close dialogs. |
161 EXPECT_EQ(dialog()->input(), dialog()->GetFocusManager()->GetFocusedView()); | 166 EXPECT_EQ(dialog()->input(), dialog()->GetFocusManager()->GetFocusedView()); |
162 const ui::KeyEvent return_event( | 167 const ui::KeyEvent return_event( |
163 ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); | 168 ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); |
164 SimulateKeyEvent(return_event); | 169 SimulateKeyEvent(return_event); |
165 dialog()->CheckAndResetStates(false, true, false, nullptr); | 170 dialog()->CheckAndResetStates(false, true, false, nullptr); |
(...skipping 14 matching lines...) Expand all Loading... | |
180 SimulateKeyEvent(return_event); | 185 SimulateKeyEvent(return_event); |
181 dialog()->CheckAndResetStates(true, false, false, nullptr); | 186 dialog()->CheckAndResetStates(true, false, false, nullptr); |
182 | 187 |
183 // Check that escape can be overridden. | 188 // Check that escape can be overridden. |
184 dialog()->set_should_handle_escape(true); | 189 dialog()->set_should_handle_escape(true); |
185 SimulateKeyEvent(escape_event); | 190 SimulateKeyEvent(escape_event); |
186 dialog()->CheckAndResetStates(false, false, false, nullptr); | 191 dialog()->CheckAndResetStates(false, false, false, nullptr); |
187 } | 192 } |
188 | 193 |
189 TEST_F(DialogTest, RemoveDefaultButton) { | 194 TEST_F(DialogTest, RemoveDefaultButton) { |
195 ShowDialog(); | |
190 // Removing buttons from the dialog here should not cause a crash on close. | 196 // Removing buttons from the dialog here should not cause a crash on close. |
191 delete dialog()->GetDialogClientView()->ok_button(); | 197 delete dialog()->GetDialogClientView()->ok_button(); |
192 delete dialog()->GetDialogClientView()->cancel_button(); | 198 delete dialog()->GetDialogClientView()->cancel_button(); |
193 } | 199 } |
194 | 200 |
195 TEST_F(DialogTest, HitTest_HiddenTitle) { | 201 TEST_F(DialogTest, HitTest_HiddenTitle) { |
202 ShowDialog(); | |
196 // Ensure that BubbleFrameView hit-tests as expected when the title is hidden. | 203 // Ensure that BubbleFrameView hit-tests as expected when the title is hidden. |
197 const NonClientView* view = dialog()->GetWidget()->non_client_view(); | 204 const NonClientView* view = dialog()->GetWidget()->non_client_view(); |
198 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); | 205 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); |
199 const int border = frame->bubble_border()->GetBorderThickness(); | 206 const int border = frame->bubble_border()->GetBorderThickness(); |
200 | 207 |
201 struct { | 208 struct { |
202 const int point; | 209 const int point; |
203 const int hit; | 210 const int hit; |
204 } cases[] = { | 211 } cases[] = { |
205 { border, HTSYSMENU }, | 212 { border, HTSYSMENU }, |
206 { border + 10, HTSYSMENU }, | 213 { border + 10, HTSYSMENU }, |
207 { border + 20, HTCLIENT }, | 214 { border + 20, HTCLIENT }, |
208 { border + 50, HTCLIENT }, | 215 { border + 50, HTCLIENT }, |
209 { border + 60, HTCLIENT }, | 216 { border + 60, HTCLIENT }, |
210 { 1000, HTNOWHERE }, | 217 { 1000, HTNOWHERE }, |
211 }; | 218 }; |
212 | 219 |
213 for (size_t i = 0; i < arraysize(cases); ++i) { | 220 for (size_t i = 0; i < arraysize(cases); ++i) { |
214 gfx::Point point(cases[i].point, cases[i].point); | 221 gfx::Point point(cases[i].point, cases[i].point); |
215 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) | 222 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) |
216 << " case " << i << " with border: " << border << ", at point " | 223 << " case " << i << " with border: " << border << ", at point " |
217 << cases[i].point; | 224 << cases[i].point; |
218 } | 225 } |
219 } | 226 } |
220 | 227 |
221 TEST_F(DialogTest, HitTest_WithTitle) { | 228 TEST_F(DialogTest, HitTest_WithTitle) { |
229 ShowDialog(); | |
222 // Ensure that BubbleFrameView hit-tests as expected when the title is shown. | 230 // Ensure that BubbleFrameView hit-tests as expected when the title is shown. |
223 const NonClientView* view = dialog()->GetWidget()->non_client_view(); | 231 const NonClientView* view = dialog()->GetWidget()->non_client_view(); |
224 dialog()->set_title(base::ASCIIToUTF16("Title")); | 232 dialog()->set_title(base::ASCIIToUTF16("Title")); |
225 dialog()->GetWidget()->UpdateWindowTitle(); | 233 dialog()->GetWidget()->UpdateWindowTitle(); |
226 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); | 234 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); |
227 const int border = frame->bubble_border()->GetBorderThickness(); | 235 const int border = frame->bubble_border()->GetBorderThickness(); |
228 | 236 |
229 struct { | 237 struct { |
230 const int point; | 238 const int point; |
231 const int hit; | 239 const int hit; |
232 } cases[] = { | 240 } cases[] = { |
233 { border, HTSYSMENU }, | 241 { border, HTSYSMENU }, |
234 { border + 10, HTSYSMENU }, | 242 { border + 10, HTSYSMENU }, |
235 { border + 20, HTCAPTION }, | 243 { border + 20, HTCAPTION }, |
236 { border + 50, HTCLIENT }, | 244 { border + 50, HTCLIENT }, |
237 { border + 60, HTCLIENT }, | 245 { border + 60, HTCLIENT }, |
238 { 1000, HTNOWHERE }, | 246 { 1000, HTNOWHERE }, |
239 }; | 247 }; |
240 | 248 |
241 for (size_t i = 0; i < arraysize(cases); ++i) { | 249 for (size_t i = 0; i < arraysize(cases); ++i) { |
242 gfx::Point point(cases[i].point, cases[i].point); | 250 gfx::Point point(cases[i].point, cases[i].point); |
243 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) | 251 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) |
244 << " with border: " << border << ", at point " << cases[i].point; | 252 << " with border: " << border << ", at point " << cases[i].point; |
245 } | 253 } |
246 } | 254 } |
247 | 255 |
248 TEST_F(DialogTest, BoundsAccommodateTitle) { | 256 TEST_F(DialogTest, BoundsAccommodateTitle) { |
257 ShowDialog(); | |
249 TestDialog* dialog2(new TestDialog()); | 258 TestDialog* dialog2(new TestDialog()); |
250 dialog2->set_title(base::ASCIIToUTF16("Title")); | 259 dialog2->set_title(base::ASCIIToUTF16("Title")); |
251 DialogDelegate::CreateDialogWidget(dialog2, GetContext(), nullptr); | 260 DialogDelegate::CreateDialogWidget(dialog2, GetContext(), nullptr); |
252 | 261 |
253 // Titled dialogs have taller initial frame bounds than untitled dialogs. | 262 // Titled dialogs have taller initial frame bounds than untitled dialogs. |
254 View* frame1 = dialog()->GetWidget()->non_client_view()->frame_view(); | 263 View* frame1 = dialog()->GetWidget()->non_client_view()->frame_view(); |
255 View* frame2 = dialog2->GetWidget()->non_client_view()->frame_view(); | 264 View* frame2 = dialog2->GetWidget()->non_client_view()->frame_view(); |
256 EXPECT_LT(frame1->GetPreferredSize().height(), | 265 EXPECT_LT(frame1->GetPreferredSize().height(), |
257 frame2->GetPreferredSize().height()); | 266 frame2->GetPreferredSize().height()); |
258 | 267 |
259 // Giving the default test dialog a title will yield the same bounds. | 268 // Giving the default test dialog a title will yield the same bounds. |
260 dialog()->set_title(base::ASCIIToUTF16("Title")); | 269 dialog()->set_title(base::ASCIIToUTF16("Title")); |
261 dialog()->GetWidget()->UpdateWindowTitle(); | 270 dialog()->GetWidget()->UpdateWindowTitle(); |
262 EXPECT_EQ(frame1->GetPreferredSize().height(), | 271 EXPECT_EQ(frame1->GetPreferredSize().height(), |
263 frame2->GetPreferredSize().height()); | 272 frame2->GetPreferredSize().height()); |
264 | 273 |
265 dialog2->TearDown(); | 274 dialog2->TearDown(); |
266 } | 275 } |
267 | 276 |
268 // Tests default focus is assigned correctly when showing a new dialog. | 277 // Tests default focus is assigned correctly when showing a new dialog. |
269 TEST_F(DialogTest, InitialFocus) { | 278 TEST_F(DialogTest, InitialFocus) { |
279 ShowDialog(); | |
270 EXPECT_TRUE(dialog()->input()->HasFocus()); | 280 EXPECT_TRUE(dialog()->input()->HasFocus()); |
271 EXPECT_EQ(dialog()->input(), dialog()->GetFocusManager()->GetFocusedView()); | 281 EXPECT_EQ(dialog()->input(), dialog()->GetFocusManager()->GetFocusedView()); |
272 } | 282 } |
273 | 283 |
284 // If the initially focused View provided is unfocusable, check the next | |
285 // available focusable View is focused. | |
286 TEST_F(DialogTest, UnfocusableInitialFocus) { | |
287 DialogDelegateView* dialog = new DialogDelegateView(); | |
288 Textfield* textfield = new Textfield(); | |
289 dialog->AddChildView(textfield); | |
290 Widget* dialog_widget = | |
291 DialogDelegate::CreateDialogWidget(dialog, GetContext(), nullptr); | |
292 | |
293 // Turn off focusability on all the dialog's buttons. On Mac, we can just do | |
294 // this by turning off full keyboard access. On non-Mac, this will have no | |
295 // effect - turn off focusability for Views there manually. | |
296 SetFullKeyboardAccessState(dialog_widget, false); | |
tapted
2017/01/12 02:25:43
if you do this before creating the widget, I think
Patti Lor
2017/01/12 06:12:37
Oh, that works! Thanks, reverted stuff back.
| |
297 #if !defined(OS_MACOSX) | |
298 DialogClientView* dcv = dialog->GetDialogClientView(); | |
299 dcv->ok_button()->SetFocusBehavior(View::FocusBehavior::NEVER); | |
300 dcv->cancel_button()->SetFocusBehavior(View::FocusBehavior::NEVER); | |
301 #endif | |
302 | |
303 // On showing the dialog, the initially focused View will be the OK button. | |
304 // Since it is no longer focusable, focus should advance to the next focusable | |
305 // View, which is |textfield|. | |
306 dialog_widget->Show(); | |
307 EXPECT_TRUE(textfield->HasFocus()); | |
308 EXPECT_EQ(textfield, dialog->GetFocusManager()->GetFocusedView()); | |
309 dialog_widget->Close(); | |
310 } | |
311 | |
274 } // namespace views | 312 } // namespace views |
OLD | NEW |