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 "ui/views/controls/combobox/combobox.h" | 5 #include "ui/views/controls/combobox/combobox.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "ui/base/ime/input_method.h" | 11 #include "ui/base/ime/input_method.h" |
| 12 #include "ui/base/ime/text_input_client.h" | 12 #include "ui/base/ime/text_input_client.h" |
| 13 #include "ui/base/models/combobox_model.h" | 13 #include "ui/base/models/combobox_model.h" |
| 14 #include "ui/base/models/menu_model.h" | |
| 14 #include "ui/events/event.h" | 15 #include "ui/events/event.h" |
| 15 #include "ui/events/event_constants.h" | 16 #include "ui/events/event_constants.h" |
| 16 #include "ui/events/event_utils.h" | 17 #include "ui/events/event_utils.h" |
| 17 #include "ui/events/keycodes/keyboard_codes.h" | 18 #include "ui/events/keycodes/keyboard_codes.h" |
| 18 #include "ui/views/controls/combobox/combobox_listener.h" | 19 #include "ui/views/controls/combobox/combobox_listener.h" |
| 19 #include "ui/views/controls/menu/menu_runner.h" | 20 #include "ui/views/controls/menu/menu_runner.h" |
| 20 #include "ui/views/controls/menu/menu_runner_handler.h" | 21 #include "ui/views/controls/menu/menu_runner_handler.h" |
| 21 #include "ui/views/test/menu_runner_test_api.h" | 22 #include "ui/views/test/menu_runner_test_api.h" |
| 22 #include "ui/views/test/views_test_base.h" | 23 #include "ui/views/test/views_test_base.h" |
| 23 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
| 24 | 25 |
| 25 using base::ASCIIToUTF16; | 26 using base::ASCIIToUTF16; |
| 26 | 27 |
| 27 namespace views { | 28 namespace views { |
| 29 namespace test { | |
| 30 | |
| 31 class ComboboxTestApi { | |
| 32 public: | |
| 33 explicit ComboboxTestApi(Combobox* combobox) : combobox_(combobox) {} | |
| 34 | |
| 35 void PerformActionAt(int index) { menu_model()->ActivatedAt(index); } | |
| 36 void InstallTestMenuRunner(); | |
| 37 | |
| 38 gfx::Size content_size() { return combobox_->content_size_; } | |
| 39 ui::MenuModel* menu_model() { return combobox_->GetMenuModelForTest(); } | |
| 40 int menu_show_count() { return menu_show_count_; } | |
| 41 | |
| 42 private: | |
| 43 Combobox* combobox_; | |
| 44 int menu_show_count_ = 0; | |
|
sky
2015/09/03 17:52:27
Is there a reason you need this as a member rather
tapted
2015/09/04 00:46:54
Nope. Moved it out (now an argument of InstallTest
| |
| 45 | |
| 46 DISALLOW_COPY_AND_ASSIGN(ComboboxTestApi); | |
| 47 }; | |
| 48 | |
| 49 } // namespace test | |
| 50 | |
| 51 using test::ComboboxTestApi; | |
| 28 | 52 |
| 29 namespace { | 53 namespace { |
| 30 | 54 |
| 31 // An dummy implementation of MenuRunnerHandler to check if the dropdown menu is | 55 // An dummy implementation of MenuRunnerHandler to check if the dropdown menu is |
| 32 // shown or not. | 56 // shown or not. |
| 33 class TestMenuRunnerHandler : public MenuRunnerHandler { | 57 class TestMenuRunnerHandler : public MenuRunnerHandler { |
| 34 public: | 58 public: |
| 35 TestMenuRunnerHandler() : executed_(false) {} | 59 explicit TestMenuRunnerHandler(int* show_counter) |
| 36 | 60 : show_counter_(show_counter) {} |
| 37 bool executed() const { return executed_; } | |
| 38 | |
| 39 MenuRunner::RunResult RunMenuAt(Widget* parent, | 61 MenuRunner::RunResult RunMenuAt(Widget* parent, |
| 40 MenuButton* button, | 62 MenuButton* button, |
| 41 const gfx::Rect& bounds, | 63 const gfx::Rect& bounds, |
| 42 MenuAnchorPosition anchor, | 64 MenuAnchorPosition anchor, |
| 43 ui::MenuSourceType source_type, | 65 ui::MenuSourceType source_type, |
| 44 int32 types) override { | 66 int32 types) override { |
| 45 executed_ = true; | 67 *show_counter_ += 1; |
| 46 return MenuRunner::NORMAL_EXIT; | 68 return MenuRunner::NORMAL_EXIT; |
| 47 } | 69 } |
| 48 | 70 |
| 49 private: | 71 private: |
| 50 bool executed_; | 72 int* show_counter_; |
| 51 | 73 |
| 52 DISALLOW_COPY_AND_ASSIGN(TestMenuRunnerHandler); | 74 DISALLOW_COPY_AND_ASSIGN(TestMenuRunnerHandler); |
| 53 }; | 75 }; |
| 54 | 76 |
| 55 // A wrapper of Combobox to intercept the result of OnKeyPressed() and | 77 // A wrapper of Combobox to intercept the result of OnKeyPressed() and |
| 56 // OnKeyReleased() methods. | 78 // OnKeyReleased() methods. |
| 57 class TestCombobox : public Combobox { | 79 class TestCombobox : public Combobox { |
| 58 public: | 80 public: |
| 59 explicit TestCombobox(ui::ComboboxModel* model) | 81 explicit TestCombobox(ui::ComboboxModel* model) |
| 60 : Combobox(model), | 82 : Combobox(model), |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 86 | 108 |
| 87 DISALLOW_COPY_AND_ASSIGN(TestCombobox); | 109 DISALLOW_COPY_AND_ASSIGN(TestCombobox); |
| 88 }; | 110 }; |
| 89 | 111 |
| 90 // A concrete class is needed to test the combobox. | 112 // A concrete class is needed to test the combobox. |
| 91 class TestComboboxModel : public ui::ComboboxModel { | 113 class TestComboboxModel : public ui::ComboboxModel { |
| 92 public: | 114 public: |
| 93 TestComboboxModel() {} | 115 TestComboboxModel() {} |
| 94 ~TestComboboxModel() override {} | 116 ~TestComboboxModel() override {} |
| 95 | 117 |
| 96 static const int kItemCount = 10; | 118 enum { kItemCount = 10 }; |
| 97 | 119 |
| 98 // ui::ComboboxModel: | 120 // ui::ComboboxModel: |
| 99 int GetItemCount() const override { return kItemCount; } | 121 int GetItemCount() const override { return kItemCount; } |
| 100 base::string16 GetItemAt(int index) override { | 122 base::string16 GetItemAt(int index) override { |
| 101 if (IsItemSeparatorAt(index)) { | 123 if (IsItemSeparatorAt(index)) { |
| 102 NOTREACHED(); | 124 NOTREACHED(); |
| 103 return ASCIIToUTF16("SEPARATOR"); | 125 return ASCIIToUTF16("SEPARATOR"); |
| 104 } | 126 } |
| 105 return ASCIIToUTF16(index % 2 == 0 ? "PEANUT BUTTER" : "JELLY"); | 127 return ASCIIToUTF16(index % 2 == 0 ? "PEANUT BUTTER" : "JELLY"); |
| 106 } | 128 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 128 DISALLOW_COPY_AND_ASSIGN(TestComboboxModel); | 150 DISALLOW_COPY_AND_ASSIGN(TestComboboxModel); |
| 129 }; | 151 }; |
| 130 | 152 |
| 131 // A combobox model which refers to a vector. | 153 // A combobox model which refers to a vector. |
| 132 class VectorComboboxModel : public ui::ComboboxModel { | 154 class VectorComboboxModel : public ui::ComboboxModel { |
| 133 public: | 155 public: |
| 134 explicit VectorComboboxModel(std::vector<std::string>* values) | 156 explicit VectorComboboxModel(std::vector<std::string>* values) |
| 135 : values_(values) {} | 157 : values_(values) {} |
| 136 ~VectorComboboxModel() override {} | 158 ~VectorComboboxModel() override {} |
| 137 | 159 |
| 160 void set_default_index(int default_index) { default_index_ = default_index; } | |
| 161 | |
| 138 // ui::ComboboxModel: | 162 // ui::ComboboxModel: |
| 139 int GetItemCount() const override { return (int)values_->size(); } | 163 int GetItemCount() const override { return (int)values_->size(); } |
| 140 base::string16 GetItemAt(int index) override { | 164 base::string16 GetItemAt(int index) override { |
| 141 return ASCIIToUTF16(values_->at(index)); | 165 return ASCIIToUTF16(values_->at(index)); |
| 142 } | 166 } |
| 143 bool IsItemSeparatorAt(int index) override { return false; } | 167 bool IsItemSeparatorAt(int index) override { return false; } |
| 168 int GetDefaultIndex() const override { return default_index_; } | |
| 144 | 169 |
| 145 private: | 170 private: |
| 146 std::vector<std::string>* values_; | 171 std::vector<std::string>* values_; |
| 172 int default_index_ = 0; | |
| 173 | |
| 174 DISALLOW_COPY_AND_ASSIGN(VectorComboboxModel); | |
| 147 }; | 175 }; |
| 148 | 176 |
| 149 class EvilListener : public ComboboxListener { | 177 class EvilListener : public ComboboxListener { |
| 150 public: | 178 public: |
| 151 EvilListener() : deleted_(false) {} | 179 EvilListener() : deleted_(false) {} |
| 152 ~EvilListener() override{}; | 180 ~EvilListener() override{}; |
| 153 | 181 |
| 154 // ComboboxListener: | 182 // ComboboxListener: |
| 155 void OnPerformAction(Combobox* combobox) override { | 183 void OnPerformAction(Combobox* combobox) override { |
| 156 delete combobox; | 184 delete combobox; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 private: | 218 private: |
| 191 int perform_action_index_; | 219 int perform_action_index_; |
| 192 int actions_performed_; | 220 int actions_performed_; |
| 193 | 221 |
| 194 private: | 222 private: |
| 195 DISALLOW_COPY_AND_ASSIGN(TestComboboxListener); | 223 DISALLOW_COPY_AND_ASSIGN(TestComboboxListener); |
| 196 }; | 224 }; |
| 197 | 225 |
| 198 } // namespace | 226 } // namespace |
| 199 | 227 |
| 228 void ComboboxTestApi::InstallTestMenuRunner() { | |
| 229 combobox_->menu_runner_.reset( | |
| 230 new MenuRunner(menu_model(), MenuRunner::COMBOBOX)); | |
| 231 test::MenuRunnerTestAPI test_api(combobox_->menu_runner_.get()); | |
| 232 test_api.SetMenuRunnerHandler( | |
| 233 make_scoped_ptr(new TestMenuRunnerHandler(&menu_show_count_))); | |
| 234 } | |
| 235 | |
| 200 class ComboboxTest : public ViewsTestBase { | 236 class ComboboxTest : public ViewsTestBase { |
| 201 public: | 237 public: |
| 202 ComboboxTest() : widget_(NULL), combobox_(NULL) {} | 238 ComboboxTest() : widget_(NULL), combobox_(NULL) {} |
| 203 | 239 |
| 204 void TearDown() override { | 240 void TearDown() override { |
| 205 if (widget_) | 241 if (widget_) |
| 206 widget_->Close(); | 242 widget_->Close(); |
| 207 ViewsTestBase::TearDown(); | 243 ViewsTestBase::TearDown(); |
| 208 } | 244 } |
| 209 | 245 |
| 210 void InitCombobox(const std::set<int>* separators) { | 246 void InitCombobox(const std::set<int>* separators) { |
| 211 model_.reset(new TestComboboxModel()); | 247 model_.reset(new TestComboboxModel()); |
| 212 | 248 |
| 213 if (separators) | 249 if (separators) |
| 214 model_->SetSeparators(*separators); | 250 model_->SetSeparators(*separators); |
| 215 | 251 |
| 216 ASSERT_FALSE(combobox_); | 252 ASSERT_FALSE(combobox_); |
| 217 combobox_ = new TestCombobox(model_.get()); | 253 combobox_ = new TestCombobox(model_.get()); |
| 254 test_api_.reset(new ComboboxTestApi(combobox_)); | |
| 218 combobox_->set_id(1); | 255 combobox_->set_id(1); |
| 219 | 256 |
| 220 widget_ = new Widget; | 257 widget_ = new Widget; |
| 221 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 258 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
| 222 params.bounds = gfx::Rect(200, 200, 200, 200); | 259 params.bounds = gfx::Rect(200, 200, 200, 200); |
| 223 widget_->Init(params); | 260 widget_->Init(params); |
| 224 View* container = new View(); | 261 View* container = new View(); |
| 225 widget_->SetContentsView(container); | 262 widget_->SetContentsView(container); |
| 226 container->AddChildView(combobox_); | 263 container->AddChildView(combobox_); |
| 227 | 264 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 255 ui::ET_MOUSE_RELEASED, point, point, ui::EventTimeForNow(), | 292 ui::ET_MOUSE_RELEASED, point, point, ui::EventTimeForNow(), |
| 256 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 293 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 257 widget_->OnMouseEvent(&released_event); | 294 widget_->OnMouseEvent(&released_event); |
| 258 } | 295 } |
| 259 | 296 |
| 260 // We need widget to populate wrapper class. | 297 // We need widget to populate wrapper class. |
| 261 Widget* widget_; | 298 Widget* widget_; |
| 262 | 299 |
| 263 // |combobox_| will be allocated InitCombobox() and then owned by |widget_|. | 300 // |combobox_| will be allocated InitCombobox() and then owned by |widget_|. |
| 264 TestCombobox* combobox_; | 301 TestCombobox* combobox_; |
| 302 scoped_ptr<ComboboxTestApi> test_api_; | |
| 265 | 303 |
| 266 // Combobox does not take ownership of the model, hence it needs to be scoped. | 304 // Combobox does not take ownership of the model, hence it needs to be scoped. |
| 267 scoped_ptr<TestComboboxModel> model_; | 305 scoped_ptr<TestComboboxModel> model_; |
| 306 | |
| 307 private: | |
| 308 DISALLOW_COPY_AND_ASSIGN(ComboboxTest); | |
| 268 }; | 309 }; |
| 269 | 310 |
| 270 TEST_F(ComboboxTest, KeyTest) { | 311 TEST_F(ComboboxTest, KeyTest) { |
| 271 InitCombobox(NULL); | 312 InitCombobox(NULL); |
| 272 SendKeyEvent(ui::VKEY_END); | 313 SendKeyEvent(ui::VKEY_END); |
| 273 EXPECT_EQ(combobox_->selected_index() + 1, model_->GetItemCount()); | 314 EXPECT_EQ(combobox_->selected_index() + 1, model_->GetItemCount()); |
| 274 SendKeyEvent(ui::VKEY_HOME); | 315 SendKeyEvent(ui::VKEY_HOME); |
| 275 EXPECT_EQ(combobox_->selected_index(), 0); | 316 EXPECT_EQ(combobox_->selected_index(), 0); |
| 276 SendKeyEvent(ui::VKEY_DOWN); | 317 SendKeyEvent(ui::VKEY_DOWN); |
| 277 SendKeyEvent(ui::VKEY_DOWN); | 318 SendKeyEvent(ui::VKEY_DOWN); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 EXPECT_EQ(0, combobox_->selected_index()); | 519 EXPECT_EQ(0, combobox_->selected_index()); |
| 479 } | 520 } |
| 480 | 521 |
| 481 TEST_F(ComboboxTest, ListenerHandlesDelete) { | 522 TEST_F(ComboboxTest, ListenerHandlesDelete) { |
| 482 TestComboboxModel model; | 523 TestComboboxModel model; |
| 483 | 524 |
| 484 // |combobox| will be deleted on change. | 525 // |combobox| will be deleted on change. |
| 485 TestCombobox* combobox = new TestCombobox(&model); | 526 TestCombobox* combobox = new TestCombobox(&model); |
| 486 scoped_ptr<EvilListener> evil_listener(new EvilListener()); | 527 scoped_ptr<EvilListener> evil_listener(new EvilListener()); |
| 487 combobox->set_listener(evil_listener.get()); | 528 combobox->set_listener(evil_listener.get()); |
| 488 ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2)); | 529 ASSERT_NO_FATAL_FAILURE(ComboboxTestApi(combobox).PerformActionAt(2)); |
| 489 EXPECT_TRUE(evil_listener->deleted()); | 530 EXPECT_TRUE(evil_listener->deleted()); |
| 490 | 531 |
| 491 // With STYLE_ACTION | 532 // With STYLE_ACTION |
| 492 // |combobox| will be deleted on change. | 533 // |combobox| will be deleted on change. |
| 493 combobox = new TestCombobox(&model); | 534 combobox = new TestCombobox(&model); |
| 494 evil_listener.reset(new EvilListener()); | 535 evil_listener.reset(new EvilListener()); |
| 495 combobox->set_listener(evil_listener.get()); | 536 combobox->set_listener(evil_listener.get()); |
| 496 combobox->SetStyle(Combobox::STYLE_ACTION); | 537 combobox->SetStyle(Combobox::STYLE_ACTION); |
| 497 ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2)); | 538 ASSERT_NO_FATAL_FAILURE(ComboboxTestApi(combobox).PerformActionAt(2)); |
| 498 EXPECT_TRUE(evil_listener->deleted()); | 539 EXPECT_TRUE(evil_listener->deleted()); |
| 499 } | 540 } |
| 500 | 541 |
| 501 TEST_F(ComboboxTest, Click) { | 542 TEST_F(ComboboxTest, Click) { |
| 502 InitCombobox(NULL); | 543 InitCombobox(NULL); |
| 503 | 544 |
| 504 TestComboboxListener listener; | 545 TestComboboxListener listener; |
| 505 combobox_->set_listener(&listener); | 546 combobox_->set_listener(&listener); |
| 506 | 547 |
| 507 combobox_->Layout(); | 548 combobox_->Layout(); |
| 549 test_api_->InstallTestMenuRunner(); | |
| 508 | 550 |
| 509 // Click the left side. The menu is shown. | 551 // Click the left side. The menu is shown. |
| 510 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 552 EXPECT_EQ(0, test_api_->menu_show_count()); |
| 511 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | |
| 512 test::MenuRunnerTestAPI test_api( | |
| 513 combobox_->dropdown_list_menu_runner_.get()); | |
| 514 test_api.SetMenuRunnerHandler(menu_runner_handler.Pass()); | |
| 515 PerformClick(gfx::Point(combobox_->x() + 1, | 553 PerformClick(gfx::Point(combobox_->x() + 1, |
| 516 combobox_->y() + combobox_->height() / 2)); | 554 combobox_->y() + combobox_->height() / 2)); |
| 517 EXPECT_FALSE(listener.on_perform_action_called()); | 555 EXPECT_FALSE(listener.on_perform_action_called()); |
| 518 EXPECT_TRUE(test_menu_runner_handler->executed()); | 556 EXPECT_EQ(1, test_api_->menu_show_count()); |
| 519 } | 557 } |
| 520 | 558 |
| 521 TEST_F(ComboboxTest, ClickButDisabled) { | 559 TEST_F(ComboboxTest, ClickButDisabled) { |
| 522 InitCombobox(NULL); | 560 InitCombobox(NULL); |
| 523 | 561 |
| 524 TestComboboxListener listener; | 562 TestComboboxListener listener; |
| 525 combobox_->set_listener(&listener); | 563 combobox_->set_listener(&listener); |
| 526 | 564 |
| 527 combobox_->Layout(); | 565 combobox_->Layout(); |
| 528 combobox_->SetEnabled(false); | 566 combobox_->SetEnabled(false); |
| 529 | 567 |
| 530 // Click the left side, but nothing happens since the combobox is disabled. | 568 // Click the left side, but nothing happens since the combobox is disabled. |
| 531 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 569 test_api_->InstallTestMenuRunner(); |
| 532 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | |
| 533 test::MenuRunnerTestAPI test_api( | |
| 534 combobox_->dropdown_list_menu_runner_.get()); | |
| 535 test_api.SetMenuRunnerHandler(menu_runner_handler.Pass()); | |
| 536 PerformClick(gfx::Point(combobox_->x() + 1, | 570 PerformClick(gfx::Point(combobox_->x() + 1, |
| 537 combobox_->y() + combobox_->height() / 2)); | 571 combobox_->y() + combobox_->height() / 2)); |
| 538 EXPECT_FALSE(listener.on_perform_action_called()); | 572 EXPECT_FALSE(listener.on_perform_action_called()); |
| 539 EXPECT_FALSE(test_menu_runner_handler->executed()); | 573 EXPECT_EQ(0, test_api_->menu_show_count()); |
| 540 } | 574 } |
| 541 | 575 |
| 542 TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) { | 576 TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) { |
| 543 InitCombobox(NULL); | 577 InitCombobox(NULL); |
| 544 | 578 |
| 545 TestComboboxListener listener; | 579 TestComboboxListener listener; |
| 546 combobox_->set_listener(&listener); | 580 combobox_->set_listener(&listener); |
| 547 | 581 |
| 548 // With STYLE_NORMAL, the click event is ignored. | 582 // With STYLE_NORMAL, the click event is ignored. |
| 549 SendKeyEvent(ui::VKEY_RETURN); | 583 SendKeyEvent(ui::VKEY_RETURN); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 580 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { | 614 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { |
| 581 InitCombobox(NULL); | 615 InitCombobox(NULL); |
| 582 | 616 |
| 583 TestComboboxListener listener; | 617 TestComboboxListener listener; |
| 584 combobox_->set_listener(&listener); | 618 combobox_->set_listener(&listener); |
| 585 | 619 |
| 586 combobox_->SetStyle(Combobox::STYLE_ACTION); | 620 combobox_->SetStyle(Combobox::STYLE_ACTION); |
| 587 combobox_->Layout(); | 621 combobox_->Layout(); |
| 588 | 622 |
| 589 // Click the right side (arrow button). The menu is shown. | 623 // Click the right side (arrow button). The menu is shown. |
| 590 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 624 test_api_->InstallTestMenuRunner(); |
| 591 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | 625 EXPECT_EQ(0, test_api_->menu_show_count()); |
| 592 scoped_ptr<test::MenuRunnerTestAPI> test_api( | |
| 593 new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | |
| 594 test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | |
| 595 | |
| 596 PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, | 626 PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, |
| 597 combobox_->y() + combobox_->height() / 2)); | 627 combobox_->y() + combobox_->height() / 2)); |
| 598 EXPECT_FALSE(listener.on_perform_action_called()); | 628 EXPECT_FALSE(listener.on_perform_action_called()); |
| 599 EXPECT_TRUE(test_menu_runner_handler->executed()); | 629 EXPECT_EQ(1, test_api_->menu_show_count()); |
| 600 | 630 |
| 601 // Click the left side (text button). The click event is notified. | 631 // Click the left side (text button). The click event is notified. |
| 602 test_menu_runner_handler = new TestMenuRunnerHandler(); | 632 test_api_->InstallTestMenuRunner(); |
| 603 menu_runner_handler.reset(test_menu_runner_handler); | |
| 604 test_api.reset( | |
| 605 new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | |
| 606 test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | |
| 607 PerformClick(gfx::Point(combobox_->x() + 1, | 633 PerformClick(gfx::Point(combobox_->x() + 1, |
| 608 combobox_->y() + combobox_->height() / 2)); | 634 combobox_->y() + combobox_->height() / 2)); |
| 609 EXPECT_TRUE(listener.on_perform_action_called()); | 635 EXPECT_TRUE(listener.on_perform_action_called()); |
| 610 EXPECT_FALSE(test_menu_runner_handler->executed()); | 636 EXPECT_EQ(1, test_api_->menu_show_count()); // Unchanged. |
| 611 EXPECT_EQ(0, listener.perform_action_index()); | 637 EXPECT_EQ(0, listener.perform_action_index()); |
| 612 } | 638 } |
| 613 | 639 |
| 614 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { | 640 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { |
| 615 InitCombobox(NULL); | 641 InitCombobox(NULL); |
| 616 | 642 |
| 617 EXPECT_FALSE(combobox_->OnKeyPressed( | 643 EXPECT_FALSE(combobox_->OnKeyPressed( |
| 618 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE))); | 644 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE))); |
| 619 EXPECT_FALSE(combobox_->OnKeyPressed( | 645 EXPECT_FALSE(combobox_->OnKeyPressed( |
| 620 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE))); | 646 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE))); |
| 621 | 647 |
| 622 // When the combobox's style is STYLE_ACTION, pressing events of a space key | 648 // When the combobox's style is STYLE_ACTION, pressing events of a space key |
| 623 // or an enter key will be consumed. | 649 // or an enter key will be consumed. |
| 624 combobox_->SetStyle(Combobox::STYLE_ACTION); | 650 combobox_->SetStyle(Combobox::STYLE_ACTION); |
| 625 EXPECT_TRUE(combobox_->OnKeyPressed( | 651 EXPECT_TRUE(combobox_->OnKeyPressed( |
| 626 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE))); | 652 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE))); |
| 627 EXPECT_TRUE(combobox_->OnKeyPressed( | 653 EXPECT_TRUE(combobox_->OnKeyPressed( |
| 628 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE))); | 654 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE))); |
| 629 } | 655 } |
| 630 | 656 |
| 631 TEST_F(ComboboxTest, ContentWidth) { | 657 TEST_F(ComboboxTest, ContentWidth) { |
| 632 std::vector<std::string> values; | 658 std::vector<std::string> values; |
| 633 VectorComboboxModel model(&values); | 659 VectorComboboxModel model(&values); |
| 634 TestCombobox combobox(&model); | 660 TestCombobox combobox(&model); |
| 661 ComboboxTestApi test_api(&combobox); | |
| 635 | 662 |
| 636 std::string long_item = "this is the long item"; | 663 std::string long_item = "this is the long item"; |
| 637 std::string short_item = "s"; | 664 std::string short_item = "s"; |
| 638 | 665 |
| 639 values.resize(1); | 666 values.resize(1); |
| 640 values[0] = long_item; | 667 values[0] = long_item; |
| 641 combobox.ModelChanged(); | 668 combobox.ModelChanged(); |
| 642 | 669 |
| 643 const int long_item_width = combobox.content_size_.width(); | 670 const int long_item_width = test_api.content_size().width(); |
| 644 | 671 |
| 645 values[0] = short_item; | 672 values[0] = short_item; |
| 646 combobox.ModelChanged(); | 673 combobox.ModelChanged(); |
| 647 | 674 |
| 648 const int short_item_width = combobox.content_size_.width(); | 675 const int short_item_width = test_api.content_size().width(); |
| 649 | 676 |
| 650 values.resize(2); | 677 values.resize(2); |
| 651 values[0] = short_item; | 678 values[0] = short_item; |
| 652 values[1] = long_item; | 679 values[1] = long_item; |
| 653 combobox.ModelChanged(); | 680 combobox.ModelChanged(); |
| 654 | 681 |
| 655 // When the style is STYLE_NORMAL, the width will fit with the longest item. | 682 // When the style is STYLE_NORMAL, the width will fit with the longest item. |
| 656 combobox.SetStyle(Combobox::STYLE_NORMAL); | 683 combobox.SetStyle(Combobox::STYLE_NORMAL); |
| 657 EXPECT_EQ(long_item_width, combobox.content_size_.width()); | 684 EXPECT_EQ(long_item_width, test_api.content_size().width()); |
| 658 | 685 |
| 659 // When the style is STYLE_ACTION, the width will fit with the first items' | 686 // When the style is STYLE_ACTION, the width will fit with the selected item's |
| 660 // width. | 687 // width. |
| 661 combobox.SetStyle(Combobox::STYLE_ACTION); | 688 combobox.SetStyle(Combobox::STYLE_ACTION); |
| 662 EXPECT_EQ(short_item_width, combobox.content_size_.width()); | 689 EXPECT_EQ(short_item_width, test_api.content_size().width()); |
| 690 | |
| 691 // Note the "action" style ignores SetSelectedIndex(), but can specify the | |
| 692 // default index in its model. | |
| 693 model.set_default_index(1); | |
| 694 combobox.ModelChanged(); | |
| 695 EXPECT_EQ(long_item_width, test_api.content_size().width()); | |
| 663 } | 696 } |
| 664 | 697 |
| 665 TEST_F(ComboboxTest, TypingPrefixNotifiesListener) { | 698 TEST_F(ComboboxTest, TypingPrefixNotifiesListener) { |
| 666 InitCombobox(NULL); | 699 InitCombobox(NULL); |
| 667 | 700 |
| 668 TestComboboxListener listener; | 701 TestComboboxListener listener; |
| 669 combobox_->set_listener(&listener); | 702 combobox_->set_listener(&listener); |
| 670 ui::TextInputClient* input_client = | 703 ui::TextInputClient* input_client = |
| 671 widget_->GetInputMethod()->GetTextInputClient(); | 704 widget_->GetInputMethod()->GetTextInputClient(); |
| 672 | 705 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 685 combobox_->OnBlur(); | 718 combobox_->OnBlur(); |
| 686 combobox_->RequestFocus(); | 719 combobox_->RequestFocus(); |
| 687 | 720 |
| 688 // Type the first character of "PEANUT BUTTER", which should change the | 721 // Type the first character of "PEANUT BUTTER", which should change the |
| 689 // selected index and perform an action. | 722 // selected index and perform an action. |
| 690 input_client->InsertChar('P', ui::EF_NONE); | 723 input_client->InsertChar('P', ui::EF_NONE); |
| 691 EXPECT_EQ(2, listener.actions_performed()); | 724 EXPECT_EQ(2, listener.actions_performed()); |
| 692 EXPECT_EQ(2, listener.perform_action_index()); | 725 EXPECT_EQ(2, listener.perform_action_index()); |
| 693 } | 726 } |
| 694 | 727 |
| 728 // Test properties on the Combobox menu model. | |
| 729 TEST_F(ComboboxTest, MenuModel) { | |
| 730 const int kSeparatorIndex = 3; | |
| 731 std::set<int> separators; | |
| 732 separators.insert(kSeparatorIndex); | |
| 733 InitCombobox(&separators); | |
| 734 | |
| 735 ui::MenuModel* menu_model = test_api_->menu_model(); | |
| 736 | |
| 737 EXPECT_EQ(TestComboboxModel::kItemCount, menu_model->GetItemCount()); | |
| 738 EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, | |
| 739 menu_model->GetTypeAt(kSeparatorIndex)); | |
| 740 | |
| 741 #if defined(OS_MACOSX) | |
| 742 // Comboboxes on Mac should have checkmarks, with the selected item checked, | |
| 743 EXPECT_EQ(ui::MenuModel::TYPE_CHECK, menu_model->GetTypeAt(0)); | |
| 744 EXPECT_EQ(ui::MenuModel::TYPE_CHECK, menu_model->GetTypeAt(1)); | |
| 745 EXPECT_TRUE(menu_model->IsItemCheckedAt(0)); | |
| 746 EXPECT_FALSE(menu_model->IsItemCheckedAt(1)); | |
| 747 | |
| 748 combobox_->SetSelectedIndex(1); | |
| 749 EXPECT_FALSE(menu_model->IsItemCheckedAt(0)); | |
| 750 EXPECT_TRUE(menu_model->IsItemCheckedAt(1)); | |
| 751 #else | |
| 752 EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu_model->GetTypeAt(0)); | |
| 753 EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu_model->GetTypeAt(1)); | |
| 754 #endif | |
| 755 | |
| 756 EXPECT_EQ(ASCIIToUTF16("PEANUT BUTTER"), menu_model->GetLabelAt(0)); | |
| 757 EXPECT_EQ(ASCIIToUTF16("JELLY"), menu_model->GetLabelAt(1)); | |
| 758 | |
| 759 // Check that with STYLE_ACTION, the first item (only) is not shown. | |
| 760 EXPECT_TRUE(menu_model->IsVisibleAt(0)); | |
| 761 combobox_->SetStyle(Combobox::STYLE_ACTION); | |
| 762 EXPECT_FALSE(menu_model->IsVisibleAt(0)); | |
| 763 EXPECT_TRUE(menu_model->IsVisibleAt(1)); | |
| 764 } | |
| 765 | |
| 695 } // namespace views | 766 } // namespace views |
| OLD | NEW |