Chromium Code Reviews| 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 10 matching lines...) Expand all Loading... | |
| 21 #if defined(OS_MACOSX) | 21 #if defined(OS_MACOSX) |
| 22 #include "ui/base/test/scoped_fake_full_keyboard_access.h" | 22 #include "ui/base/test/scoped_fake_full_keyboard_access.h" |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 namespace views { | 25 namespace views { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 class TestDialog : public DialogDelegateView { | 29 class TestDialog : public DialogDelegateView { |
| 30 public: | 30 public: |
| 31 TestDialog() | 31 TestDialog() : input_(new views::Textfield()) { AddChildView(input_); } |
| 32 : input_(new views::Textfield()), | |
| 33 canceled_(false), | |
| 34 accepted_(false), | |
| 35 closed_(false), | |
| 36 closeable_(false), | |
| 37 should_handle_escape_(false) { | |
| 38 AddChildView(input_); | |
| 39 } | |
| 40 ~TestDialog() override {} | 32 ~TestDialog() override {} |
| 41 | 33 |
| 42 void Init() { | 34 void Init() { |
| 43 // Add the accelerator before being added to the widget hierarchy (before | 35 // Add the accelerator before being added to the widget hierarchy (before |
| 44 // DCV has registered its accelerator) to make sure accelerator handling is | 36 // DCV has registered its accelerator) to make sure accelerator handling is |
| 45 // not dependent on the order of AddAccelerator calls. | 37 // not dependent on the order of AddAccelerator calls. |
| 46 EXPECT_FALSE(GetWidget()); | 38 EXPECT_FALSE(GetWidget()); |
| 47 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 39 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
| 48 } | 40 } |
| 49 | 41 |
| 50 // WidgetDelegate overrides: | 42 // WidgetDelegate overrides: |
| 51 bool ShouldShowWindowTitle() const override { | 43 bool ShouldShowWindowTitle() const override { |
| 52 return !title_.empty(); | 44 return !title_.empty(); |
| 53 } | 45 } |
| 54 | 46 |
| 47 bool ShouldShowCloseButton() const override { return show_close_button_; } | |
| 48 | |
| 55 // DialogDelegateView overrides: | 49 // DialogDelegateView overrides: |
| 56 bool Cancel() override { | 50 bool Cancel() override { |
| 57 canceled_ = true; | 51 canceled_ = true; |
| 58 return closeable_; | 52 return closeable_; |
| 59 } | 53 } |
| 60 bool Accept() override { | 54 bool Accept() override { |
| 61 accepted_ = true; | 55 accepted_ = true; |
| 62 return closeable_; | 56 return closeable_; |
| 63 } | 57 } |
| 64 bool Close() override { | 58 bool Close() override { |
| 65 closed_ = true; | 59 closed_ = true; |
| 66 return closeable_; | 60 return closeable_; |
| 67 } | 61 } |
| 68 | 62 |
| 69 // DialogDelegateView overrides: | |
| 70 gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); } | 63 gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); } |
| 71 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { | 64 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { |
| 72 return should_handle_escape_; | 65 return should_handle_escape_; |
| 73 } | 66 } |
| 74 base::string16 GetWindowTitle() const override { return title_; } | 67 base::string16 GetWindowTitle() const override { return title_; } |
| 75 View* GetInitiallyFocusedView() override { return input_; } | 68 View* GetInitiallyFocusedView() override { return input_; } |
| 76 bool ShouldUseCustomFrame() const override { return true; } | 69 bool ShouldUseCustomFrame() const override { return true; } |
| 77 | 70 |
| 78 void CheckAndResetStates(bool canceled, | 71 void CheckAndResetStates(bool canceled, |
| 79 bool accepted, | 72 bool accepted, |
| 80 bool closed) { | 73 bool closed) { |
| 81 EXPECT_EQ(canceled, canceled_); | 74 EXPECT_EQ(canceled, canceled_); |
| 82 canceled_ = false; | 75 canceled_ = false; |
| 83 EXPECT_EQ(accepted, accepted_); | 76 EXPECT_EQ(accepted, accepted_); |
| 84 accepted_ = false; | 77 accepted_ = false; |
| 85 EXPECT_EQ(closed, closed_); | 78 EXPECT_EQ(closed, closed_); |
| 86 closed_ = false; | 79 closed_ = false; |
| 87 } | 80 } |
| 88 | 81 |
| 89 void TearDown() { | 82 void TearDown() { |
| 90 closeable_ = true; | 83 closeable_ = true; |
| 91 GetWidget()->Close(); | 84 GetWidget()->Close(); |
| 92 } | 85 } |
| 93 | 86 |
| 94 void set_title(const base::string16& title) { title_ = title; } | 87 void set_title(const base::string16& title) { title_ = title; } |
| 88 void set_show_close_button(bool show_close) { | |
| 89 show_close_button_ = show_close; | |
| 90 } | |
| 95 void set_should_handle_escape(bool should_handle_escape) { | 91 void set_should_handle_escape(bool should_handle_escape) { |
| 96 should_handle_escape_ = should_handle_escape; | 92 should_handle_escape_ = should_handle_escape; |
| 97 } | 93 } |
| 98 | 94 |
| 99 views::Textfield* input() { return input_; } | 95 views::Textfield* input() { return input_; } |
| 100 | 96 |
| 101 private: | 97 private: |
| 102 views::Textfield* input_; | 98 views::Textfield* input_; |
| 103 bool canceled_; | 99 bool canceled_ = false; |
| 104 bool accepted_; | 100 bool accepted_ = false; |
| 105 bool closed_; | 101 bool closed_ = false; |
| 106 // Prevent the dialog from closing, for repeated ok and cancel button clicks. | 102 // Prevent the dialog from closing, for repeated ok and cancel button clicks. |
| 107 bool closeable_; | 103 bool closeable_; |
| 108 base::string16 title_; | 104 base::string16 title_; |
| 109 bool should_handle_escape_; | 105 bool show_close_button_ = true; |
| 106 bool should_handle_escape_ = false; | |
| 110 | 107 |
| 111 DISALLOW_COPY_AND_ASSIGN(TestDialog); | 108 DISALLOW_COPY_AND_ASSIGN(TestDialog); |
| 112 }; | 109 }; |
| 113 | 110 |
| 114 class DialogTest : public ViewsTestBase { | 111 class DialogTest : public ViewsTestBase { |
| 115 public: | 112 public: |
| 116 DialogTest() : dialog_(nullptr) {} | 113 DialogTest() : dialog_(nullptr) {} |
| 117 ~DialogTest() override {} | 114 ~DialogTest() override {} |
| 118 | 115 |
| 119 void SetUp() override { | 116 void SetUp() override { |
| 120 ViewsTestBase::SetUp(); | 117 ViewsTestBase::SetUp(); |
| 121 dialog_ = new TestDialog(); | 118 InitializeDialog(); |
| 122 dialog_->Init(); | 119 ShowDialog(); |
| 123 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr)->Show(); | |
| 124 } | 120 } |
| 125 | 121 |
| 126 void TearDown() override { | 122 void TearDown() override { |
| 127 dialog_->TearDown(); | 123 dialog_->TearDown(); |
| 128 ViewsTestBase::TearDown(); | 124 ViewsTestBase::TearDown(); |
| 129 } | 125 } |
| 130 | 126 |
| 127 void InitializeDialog() { | |
| 128 if (dialog_) | |
| 129 dialog_->TearDown(); | |
| 130 | |
| 131 dialog_ = new TestDialog(); | |
| 132 dialog_->Init(); | |
| 133 } | |
| 134 | |
| 135 void ShowDialog() { | |
| 136 DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr)->Show(); | |
| 137 } | |
| 138 | |
| 131 void SimulateKeyEvent(const ui::KeyEvent& event) { | 139 void SimulateKeyEvent(const ui::KeyEvent& event) { |
| 132 ui::KeyEvent event_copy = event; | 140 ui::KeyEvent event_copy = event; |
| 133 if (dialog()->GetFocusManager()->OnKeyEvent(event_copy)) | 141 if (dialog()->GetFocusManager()->OnKeyEvent(event_copy)) |
| 134 dialog()->GetWidget()->OnKeyEvent(&event_copy); | 142 dialog()->GetWidget()->OnKeyEvent(&event_copy); |
| 135 } | 143 } |
| 136 | 144 |
| 137 TestDialog* dialog() const { return dialog_; } | 145 TestDialog* dialog() const { return dialog_; } |
| 138 | 146 |
| 139 private: | 147 private: |
| 140 TestDialog* dialog_; | 148 TestDialog* dialog_; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 delete dialog()->GetDialogClientView()->cancel_button(); | 206 delete dialog()->GetDialogClientView()->cancel_button(); |
| 199 } | 207 } |
| 200 | 208 |
| 201 TEST_F(DialogTest, HitTest_HiddenTitle) { | 209 TEST_F(DialogTest, HitTest_HiddenTitle) { |
| 202 // Ensure that BubbleFrameView hit-tests as expected when the title is hidden. | 210 // Ensure that BubbleFrameView hit-tests as expected when the title is hidden. |
| 203 const NonClientView* view = dialog()->GetWidget()->non_client_view(); | 211 const NonClientView* view = dialog()->GetWidget()->non_client_view(); |
| 204 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); | 212 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); |
| 205 const int border = frame->bubble_border()->GetBorderThickness(); | 213 const int border = frame->bubble_border()->GetBorderThickness(); |
| 206 | 214 |
| 207 struct { | 215 struct { |
| 208 const int point; | 216 int point; |
| 209 const int hit; | 217 int hit; |
| 218 } cases[] = { | |
| 219 {border, HTSYSMENU}, | |
| 220 {border + 10, HTSYSMENU}, | |
| 221 {border + 20, HTNOWHERE}, | |
| 222 {border + 50, HTCLIENT /* Space is reserved for the close button. */}, | |
| 223 {border + 60, HTCLIENT}, | |
| 224 {1000, HTNOWHERE}, | |
| 225 }; | |
| 226 | |
| 227 for (size_t i = 0; i < arraysize(cases); ++i) { | |
| 228 gfx::Point point(cases[i].point, cases[i].point); | |
| 229 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) | |
| 230 << " case " << i << " with border: " << border << ", at point " | |
| 231 << cases[i].point; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 TEST_F(DialogTest, HitTest_HiddenTitleNoCloseButton) { | |
| 236 InitializeDialog(); | |
| 237 dialog()->set_show_close_button(false); | |
| 238 ShowDialog(); | |
|
Peter Kasting
2017/04/13 23:47:35
Cool, this route is more readable than the old cod
Evan Stade
2017/04/13 23:51:24
honestly, would rather not let this change snowbal
Peter Kasting
2017/04/13 23:53:35
OK. I just figured you introduced this in part be
| |
| 239 | |
| 240 const NonClientView* view = dialog()->GetWidget()->non_client_view(); | |
| 241 BubbleFrameView* frame = static_cast<BubbleFrameView*>(view->frame_view()); | |
| 242 const int border = frame->bubble_border()->GetBorderThickness(); | |
| 243 | |
| 244 struct { | |
| 245 int point; | |
| 246 int hit; | |
| 210 } cases[] = { | 247 } cases[] = { |
| 211 { border, HTSYSMENU }, | 248 { border, HTSYSMENU }, |
| 212 { border + 10, HTSYSMENU }, | 249 { border + 10, HTSYSMENU }, |
| 213 { border + 20, HTCLIENT }, | 250 { border + 20, HTCLIENT }, |
| 214 { border + 50, HTCLIENT }, | 251 { border + 50, HTCLIENT }, |
| 215 { border + 60, HTCLIENT }, | 252 { border + 60, HTCLIENT }, |
| 216 { 1000, HTNOWHERE }, | 253 { 1000, HTNOWHERE }, |
| 217 }; | 254 }; |
| 218 | 255 |
| 219 for (size_t i = 0; i < arraysize(cases); ++i) { | 256 for (size_t i = 0; i < arraysize(cases); ++i) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 // On showing the dialog, the initially focused View will be the OK button. | 380 // On showing the dialog, the initially focused View will be the OK button. |
| 344 // Since it is no longer focusable, focus should advance to the next focusable | 381 // Since it is no longer focusable, focus should advance to the next focusable |
| 345 // View, which is |textfield|. | 382 // View, which is |textfield|. |
| 346 dialog_widget->Show(); | 383 dialog_widget->Show(); |
| 347 EXPECT_TRUE(textfield->HasFocus()); | 384 EXPECT_TRUE(textfield->HasFocus()); |
| 348 EXPECT_EQ(textfield, dialog->GetFocusManager()->GetFocusedView()); | 385 EXPECT_EQ(textfield, dialog->GetFocusManager()->GetFocusedView()); |
| 349 dialog_widget->CloseNow(); | 386 dialog_widget->CloseNow(); |
| 350 } | 387 } |
| 351 | 388 |
| 352 } // namespace views | 389 } // namespace views |
| OLD | NEW |