| 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" | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 110   void SetSeparators(const std::set<int>& separators) { | 110   void SetSeparators(const std::set<int>& separators) { | 
| 111     separators_ = separators; | 111     separators_ = separators; | 
| 112   } | 112   } | 
| 113 | 113 | 
| 114  private: | 114  private: | 
| 115   std::set<int> separators_; | 115   std::set<int> separators_; | 
| 116 | 116 | 
| 117   DISALLOW_COPY_AND_ASSIGN(TestComboboxModel); | 117   DISALLOW_COPY_AND_ASSIGN(TestComboboxModel); | 
| 118 }; | 118 }; | 
| 119 | 119 | 
|  | 120 // A combobox model which refers to a vector. | 
|  | 121 class VectorComboboxModel : public ui::ComboboxModel { | 
|  | 122  public: | 
|  | 123   VectorComboboxModel(std::vector<std::string>* values) | 
|  | 124       : values_(values) { | 
|  | 125   } | 
|  | 126   virtual ~VectorComboboxModel() {} | 
|  | 127 | 
|  | 128   // ui::ComboboxModel: | 
|  | 129   virtual int GetItemCount() const OVERRIDE { | 
|  | 130     return values_->size(); | 
|  | 131   } | 
|  | 132   virtual base::string16 GetItemAt(int index) OVERRIDE { | 
|  | 133     return ASCIIToUTF16(values_->at(index)); | 
|  | 134   } | 
|  | 135   virtual bool IsItemSeparatorAt(int index) OVERRIDE { | 
|  | 136     return false; | 
|  | 137   } | 
|  | 138 | 
|  | 139  private: | 
|  | 140   std::vector<std::string>* values_; | 
|  | 141 }; | 
|  | 142 | 
| 120 class EvilListener : public ComboboxListener { | 143 class EvilListener : public ComboboxListener { | 
| 121  public: | 144  public: | 
| 122   EvilListener() : deleted_(false) {}; | 145   EvilListener() : deleted_(false) {}; | 
| 123   virtual ~EvilListener() {}; | 146   virtual ~EvilListener() {}; | 
| 124 | 147 | 
| 125   // ComboboxListener: | 148   // ComboboxListener: | 
| 126   virtual void OnSelectedIndexChanged(Combobox* combobox) OVERRIDE { | 149   virtual void OnSelectedIndexChanged(Combobox* combobox) OVERRIDE { | 
| 127     delete combobox; | 150     delete combobox; | 
| 128     deleted_ = true; | 151     deleted_ = true; | 
| 129   } | 152   } | 
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 432 // Verifies selecting the first matching value (and returning whether found). | 455 // Verifies selecting the first matching value (and returning whether found). | 
| 433 TEST_F(ComboboxTest, SelectValue) { | 456 TEST_F(ComboboxTest, SelectValue) { | 
| 434   InitCombobox(); | 457   InitCombobox(); | 
| 435   ASSERT_EQ(model_->GetDefaultIndex(), combobox_->selected_index()); | 458   ASSERT_EQ(model_->GetDefaultIndex(), combobox_->selected_index()); | 
| 436   EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER"))); | 459   EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER"))); | 
| 437   EXPECT_EQ(0, combobox_->selected_index()); | 460   EXPECT_EQ(0, combobox_->selected_index()); | 
| 438   EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("JELLY"))); | 461   EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("JELLY"))); | 
| 439   EXPECT_EQ(1, combobox_->selected_index()); | 462   EXPECT_EQ(1, combobox_->selected_index()); | 
| 440   EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS"))); | 463   EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS"))); | 
| 441   EXPECT_EQ(1, combobox_->selected_index()); | 464   EXPECT_EQ(1, combobox_->selected_index()); | 
|  | 465 | 
|  | 466   // With the action style, the selected index is always 0. | 
|  | 467   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
|  | 468   EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER"))); | 
|  | 469   EXPECT_EQ(0, combobox_->selected_index()); | 
|  | 470   EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("JELLY"))); | 
|  | 471   EXPECT_EQ(0, combobox_->selected_index()); | 
|  | 472   EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS"))); | 
|  | 473   EXPECT_EQ(0, combobox_->selected_index()); | 
|  | 474 } | 
|  | 475 | 
|  | 476 TEST_F(ComboboxTest, SelectIndexActionStyle) { | 
|  | 477   InitCombobox(); | 
|  | 478 | 
|  | 479   // With the action style, the selected index is always 0. | 
|  | 480   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
|  | 481   combobox_->SetSelectedIndex(1); | 
|  | 482   EXPECT_EQ(0, combobox_->selected_index()); | 
|  | 483   combobox_->SetSelectedIndex(2); | 
|  | 484   EXPECT_EQ(0, combobox_->selected_index()); | 
|  | 485   combobox_->SetSelectedIndex(3); | 
|  | 486   EXPECT_EQ(0, combobox_->selected_index()); | 
| 442 } | 487 } | 
| 443 | 488 | 
| 444 TEST_F(ComboboxTest, ListenerHandlesDelete) { | 489 TEST_F(ComboboxTest, ListenerHandlesDelete) { | 
| 445   TestComboboxModel model; | 490   TestComboboxModel model; | 
| 446   TestCombobox* combobox = new TestCombobox(&model);  // Deleted on change. | 491   TestCombobox* combobox = new TestCombobox(&model);  // Deleted on change. | 
| 447   EvilListener evil_listener; | 492   EvilListener evil_listener; | 
| 448   combobox->set_listener(&evil_listener); | 493   combobox->set_listener(&evil_listener); | 
| 449   ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2)); | 494   ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2)); | 
| 450   EXPECT_TRUE(evil_listener.deleted()); | 495   EXPECT_TRUE(evil_listener.deleted()); | 
| 451 } | 496 } | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 469   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 514   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 470   EXPECT_TRUE(test_menu_runner_handler->executed()); | 515   EXPECT_TRUE(test_menu_runner_handler->executed()); | 
| 471 } | 516 } | 
| 472 | 517 | 
| 473 TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) { | 518 TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) { | 
| 474   InitCombobox(); | 519   InitCombobox(); | 
| 475 | 520 | 
| 476   TestComboboxListener listener; | 521   TestComboboxListener listener; | 
| 477   combobox_->set_listener(&listener); | 522   combobox_->set_listener(&listener); | 
| 478 | 523 | 
| 479   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 524   // With STYLE_NORMAL, the click event is ignored. | 
| 480   SendKeyEvent(ui::VKEY_RETURN); | 525   SendKeyEvent(ui::VKEY_RETURN); | 
| 481   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 526   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 482 | 527 | 
| 483   // With STYLE_NOTIFY_ON_CLICK, the click event is notified. | 528   // With STYLE_ACTION, the click event is notified. | 
| 484   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 529   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
| 485   SendKeyEvent(ui::VKEY_RETURN); | 530   SendKeyEvent(ui::VKEY_RETURN); | 
| 486   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 531   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 
| 487 } | 532 } | 
| 488 | 533 | 
| 489 TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) { | 534 TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) { | 
| 490   InitCombobox(); | 535   InitCombobox(); | 
| 491 | 536 | 
| 492   TestComboboxListener listener; | 537   TestComboboxListener listener; | 
| 493   combobox_->set_listener(&listener); | 538   combobox_->set_listener(&listener); | 
| 494 | 539 | 
| 495   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 540   // With STYLE_NORMAL, the click event is ignored. | 
| 496   SendKeyEvent(ui::VKEY_SPACE); | 541   SendKeyEvent(ui::VKEY_SPACE); | 
| 497   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 542   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 498   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 543   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 
| 499   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 544   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 500 | 545 | 
| 501   // With STYLE_NOTIFY_ON_CLICK, the click event is notified after releasing. | 546   // With STYLE_ACTION, the click event is notified after releasing. | 
| 502   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 547   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
| 503   SendKeyEvent(ui::VKEY_SPACE); | 548   SendKeyEvent(ui::VKEY_SPACE); | 
| 504   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 549   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 505   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 550   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 
| 506   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 551   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 
| 507 } | 552 } | 
| 508 | 553 | 
| 509 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { | 554 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { | 
| 510   InitCombobox(); | 555   InitCombobox(); | 
| 511 | 556 | 
| 512   TestComboboxListener listener; | 557   TestComboboxListener listener; | 
| 513   combobox_->set_listener(&listener); | 558   combobox_->set_listener(&listener); | 
| 514 | 559 | 
| 515   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 560   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
| 516   combobox_->Layout(); | 561   combobox_->Layout(); | 
| 517 | 562 | 
| 518   // Click the right side (arrow button). The menu is shown. | 563   // Click the right side (arrow button). The menu is shown. | 
| 519   TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 564   TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 
| 520   scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | 565   scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | 
| 521   scoped_ptr<test::MenuRunnerTestAPI> test_api( | 566   scoped_ptr<test::MenuRunnerTestAPI> test_api( | 
| 522       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 567       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 
| 523   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 568   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 
| 524 | 569 | 
| 525   PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, | 570   PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 540 } | 585 } | 
| 541 | 586 | 
| 542 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { | 587 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { | 
| 543   InitCombobox(); | 588   InitCombobox(); | 
| 544 | 589 | 
| 545   EXPECT_FALSE(combobox_->OnKeyPressed( | 590   EXPECT_FALSE(combobox_->OnKeyPressed( | 
| 546       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 591       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 
| 547   EXPECT_FALSE(combobox_->OnKeyPressed( | 592   EXPECT_FALSE(combobox_->OnKeyPressed( | 
| 548       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 593       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 
| 549 | 594 | 
| 550   // When the combobox's style is STYLE_NOTIFY_ON_CLICK, pressing events of | 595   // When the combobox's style is STYLE_ACTION, pressing events of a space key | 
| 551   // a space key or an enter key will be consumed. | 596   // or an enter key will be consumed. | 
| 552   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 597   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
| 553   EXPECT_TRUE(combobox_->OnKeyPressed( | 598   EXPECT_TRUE(combobox_->OnKeyPressed( | 
| 554       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 599       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 
| 555   EXPECT_TRUE(combobox_->OnKeyPressed( | 600   EXPECT_TRUE(combobox_->OnKeyPressed( | 
| 556       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 601       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 
| 557 } | 602 } | 
| 558 | 603 | 
|  | 604 TEST_F(ComboboxTest, ContentWidth) { | 
|  | 605   std::vector<std::string> values; | 
|  | 606 | 
|  | 607   scoped_ptr<VectorComboboxModel> model(new VectorComboboxModel(&values)); | 
|  | 608   combobox_ = new TestCombobox(model.get()); | 
|  | 609 | 
|  | 610   std::string long_item = "this is the long item"; | 
|  | 611   std::string short_item = "s"; | 
|  | 612 | 
|  | 613   values.resize(1); | 
|  | 614   values[0] = long_item; | 
|  | 615   combobox_->ModelChanged(); | 
|  | 616 | 
|  | 617   const int long_item_width = combobox_->content_size_.width(); | 
|  | 618 | 
|  | 619   values[0] = short_item; | 
|  | 620   combobox_->ModelChanged(); | 
|  | 621 | 
|  | 622   const int short_item_width = combobox_->content_size_.width(); | 
|  | 623 | 
|  | 624   values.resize(2); | 
|  | 625   values[0] = short_item; | 
|  | 626   values[1] = long_item; | 
|  | 627   combobox_->ModelChanged(); | 
|  | 628 | 
|  | 629   // When the style is STYLE_NORMAL, the width will fit with the longest item. | 
|  | 630   combobox_->SetStyle(Combobox::STYLE_NORMAL); | 
|  | 631   EXPECT_EQ(long_item_width, combobox_->content_size_.width()); | 
|  | 632 | 
|  | 633   // When the style is STYLE_ACTION, the width will fit with the first items' | 
|  | 634   // width. | 
|  | 635   combobox_->SetStyle(Combobox::STYLE_ACTION); | 
|  | 636   EXPECT_EQ(short_item_width, combobox_->content_size_.width()); | 
|  | 637 } | 
|  | 638 | 
| 559 }  // namespace views | 639 }  // namespace views | 
| OLD | NEW | 
|---|