| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/menu/menu_controller.h" | 5 #include "ui/views/controls/menu/menu_controller.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 400 |
| 401 void SetIsCombobox(bool is_combobox) { | 401 void SetIsCombobox(bool is_combobox) { |
| 402 menu_controller_->set_is_combobox(is_combobox); | 402 menu_controller_->set_is_combobox(is_combobox); |
| 403 } | 403 } |
| 404 | 404 |
| 405 void SetSelectionOnPointerDown(SubmenuView* source, | 405 void SetSelectionOnPointerDown(SubmenuView* source, |
| 406 const ui::LocatedEvent* event) { | 406 const ui::LocatedEvent* event) { |
| 407 menu_controller_->SetSelectionOnPointerDown(source, event); | 407 menu_controller_->SetSelectionOnPointerDown(source, event); |
| 408 } | 408 } |
| 409 | 409 |
| 410 void ProcessMouseMoved(SubmenuView* source, |
| 411 const ui::MouseEvent& event) { |
| 412 menu_controller_->OnMouseMoved(source, event); |
| 413 } |
| 414 |
| 410 void RunMenu() { | 415 void RunMenu() { |
| 411 #if defined(USE_AURA) | 416 #if defined(USE_AURA) |
| 412 scoped_ptr<MenuKeyEventHandler> key_event_handler(new MenuKeyEventHandler); | 417 scoped_ptr<MenuKeyEventHandler> key_event_handler(new MenuKeyEventHandler); |
| 413 #endif | 418 #endif |
| 414 | 419 |
| 415 menu_controller_->message_loop_depth_++; | 420 menu_controller_->message_loop_depth_++; |
| 416 menu_controller_->RunMessageLoop(false); | 421 menu_controller_->RunMessageLoop(false); |
| 417 menu_controller_->message_loop_depth_--; | 422 menu_controller_->message_loop_depth_--; |
| 418 } | 423 } |
| 419 | 424 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 434 return menu_controller_delegate_.get(); | 439 return menu_controller_delegate_.get(); |
| 435 } | 440 } |
| 436 MenuController* menu_controller() { return menu_controller_; } | 441 MenuController* menu_controller() { return menu_controller_; } |
| 437 const MenuItemView* pending_state_item() const { | 442 const MenuItemView* pending_state_item() const { |
| 438 return menu_controller_->pending_state_.item; | 443 return menu_controller_->pending_state_.item; |
| 439 } | 444 } |
| 440 MenuController::ExitType menu_exit_type() const { | 445 MenuController::ExitType menu_exit_type() const { |
| 441 return menu_controller_->exit_type_; | 446 return menu_controller_->exit_type_; |
| 442 } | 447 } |
| 443 | 448 |
| 449 void AddButtonMenuItems() { |
| 450 menu_item()->SetBounds(0, 0, 200, 300); |
| 451 MenuItemView* item_view = |
| 452 menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five")); |
| 453 for (int i = 0; i < 3; ++i) { |
| 454 LabelButton* button = |
| 455 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); |
| 456 button->SetFocusable(true); |
| 457 item_view->AddChildView(button); |
| 458 } |
| 459 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); |
| 460 } |
| 461 |
| 444 private: | 462 private: |
| 445 void DestroyMenuController() { | 463 void DestroyMenuController() { |
| 446 if (!menu_controller_) | 464 if (!menu_controller_) |
| 447 return; | 465 return; |
| 448 | 466 |
| 449 if (!owner_->IsClosed()) | 467 if (!owner_->IsClosed()) |
| 450 owner_->RemoveObserver(menu_controller_); | 468 owner_->RemoveObserver(menu_controller_); |
| 451 | 469 |
| 452 menu_controller_->showing_ = false; | 470 menu_controller_->showing_ = false; |
| 453 menu_controller_->owner_ = nullptr; | 471 menu_controller_->owner_ = nullptr; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 EXPECT_EQ(0, pending_state_item()->GetCommand()); | 713 EXPECT_EQ(0, pending_state_item()->GetCommand()); |
| 696 | 714 |
| 697 // Handle searching for 'f'; should find "Four". | 715 // Handle searching for 'f'; should find "Four". |
| 698 SelectByChar('f'); | 716 SelectByChar('f'); |
| 699 EXPECT_EQ(4, pending_state_item()->GetCommand()); | 717 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 700 | 718 |
| 701 // Clear references in menu controller to the menu item that is going away. | 719 // Clear references in menu controller to the menu item that is going away. |
| 702 ResetSelection(); | 720 ResetSelection(); |
| 703 } | 721 } |
| 704 | 722 |
| 723 TEST_F(MenuControllerTest, SelectChildButtonView) { |
| 724 AddButtonMenuItems(); |
| 725 View* buttons_view = menu_item()->GetSubmenu()->child_at(4); |
| 726 ASSERT_NE(nullptr, buttons_view); |
| 727 CustomButton* button1 = |
| 728 CustomButton::AsCustomButton(buttons_view->child_at(0)); |
| 729 ASSERT_NE(nullptr, button1); |
| 730 CustomButton* button2 = |
| 731 CustomButton::AsCustomButton(buttons_view->child_at(1)); |
| 732 ASSERT_NE(nullptr, button2); |
| 733 CustomButton* button3 = |
| 734 CustomButton::AsCustomButton(buttons_view->child_at(2)); |
| 735 ASSERT_NE(nullptr, button2); |
| 736 |
| 737 // Handle searching for 'f'; should find "Four". |
| 738 SelectByChar('f'); |
| 739 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 740 |
| 741 EXPECT_FALSE(button1->IsHotTracked()); |
| 742 EXPECT_FALSE(button2->IsHotTracked()); |
| 743 EXPECT_FALSE(button3->IsHotTracked()); |
| 744 |
| 745 // Move selection to |button1|. |
| 746 IncrementSelection(); |
| 747 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 748 EXPECT_TRUE(button1->IsHotTracked()); |
| 749 EXPECT_FALSE(button2->IsHotTracked()); |
| 750 EXPECT_FALSE(button3->IsHotTracked()); |
| 751 |
| 752 // Move selection to |button2|. |
| 753 IncrementSelection(); |
| 754 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 755 EXPECT_FALSE(button1->IsHotTracked()); |
| 756 EXPECT_TRUE(button2->IsHotTracked()); |
| 757 EXPECT_FALSE(button3->IsHotTracked()); |
| 758 |
| 759 // Move selection to |button3|. |
| 760 IncrementSelection(); |
| 761 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 762 EXPECT_FALSE(button1->IsHotTracked()); |
| 763 EXPECT_FALSE(button2->IsHotTracked()); |
| 764 EXPECT_TRUE(button3->IsHotTracked()); |
| 765 |
| 766 // Move a mouse to hot track the |button1|. |
| 767 gfx::Point location(button1->GetBoundsInScreen().CenterPoint()); |
| 768 ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location, |
| 769 ui::EventTimeForNow(), 0, 0); |
| 770 SubmenuView* sub_menu = menu_item()->GetSubmenu(); |
| 771 ProcessMouseMoved(sub_menu, event); |
| 772 |
| 773 // Incrementing selection should move hot tracking to the second button (next |
| 774 // after the first button). |
| 775 IncrementSelection(); |
| 776 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 777 EXPECT_FALSE(button1->IsHotTracked()); |
| 778 EXPECT_TRUE(button2->IsHotTracked()); |
| 779 EXPECT_FALSE(button3->IsHotTracked()); |
| 780 |
| 781 // Increment selection twice to wrap around. |
| 782 IncrementSelection(); |
| 783 IncrementSelection(); |
| 784 EXPECT_EQ(1, pending_state_item()->GetCommand()); |
| 785 |
| 786 // Clear references in menu controller to the menu item that is going away. |
| 787 ResetSelection(); |
| 788 } |
| 789 |
| 790 TEST_F(MenuControllerTest, DeleteChildButtonView) { |
| 791 AddButtonMenuItems(); |
| 792 |
| 793 // Handle searching for 'f'; should find "Four". |
| 794 SelectByChar('f'); |
| 795 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 796 |
| 797 View* buttons_view = menu_item()->GetSubmenu()->child_at(4); |
| 798 ASSERT_NE(nullptr, buttons_view); |
| 799 CustomButton* button1 = |
| 800 CustomButton::AsCustomButton(buttons_view->child_at(0)); |
| 801 ASSERT_NE(nullptr, button1); |
| 802 CustomButton* button2 = |
| 803 CustomButton::AsCustomButton(buttons_view->child_at(1)); |
| 804 ASSERT_NE(nullptr, button2); |
| 805 CustomButton* button3 = |
| 806 CustomButton::AsCustomButton(buttons_view->child_at(2)); |
| 807 ASSERT_NE(nullptr, button2); |
| 808 EXPECT_FALSE(button1->IsHotTracked()); |
| 809 EXPECT_FALSE(button2->IsHotTracked()); |
| 810 EXPECT_FALSE(button3->IsHotTracked()); |
| 811 |
| 812 // Increment twice to move selection to |button2|. |
| 813 IncrementSelection(); |
| 814 IncrementSelection(); |
| 815 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 816 EXPECT_FALSE(button1->IsHotTracked()); |
| 817 EXPECT_TRUE(button2->IsHotTracked()); |
| 818 EXPECT_FALSE(button3->IsHotTracked()); |
| 819 |
| 820 // Delete |button2| while it is hot-tracked. |
| 821 // This should update MenuController via ViewHierarchyChanged and reset |
| 822 // |hot_button_|. |
| 823 delete button2; |
| 824 |
| 825 // Incrementing selection should now set hot-tracked item to |button1|. |
| 826 // It should not crash. |
| 827 IncrementSelection(); |
| 828 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 829 EXPECT_TRUE(button1->IsHotTracked()); |
| 830 EXPECT_FALSE(button3->IsHotTracked()); |
| 831 } |
| 832 |
| 705 // Tests that a menu opened asynchronously, will notify its | 833 // Tests that a menu opened asynchronously, will notify its |
| 706 // MenuControllerDelegate when Accept is called. | 834 // MenuControllerDelegate when Accept is called. |
| 707 TEST_F(MenuControllerTest, AsynchronousAccept) { | 835 TEST_F(MenuControllerTest, AsynchronousAccept) { |
| 708 MenuController* controller = menu_controller(); | 836 MenuController* controller = menu_controller(); |
| 709 controller->SetAsyncRun(true); | 837 controller->SetAsyncRun(true); |
| 710 | 838 |
| 711 int mouse_event_flags = 0; | 839 int mouse_event_flags = 0; |
| 712 MenuItemView* run_result = | 840 MenuItemView* run_result = |
| 713 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 841 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
| 714 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 842 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 // shutdown. This should not crash while attempting to repost the event. | 1119 // shutdown. This should not crash while attempting to repost the event. |
| 992 SetSelectionOnPointerDown(sub_menu, &event); | 1120 SetSelectionOnPointerDown(sub_menu, &event); |
| 993 | 1121 |
| 994 // Close to remove observers before test TearDown | 1122 // Close to remove observers before test TearDown |
| 995 sub_menu->Close(); | 1123 sub_menu->Close(); |
| 996 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1124 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 997 } | 1125 } |
| 998 | 1126 |
| 999 } // namespace test | 1127 } // namespace test |
| 1000 } // namespace views | 1128 } // namespace views |
| OLD | NEW |