| 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   } | 
| 130 | 153 | 
| 131   bool deleted() const { return deleted_; } | 154   bool deleted() const { return deleted_; } | 
| 132 | 155 | 
| 133  private: | 156  private: | 
| 134   bool deleted_; | 157   bool deleted_; | 
| 135 | 158 | 
| 136   DISALLOW_COPY_AND_ASSIGN(EvilListener); | 159   DISALLOW_COPY_AND_ASSIGN(EvilListener); | 
| 137 }; | 160 }; | 
| 138 | 161 | 
| 139 class TestComboboxListener : public views::ComboboxListener { | 162 class TestComboboxListener : public views::ComboboxListener { | 
| 140  public: | 163  public: | 
| 141   TestComboboxListener() | 164   TestComboboxListener() | 
| 142       : on_selected_index_changed_called_(false), | 165       : on_selected_index_changed_called_(false), | 
| 143         on_combobox_text_button_clicked_called_(false) { | 166         on_combobox_text_button_clicked_called_(false), | 
|  | 167         last_selected_index_(-1) { | 
| 144   } | 168   } | 
| 145   virtual ~TestComboboxListener() {} | 169   virtual ~TestComboboxListener() {} | 
| 146 | 170 | 
| 147   virtual void OnSelectedIndexChanged(views::Combobox* combobox) OVERRIDE { | 171   virtual void OnSelectedIndexChanged(views::Combobox* combobox) OVERRIDE { | 
| 148     on_selected_index_changed_called_ = true; | 172     on_selected_index_changed_called_ = true; | 
|  | 173     last_selected_index_ = combobox->selected_index(); | 
| 149   } | 174   } | 
| 150 | 175 | 
| 151   virtual void OnComboboxTextButtonClicked(views::Combobox* combobox) OVERRIDE { | 176   virtual void OnComboboxTextButtonClicked(views::Combobox* combobox) OVERRIDE { | 
| 152     on_combobox_text_button_clicked_called_ = true; | 177     on_combobox_text_button_clicked_called_ = true; | 
|  | 178     last_selected_index_ = combobox->selected_index(); | 
| 153   } | 179   } | 
| 154 | 180 | 
| 155   bool on_selected_index_changed_called() const { | 181   bool on_selected_index_changed_called() const { | 
| 156     return on_selected_index_changed_called_; | 182     return on_selected_index_changed_called_; | 
| 157   } | 183   } | 
| 158 | 184 | 
| 159   bool on_combobox_text_button_clicked_called() const { | 185   bool on_combobox_text_button_clicked_called() const { | 
| 160     return on_combobox_text_button_clicked_called_; | 186     return on_combobox_text_button_clicked_called_; | 
| 161   } | 187   } | 
| 162 | 188 | 
|  | 189   int last_selected_index() const { | 
|  | 190     return last_selected_index_; | 
|  | 191   } | 
|  | 192 | 
| 163  private: | 193  private: | 
| 164   bool on_selected_index_changed_called_; | 194   bool on_selected_index_changed_called_; | 
| 165   bool on_combobox_text_button_clicked_called_; | 195   bool on_combobox_text_button_clicked_called_; | 
|  | 196   int last_selected_index_; | 
| 166 | 197 | 
| 167  private: | 198  private: | 
| 168   DISALLOW_COPY_AND_ASSIGN(TestComboboxListener); | 199   DISALLOW_COPY_AND_ASSIGN(TestComboboxListener); | 
| 169 }; | 200 }; | 
| 170 | 201 | 
| 171 }  // namespace | 202 }  // namespace | 
| 172 | 203 | 
| 173 class ComboboxTest : public ViewsTestBase { | 204 class ComboboxTest : public ViewsTestBase { | 
| 174  public: | 205  public: | 
| 175   ComboboxTest() : widget_(NULL), combobox_(NULL), input_method_(NULL) {} | 206   ComboboxTest() : widget_(NULL), combobox_(NULL), input_method_(NULL) {} | 
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 475 | 506 | 
| 476   TestComboboxListener listener; | 507   TestComboboxListener listener; | 
| 477   combobox_->set_listener(&listener); | 508   combobox_->set_listener(&listener); | 
| 478 | 509 | 
| 479   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 510   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 
| 480   SendKeyEvent(ui::VKEY_RETURN); | 511   SendKeyEvent(ui::VKEY_RETURN); | 
| 481   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 512   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 482 | 513 | 
| 483   // With STYLE_NOTIFY_ON_CLICK, the click event is notified. | 514   // With STYLE_NOTIFY_ON_CLICK, the click event is notified. | 
| 484   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 515   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 
|  | 516   combobox_->SetSelectedIndex(1); | 
| 485   SendKeyEvent(ui::VKEY_RETURN); | 517   SendKeyEvent(ui::VKEY_RETURN); | 
| 486   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 518   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 
|  | 519   // The selected index is always 0 when pressing a key. | 
|  | 520   EXPECT_EQ(0, listener.last_selected_index()); | 
| 487 } | 521 } | 
| 488 | 522 | 
| 489 TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) { | 523 TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) { | 
| 490   InitCombobox(); | 524   InitCombobox(); | 
| 491 | 525 | 
| 492   TestComboboxListener listener; | 526   TestComboboxListener listener; | 
| 493   combobox_->set_listener(&listener); | 527   combobox_->set_listener(&listener); | 
| 494 | 528 | 
| 495   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 529   // With STYLE_SHOW_DROP_DOWN_ON_CLICK, the click event is ignored. | 
| 496   SendKeyEvent(ui::VKEY_SPACE); | 530   SendKeyEvent(ui::VKEY_SPACE); | 
| 497   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 531   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 498   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 532   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 
| 499   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 533   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 500 | 534 | 
| 501   // With STYLE_NOTIFY_ON_CLICK, the click event is notified after releasing. | 535   // With STYLE_NOTIFY_ON_CLICK, the click event is notified after releasing. | 
| 502   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 536   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 
|  | 537   combobox_->SetSelectedIndex(1); | 
| 503   SendKeyEvent(ui::VKEY_SPACE); | 538   SendKeyEvent(ui::VKEY_SPACE); | 
| 504   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 539   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 505   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 540   SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED); | 
| 506   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 541   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 
|  | 542   // The selected index is always 0 when pressing a key. | 
|  | 543   EXPECT_EQ(0, listener.last_selected_index()); | 
| 507 } | 544 } | 
| 508 | 545 | 
| 509 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { | 546 TEST_F(ComboboxTest, NotifyOnClickWithMouse) { | 
| 510   InitCombobox(); | 547   InitCombobox(); | 
| 511 | 548 | 
| 512   TestComboboxListener listener; | 549   TestComboboxListener listener; | 
| 513   combobox_->set_listener(&listener); | 550   combobox_->set_listener(&listener); | 
| 514 | 551 | 
| 515   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 552   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 
|  | 553   combobox_->SetSelectedIndex(1); | 
| 516   combobox_->Layout(); | 554   combobox_->Layout(); | 
| 517 | 555 | 
| 518   // Click the right side (arrow button). The menu is shown. | 556   // Click the right side (arrow button). The menu is shown. | 
| 519   TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 557   TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler(); | 
| 520   scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | 558   scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler); | 
| 521   scoped_ptr<test::MenuRunnerTestAPI> test_api( | 559   scoped_ptr<test::MenuRunnerTestAPI> test_api( | 
| 522       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 560       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 
| 523   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 561   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 
| 524 | 562 | 
| 525   PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, | 563   PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1, | 
| 526                           combobox_->y() + combobox_->height() / 2)); | 564                           combobox_->y() + combobox_->height() / 2)); | 
| 527   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 565   EXPECT_FALSE(listener.on_combobox_text_button_clicked_called()); | 
| 528   EXPECT_TRUE(test_menu_runner_handler->executed()); | 566   EXPECT_TRUE(test_menu_runner_handler->executed()); | 
| 529 | 567 | 
| 530   // Click the left side (text button). The click event is notified. | 568   // Click the left side (text button). The click event is notified. | 
| 531   test_menu_runner_handler = new TestMenuRunnerHandler(); | 569   test_menu_runner_handler = new TestMenuRunnerHandler(); | 
| 532   menu_runner_handler.reset(test_menu_runner_handler); | 570   menu_runner_handler.reset(test_menu_runner_handler); | 
| 533   test_api.reset( | 571   test_api.reset( | 
| 534       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 572       new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get())); | 
| 535   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 573   test_api->SetMenuRunnerHandler(menu_runner_handler.Pass()); | 
| 536   PerformClick(gfx::Point(combobox_->x() + 1, | 574   PerformClick(gfx::Point(combobox_->x() + 1, | 
| 537                           combobox_->y() + combobox_->height() / 2)); | 575                           combobox_->y() + combobox_->height() / 2)); | 
| 538   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 576   EXPECT_TRUE(listener.on_combobox_text_button_clicked_called()); | 
| 539   EXPECT_FALSE(test_menu_runner_handler->executed()); | 577   EXPECT_FALSE(test_menu_runner_handler->executed()); | 
|  | 578   // The selected index is always 0 when clicking. | 
|  | 579   EXPECT_EQ(0, listener.last_selected_index()); | 
| 540 } | 580 } | 
| 541 | 581 | 
| 542 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { | 582 TEST_F(ComboboxTest, ConsumingPressKeyEvents) { | 
| 543   InitCombobox(); | 583   InitCombobox(); | 
| 544 | 584 | 
| 545   EXPECT_FALSE(combobox_->OnKeyPressed( | 585   EXPECT_FALSE(combobox_->OnKeyPressed( | 
| 546       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 586       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 
| 547   EXPECT_FALSE(combobox_->OnKeyPressed( | 587   EXPECT_FALSE(combobox_->OnKeyPressed( | 
| 548       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 588       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 
| 549 | 589 | 
| 550   // When the combobox's style is STYLE_NOTIFY_ON_CLICK, pressing events of | 590   // When the combobox's style is STYLE_NOTIFY_ON_CLICK, pressing events of | 
| 551   // a space key or an enter key will be consumed. | 591   // a space key or an enter key will be consumed. | 
| 552   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 592   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 
| 553   EXPECT_TRUE(combobox_->OnKeyPressed( | 593   EXPECT_TRUE(combobox_->OnKeyPressed( | 
| 554       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 594       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0, false))); | 
| 555   EXPECT_TRUE(combobox_->OnKeyPressed( | 595   EXPECT_TRUE(combobox_->OnKeyPressed( | 
| 556       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 596       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, 0, false))); | 
| 557 } | 597 } | 
| 558 | 598 | 
|  | 599 TEST_F(ComboboxTest, ContentWidth) { | 
|  | 600   std::vector<std::string> values; | 
|  | 601 | 
|  | 602   scoped_ptr<VectorComboboxModel> model(new VectorComboboxModel(&values)); | 
|  | 603   combobox_ = new TestCombobox(model.get()); | 
|  | 604 | 
|  | 605   std::string long_item = "this is the long item"; | 
|  | 606   std::string short_item = "s"; | 
|  | 607 | 
|  | 608   values.resize(1); | 
|  | 609   values[0] = long_item; | 
|  | 610   combobox_->ModelChanged(); | 
|  | 611 | 
|  | 612   const int long_item_width = combobox_->content_size_.width(); | 
|  | 613 | 
|  | 614   values[0] = short_item; | 
|  | 615   combobox_->ModelChanged(); | 
|  | 616 | 
|  | 617   const int short_item_width = combobox_->content_size_.width(); | 
|  | 618 | 
|  | 619   values.resize(2); | 
|  | 620   values[0] = short_item; | 
|  | 621   values[1] = long_item; | 
|  | 622   combobox_->ModelChanged(); | 
|  | 623 | 
|  | 624   // When the style is STYLE_SHOW_DROP_DOWN_ON_CLICK, the width will fit with | 
|  | 625   // the longest item. | 
|  | 626   combobox_->SetStyle(Combobox::STYLE_SHOW_DROP_DOWN_ON_CLICK); | 
|  | 627   EXPECT_EQ(long_item_width, combobox_->content_size_.width()); | 
|  | 628 | 
|  | 629   // When the style is STYLE_NOTIFY_ON_CLICK, the width will fit with the first | 
|  | 630   // items' width. | 
|  | 631   combobox_->SetStyle(Combobox::STYLE_NOTIFY_ON_CLICK); | 
|  | 632   EXPECT_EQ(short_item_width, combobox_->content_size_.width()); | 
|  | 633 } | 
|  | 634 | 
| 559 }  // namespace views | 635 }  // namespace views | 
| OLD | NEW | 
|---|