| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/strings/utf_string_conversions.h" | |
| 6 #include "ui/base/hit_test.h" | |
| 7 #include "ui/views/bubble/bubble_border.h" | |
| 8 #include "ui/views/bubble/bubble_frame_view.h" | |
| 9 #include "ui/views/controls/button/checkbox.h" | |
| 10 #include "ui/views/controls/button/label_button.h" | |
| 11 #include "ui/views/test/views_test_base.h" | |
| 12 #include "ui/views/widget/widget.h" | |
| 13 #include "ui/views/window/dialog_client_view.h" | |
| 14 #include "ui/views/window/dialog_delegate.h" | |
| 15 | |
| 16 namespace views { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 class TestDialog : public DialogDelegateView, public ButtonListener { | |
| 21 public: | |
| 22 TestDialog() | |
| 23 : canceled_(false), | |
| 24 accepted_(false), | |
| 25 closeable_(false), | |
| 26 last_pressed_button_(NULL) {} | |
| 27 virtual ~TestDialog() {} | |
| 28 | |
| 29 // DialogDelegateView overrides: | |
| 30 virtual bool Cancel() override { | |
| 31 canceled_ = true; | |
| 32 return closeable_; | |
| 33 } | |
| 34 virtual bool Accept() override { | |
| 35 accepted_ = true; | |
| 36 return closeable_; | |
| 37 } | |
| 38 | |
| 39 // DialogDelegateView overrides: | |
| 40 virtual gfx::Size GetPreferredSize() const override { | |
| 41 return gfx::Size(200, 200); | |
| 42 } | |
| 43 virtual base::string16 GetWindowTitle() const override { return title_; } | |
| 44 virtual bool UseNewStyleForThisDialog() const override { return true; } | |
| 45 | |
| 46 // ButtonListener override: | |
| 47 virtual void ButtonPressed(Button* sender, const ui::Event& event) override { | |
| 48 last_pressed_button_ = sender; | |
| 49 } | |
| 50 | |
| 51 Button* last_pressed_button() const { return last_pressed_button_; } | |
| 52 | |
| 53 void PressEnterAndCheckStates(Button* button) { | |
| 54 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); | |
| 55 GetFocusManager()->OnKeyEvent(key_event); | |
| 56 const DialogClientView* client_view = GetDialogClientView(); | |
| 57 EXPECT_EQ(canceled_, client_view->cancel_button()->is_default()); | |
| 58 EXPECT_EQ(accepted_, client_view->ok_button()->is_default()); | |
| 59 // This view does not listen for ok or cancel clicks, DialogClientView does. | |
| 60 CheckAndResetStates(button == client_view->cancel_button(), | |
| 61 button == client_view->ok_button(), | |
| 62 (canceled_ || accepted_ ) ? NULL : button); | |
| 63 } | |
| 64 | |
| 65 void CheckAndResetStates(bool canceled, bool accepted, Button* last_pressed) { | |
| 66 EXPECT_EQ(canceled, canceled_); | |
| 67 canceled_ = false; | |
| 68 EXPECT_EQ(accepted, accepted_); | |
| 69 accepted_ = false; | |
| 70 EXPECT_EQ(last_pressed, last_pressed_button_); | |
| 71 last_pressed_button_ = NULL; | |
| 72 } | |
| 73 | |
| 74 void TearDown() { | |
| 75 closeable_ = true; | |
| 76 GetWidget()->Close(); | |
| 77 } | |
| 78 | |
| 79 void set_title(const base::string16& title) { title_ = title; } | |
| 80 | |
| 81 private: | |
| 82 bool canceled_; | |
| 83 bool accepted_; | |
| 84 // Prevent the dialog from closing, for repeated ok and cancel button clicks. | |
| 85 bool closeable_; | |
| 86 Button* last_pressed_button_; | |
| 87 base::string16 title_; | |
| 88 | |
| 89 DISALLOW_COPY_AND_ASSIGN(TestDialog); | |
| 90 }; | |
| 91 | |
| 92 class DialogTest : public ViewsTestBase { | |
| 93 public: | |
| 94 DialogTest() : dialog_(NULL) {} | |
| 95 virtual ~DialogTest() {} | |
| 96 | |
| 97 virtual void SetUp() override { | |
| 98 ViewsTestBase::SetUp(); | |
| 99 dialog_ = new TestDialog(); | |
| 100 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), NULL)->Show(); | |
| 101 } | |
| 102 | |
| 103 virtual void TearDown() override { | |
| 104 dialog_->TearDown(); | |
| 105 ViewsTestBase::TearDown(); | |
| 106 } | |
| 107 | |
| 108 TestDialog* dialog() const { return dialog_; } | |
| 109 | |
| 110 private: | |
| 111 TestDialog* dialog_; | |
| 112 | |
| 113 DISALLOW_COPY_AND_ASSIGN(DialogTest); | |
| 114 }; | |
| 115 | |
| 116 } // namespace | |
| 117 | |
| 118 TEST_F(DialogTest, DefaultButtons) { | |
| 119 DialogClientView* client_view = dialog()->GetDialogClientView(); | |
| 120 LabelButton* ok_button = client_view->ok_button(); | |
| 121 | |
| 122 // DialogDelegate's default button (ok) should be default (and handle enter). | |
| 123 EXPECT_EQ(ui::DIALOG_BUTTON_OK, dialog()->GetDefaultDialogButton()); | |
| 124 dialog()->PressEnterAndCheckStates(ok_button); | |
| 125 | |
| 126 // Focus another button in the dialog, it should become the default. | |
| 127 LabelButton* button_1 = new LabelButton(dialog(), base::string16()); | |
| 128 client_view->AddChildView(button_1); | |
| 129 client_view->OnWillChangeFocus(ok_button, button_1); | |
| 130 EXPECT_TRUE(button_1->is_default()); | |
| 131 dialog()->PressEnterAndCheckStates(button_1); | |
| 132 | |
| 133 // Focus a Checkbox (not a push button), OK should become the default again. | |
| 134 Checkbox* checkbox = new Checkbox(base::string16()); | |
| 135 client_view->AddChildView(checkbox); | |
| 136 client_view->OnWillChangeFocus(button_1, checkbox); | |
| 137 EXPECT_FALSE(button_1->is_default()); | |
| 138 dialog()->PressEnterAndCheckStates(ok_button); | |
| 139 | |
| 140 // Focus yet another button in the dialog, it should become the default. | |
| 141 LabelButton* button_2 = new LabelButton(dialog(), base::string16()); | |
| 142 client_view->AddChildView(button_2); | |
| 143 client_view->OnWillChangeFocus(checkbox, button_2); | |
| 144 EXPECT_FALSE(button_1->is_default()); | |
| 145 EXPECT_TRUE(button_2->is_default()); | |
| 146 dialog()->PressEnterAndCheckStates(button_2); | |
| 147 | |
| 148 // Focus nothing, OK should become the default again. | |
| 149 client_view->OnWillChangeFocus(button_2, NULL); | |
| 150 EXPECT_FALSE(button_1->is_default()); | |
| 151 EXPECT_FALSE(button_2->is_default()); | |
| 152 dialog()->PressEnterAndCheckStates(ok_button); | |
| 153 } | |
| 154 | |
| 155 TEST_F(DialogTest, AcceptAndCancel) { | |
| 156 DialogClientView* client_view = dialog()->GetDialogClientView(); | |
| 157 LabelButton* ok_button = client_view->ok_button(); | |
| 158 LabelButton* cancel_button = client_view->cancel_button(); | |
| 159 | |
| 160 // Check that return/escape accelerators accept/cancel dialogs. | |
| 161 const ui::KeyEvent return_key( | |
| 162 ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); | |
| 163 dialog()->GetFocusManager()->OnKeyEvent(return_key); | |
| 164 dialog()->CheckAndResetStates(false, true, NULL); | |
| 165 const ui::KeyEvent escape_key( | |
| 166 ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE); | |
| 167 dialog()->GetFocusManager()->OnKeyEvent(escape_key); | |
| 168 dialog()->CheckAndResetStates(true, false, NULL); | |
| 169 | |
| 170 // Check ok and cancel button behavior on a directed return key events. | |
| 171 ok_button->OnKeyPressed(return_key); | |
| 172 dialog()->CheckAndResetStates(false, true, NULL); | |
| 173 cancel_button->OnKeyPressed(return_key); | |
| 174 dialog()->CheckAndResetStates(true, false, NULL); | |
| 175 | |
| 176 // Check that return accelerators cancel dialogs if cancel is focused. | |
| 177 cancel_button->RequestFocus(); | |
| 178 dialog()->GetFocusManager()->OnKeyEvent(return_key); | |
| 179 dialog()->CheckAndResetStates(true, false, NULL); | |
| 180 } | |
| 181 | |
| 182 TEST_F(DialogTest, RemoveDefaultButton) { | |
| 183 // Removing buttons from the dialog here should not cause a crash on close. | |
| 184 delete dialog()->GetDialogClientView()->ok_button(); | |
| 185 delete dialog()->GetDialogClientView()->cancel_button(); | |
| 186 } | |
| 187 | |
| 188 TEST_F(DialogTest, HitTest) { | |
| 189 // Ensure that the new style's BubbleFrameView hit-tests as expected. | |
| 190 const NonClientView* view = dialog()->GetWidget()->non_client_view(); | |
| 191 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); | |
| 192 const int border = frame->bubble_border()->GetBorderThickness(); | |
| 193 | |
| 194 struct { | |
| 195 const int point; | |
| 196 const int hit; | |
| 197 } cases[] = { | |
| 198 { border, HTSYSMENU }, | |
| 199 { border + 10, HTSYSMENU }, | |
| 200 { border + 20, HTCAPTION }, | |
| 201 { border + 40, HTCLIENT }, | |
| 202 { border + 50, HTCLIENT }, | |
| 203 { 1000, HTNOWHERE }, | |
| 204 }; | |
| 205 | |
| 206 for (size_t i = 0; i < arraysize(cases); ++i) { | |
| 207 gfx::Point point(cases[i].point, cases[i].point); | |
| 208 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) | |
| 209 << " with border: " << border << ", at point " << cases[i].point; | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 TEST_F(DialogTest, BoundsAccommodateTitle) { | |
| 214 TestDialog* dialog2(new TestDialog()); | |
| 215 dialog2->set_title(base::ASCIIToUTF16("Title")); | |
| 216 DialogDelegate::CreateDialogWidget(dialog2, GetContext(), NULL); | |
| 217 | |
| 218 // Titled dialogs have taller initial frame bounds than untitled dialogs. | |
| 219 View* frame1 = dialog()->GetWidget()->non_client_view()->frame_view(); | |
| 220 View* frame2 = dialog2->GetWidget()->non_client_view()->frame_view(); | |
| 221 EXPECT_LT(frame1->GetPreferredSize().height(), | |
| 222 frame2->GetPreferredSize().height()); | |
| 223 | |
| 224 // Giving the default test dialog a title will yield the same bounds. | |
| 225 dialog()->set_title(base::ASCIIToUTF16("Title")); | |
| 226 dialog()->GetWidget()->UpdateWindowTitle(); | |
| 227 EXPECT_EQ(frame1->GetPreferredSize().height(), | |
| 228 frame2->GetPreferredSize().height()); | |
| 229 } | |
| 230 | |
| 231 } // namespace views | |
| OLD | NEW |