| 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 |