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/views/bubble/bubble_border.h" | 11 #include "ui/views/bubble/bubble_border.h" |
11 #include "ui/views/bubble/bubble_frame_view.h" | 12 #include "ui/views/bubble/bubble_frame_view.h" |
12 #include "ui/views/controls/button/checkbox.h" | 13 #include "ui/views/controls/button/checkbox.h" |
13 #include "ui/views/controls/button/label_button.h" | 14 #include "ui/views/controls/button/label_button.h" |
| 15 #include "ui/views/controls/textfield/textfield.h" |
14 #include "ui/views/test/views_test_base.h" | 16 #include "ui/views/test/views_test_base.h" |
15 #include "ui/views/widget/widget.h" | 17 #include "ui/views/widget/widget.h" |
16 #include "ui/views/window/dialog_client_view.h" | 18 #include "ui/views/window/dialog_client_view.h" |
17 #include "ui/views/window/dialog_delegate.h" | 19 #include "ui/views/window/dialog_delegate.h" |
18 | 20 |
19 namespace views { | 21 namespace views { |
20 | 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 class TestDialog : public DialogDelegateView, public ButtonListener { | 25 class TestDialog : public DialogDelegateView, public ButtonListener { |
24 public: | 26 public: |
25 TestDialog() | 27 TestDialog() |
26 : canceled_(false), | 28 : input_(new views::Textfield()), |
| 29 canceled_(false), |
27 accepted_(false), | 30 accepted_(false), |
28 closeable_(false), | 31 closeable_(false), |
29 last_pressed_button_(NULL) {} | 32 last_pressed_button_(NULL) { |
| 33 AddChildView(input_); |
| 34 } |
30 ~TestDialog() override {} | 35 ~TestDialog() override {} |
31 | 36 |
32 // WidgetDelegate overrides: | 37 // WidgetDelegate overrides: |
33 bool ShouldShowWindowTitle() const override { | 38 bool ShouldShowWindowTitle() const override { |
34 return !title_.empty(); | 39 return !title_.empty(); |
35 } | 40 } |
36 | 41 |
37 // DialogDelegateView overrides: | 42 // DialogDelegateView overrides: |
38 bool Cancel() override { | 43 bool Cancel() override { |
39 canceled_ = true; | 44 canceled_ = true; |
40 return closeable_; | 45 return closeable_; |
41 } | 46 } |
42 bool Accept() override { | 47 bool Accept() override { |
43 accepted_ = true; | 48 accepted_ = true; |
44 return closeable_; | 49 return closeable_; |
45 } | 50 } |
46 | 51 |
47 // DialogDelegateView overrides: | 52 // DialogDelegateView overrides: |
48 gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); } | 53 gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); } |
49 base::string16 GetWindowTitle() const override { return title_; } | 54 base::string16 GetWindowTitle() const override { return title_; } |
| 55 View* GetInitiallyFocusedView() override { return input_; } |
50 bool UseNewStyleForThisDialog() const override { return true; } | 56 bool UseNewStyleForThisDialog() const override { return true; } |
51 | 57 |
52 // ButtonListener override: | 58 // ButtonListener override: |
53 void ButtonPressed(Button* sender, const ui::Event& event) override { | 59 void ButtonPressed(Button* sender, const ui::Event& event) override { |
54 last_pressed_button_ = sender; | 60 last_pressed_button_ = sender; |
55 } | 61 } |
56 | 62 |
57 Button* last_pressed_button() const { return last_pressed_button_; } | 63 Button* last_pressed_button() const { return last_pressed_button_; } |
58 | 64 |
59 void PressEnterAndCheckStates(Button* button) { | |
60 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); | |
61 GetFocusManager()->OnKeyEvent(key_event); | |
62 const DialogClientView* client_view = GetDialogClientView(); | |
63 EXPECT_EQ(canceled_, client_view->cancel_button()->is_default()); | |
64 EXPECT_EQ(accepted_, client_view->ok_button()->is_default()); | |
65 // This view does not listen for ok or cancel clicks, DialogClientView does. | |
66 CheckAndResetStates(button == client_view->cancel_button(), | |
67 button == client_view->ok_button(), | |
68 (canceled_ || accepted_ ) ? NULL : button); | |
69 } | |
70 | |
71 void CheckAndResetStates(bool canceled, bool accepted, Button* last_pressed) { | 65 void CheckAndResetStates(bool canceled, bool accepted, Button* last_pressed) { |
72 EXPECT_EQ(canceled, canceled_); | 66 EXPECT_EQ(canceled, canceled_); |
73 canceled_ = false; | 67 canceled_ = false; |
74 EXPECT_EQ(accepted, accepted_); | 68 EXPECT_EQ(accepted, accepted_); |
75 accepted_ = false; | 69 accepted_ = false; |
76 EXPECT_EQ(last_pressed, last_pressed_button_); | 70 EXPECT_EQ(last_pressed, last_pressed_button_); |
77 last_pressed_button_ = NULL; | 71 last_pressed_button_ = NULL; |
78 } | 72 } |
79 | 73 |
80 void TearDown() { | 74 void TearDown() { |
81 closeable_ = true; | 75 closeable_ = true; |
82 GetWidget()->Close(); | 76 GetWidget()->Close(); |
83 } | 77 } |
84 | 78 |
85 void set_title(const base::string16& title) { title_ = title; } | 79 void set_title(const base::string16& title) { title_ = title; } |
86 | 80 |
| 81 views::Textfield* input() { return input_; } |
| 82 |
87 private: | 83 private: |
| 84 views::Textfield* input_; |
88 bool canceled_; | 85 bool canceled_; |
89 bool accepted_; | 86 bool accepted_; |
90 // Prevent the dialog from closing, for repeated ok and cancel button clicks. | 87 // Prevent the dialog from closing, for repeated ok and cancel button clicks. |
91 bool closeable_; | 88 bool closeable_; |
92 Button* last_pressed_button_; | 89 Button* last_pressed_button_; |
93 base::string16 title_; | 90 base::string16 title_; |
94 | 91 |
95 DISALLOW_COPY_AND_ASSIGN(TestDialog); | 92 DISALLOW_COPY_AND_ASSIGN(TestDialog); |
96 }; | 93 }; |
97 | 94 |
98 class DialogTest : public ViewsTestBase { | 95 class DialogTest : public ViewsTestBase { |
99 public: | 96 public: |
100 DialogTest() : dialog_(NULL) {} | 97 DialogTest() : dialog_(NULL) {} |
101 ~DialogTest() override {} | 98 ~DialogTest() override {} |
102 | 99 |
103 void SetUp() override { | 100 void SetUp() override { |
104 ViewsTestBase::SetUp(); | 101 ViewsTestBase::SetUp(); |
105 dialog_ = new TestDialog(); | 102 dialog_ = new TestDialog(); |
106 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), NULL)->Show(); | 103 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), NULL)->Show(); |
107 } | 104 } |
108 | 105 |
109 void TearDown() override { | 106 void TearDown() override { |
110 dialog_->TearDown(); | 107 dialog_->TearDown(); |
111 ViewsTestBase::TearDown(); | 108 ViewsTestBase::TearDown(); |
112 } | 109 } |
113 | 110 |
| 111 void SimulateKeyEvent(const ui::KeyEvent& event) { |
| 112 ui::KeyEvent event_copy = event; |
| 113 if (dialog()->GetFocusManager()->OnKeyEvent(event_copy)) |
| 114 dialog()->GetWidget()->OnKeyEvent(&event_copy); |
| 115 } |
| 116 |
114 TestDialog* dialog() const { return dialog_; } | 117 TestDialog* dialog() const { return dialog_; } |
115 | 118 |
116 private: | 119 private: |
117 TestDialog* dialog_; | 120 TestDialog* dialog_; |
118 | 121 |
119 DISALLOW_COPY_AND_ASSIGN(DialogTest); | 122 DISALLOW_COPY_AND_ASSIGN(DialogTest); |
120 }; | 123 }; |
121 | 124 |
122 } // namespace | 125 } // namespace |
123 | 126 |
124 TEST_F(DialogTest, DefaultButtons) { | |
125 DialogClientView* client_view = dialog()->GetDialogClientView(); | |
126 LabelButton* ok_button = client_view->ok_button(); | |
127 | |
128 // DialogDelegate's default button (ok) should be default (and handle enter). | |
129 EXPECT_EQ(ui::DIALOG_BUTTON_OK, dialog()->GetDefaultDialogButton()); | |
130 dialog()->PressEnterAndCheckStates(ok_button); | |
131 | |
132 // Focus another button in the dialog, it should become the default. | |
133 LabelButton* button_1 = new LabelButton(dialog(), base::string16()); | |
134 client_view->AddChildView(button_1); | |
135 client_view->OnWillChangeFocus(ok_button, button_1); | |
136 EXPECT_TRUE(button_1->is_default()); | |
137 dialog()->PressEnterAndCheckStates(button_1); | |
138 | |
139 // Focus a Checkbox (not a push button), OK should become the default again. | |
140 Checkbox* checkbox = new Checkbox(base::string16()); | |
141 client_view->AddChildView(checkbox); | |
142 client_view->OnWillChangeFocus(button_1, checkbox); | |
143 EXPECT_FALSE(button_1->is_default()); | |
144 dialog()->PressEnterAndCheckStates(ok_button); | |
145 | |
146 // Focus yet another button in the dialog, it should become the default. | |
147 LabelButton* button_2 = new LabelButton(dialog(), base::string16()); | |
148 client_view->AddChildView(button_2); | |
149 client_view->OnWillChangeFocus(checkbox, button_2); | |
150 EXPECT_FALSE(button_1->is_default()); | |
151 EXPECT_TRUE(button_2->is_default()); | |
152 dialog()->PressEnterAndCheckStates(button_2); | |
153 | |
154 // Focus nothing, OK should become the default again. | |
155 client_view->OnWillChangeFocus(button_2, NULL); | |
156 EXPECT_FALSE(button_1->is_default()); | |
157 EXPECT_FALSE(button_2->is_default()); | |
158 dialog()->PressEnterAndCheckStates(ok_button); | |
159 } | |
160 | |
161 TEST_F(DialogTest, AcceptAndCancel) { | 127 TEST_F(DialogTest, AcceptAndCancel) { |
162 DialogClientView* client_view = dialog()->GetDialogClientView(); | 128 DialogClientView* client_view = dialog()->GetDialogClientView(); |
163 LabelButton* ok_button = client_view->ok_button(); | 129 LabelButton* ok_button = client_view->ok_button(); |
164 LabelButton* cancel_button = client_view->cancel_button(); | 130 LabelButton* cancel_button = client_view->cancel_button(); |
165 | 131 |
166 // Check that return/escape accelerators accept/cancel dialogs. | 132 // Check that return/escape accelerators accept/cancel dialogs. |
167 const ui::KeyEvent return_key( | 133 EXPECT_EQ(dialog()->input(), dialog()->GetFocusManager()->GetFocusedView()); |
| 134 const ui::KeyEvent return_event( |
168 ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); | 135 ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); |
169 dialog()->GetFocusManager()->OnKeyEvent(return_key); | 136 SimulateKeyEvent(return_event); |
170 dialog()->CheckAndResetStates(false, true, NULL); | 137 dialog()->CheckAndResetStates(false, true, NULL); |
171 const ui::KeyEvent escape_key( | 138 const ui::KeyEvent escape_event( |
172 ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE); | 139 ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE); |
173 dialog()->GetFocusManager()->OnKeyEvent(escape_key); | 140 SimulateKeyEvent(escape_event); |
174 dialog()->CheckAndResetStates(true, false, NULL); | 141 dialog()->CheckAndResetStates(true, false, NULL); |
175 | 142 |
176 // Check ok and cancel button behavior on a directed return key events. | 143 // Check ok and cancel button behavior on a directed return key events. |
177 ok_button->OnKeyPressed(return_key); | 144 ok_button->OnKeyPressed(return_event); |
178 dialog()->CheckAndResetStates(false, true, NULL); | 145 dialog()->CheckAndResetStates(false, true, NULL); |
179 cancel_button->OnKeyPressed(return_key); | 146 cancel_button->OnKeyPressed(return_event); |
180 dialog()->CheckAndResetStates(true, false, NULL); | 147 dialog()->CheckAndResetStates(true, false, NULL); |
181 | 148 |
182 // Check that return accelerators cancel dialogs if cancel is focused. | 149 // Check that return accelerators cancel dialogs if cancel is focused. |
183 cancel_button->RequestFocus(); | 150 cancel_button->RequestFocus(); |
184 dialog()->GetFocusManager()->OnKeyEvent(return_key); | 151 EXPECT_EQ(cancel_button, dialog()->GetFocusManager()->GetFocusedView()); |
| 152 SimulateKeyEvent(return_event); |
185 dialog()->CheckAndResetStates(true, false, NULL); | 153 dialog()->CheckAndResetStates(true, false, NULL); |
186 } | 154 } |
187 | 155 |
188 TEST_F(DialogTest, RemoveDefaultButton) { | 156 TEST_F(DialogTest, RemoveDefaultButton) { |
189 // Removing buttons from the dialog here should not cause a crash on close. | 157 // Removing buttons from the dialog here should not cause a crash on close. |
190 delete dialog()->GetDialogClientView()->ok_button(); | 158 delete dialog()->GetDialogClientView()->ok_button(); |
191 delete dialog()->GetDialogClientView()->cancel_button(); | 159 delete dialog()->GetDialogClientView()->cancel_button(); |
192 } | 160 } |
193 | 161 |
194 TEST_F(DialogTest, HitTest_HiddenTitle) { | 162 TEST_F(DialogTest, HitTest_HiddenTitle) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 // Giving the default test dialog a title will yield the same bounds. | 225 // Giving the default test dialog a title will yield the same bounds. |
258 dialog()->set_title(base::ASCIIToUTF16("Title")); | 226 dialog()->set_title(base::ASCIIToUTF16("Title")); |
259 dialog()->GetWidget()->UpdateWindowTitle(); | 227 dialog()->GetWidget()->UpdateWindowTitle(); |
260 EXPECT_EQ(frame1->GetPreferredSize().height(), | 228 EXPECT_EQ(frame1->GetPreferredSize().height(), |
261 frame2->GetPreferredSize().height()); | 229 frame2->GetPreferredSize().height()); |
262 | 230 |
263 dialog2->TearDown(); | 231 dialog2->TearDown(); |
264 } | 232 } |
265 | 233 |
266 } // namespace views | 234 } // namespace views |
OLD | NEW |