| 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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five")); | 454 menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five")); |
| 455 for (int i = 0; i < 3; ++i) { | 455 for (int i = 0; i < 3; ++i) { |
| 456 LabelButton* button = | 456 LabelButton* button = |
| 457 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); | 457 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); |
| 458 button->SetFocusable(true); | 458 button->SetFocusable(true); |
| 459 item_view->AddChildView(button); | 459 item_view->AddChildView(button); |
| 460 } | 460 } |
| 461 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); | 461 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); |
| 462 } | 462 } |
| 463 | 463 |
| 464 CustomButton* GetHotButton() { |
| 465 return menu_controller_->hot_button_; |
| 466 } |
| 467 |
| 468 void SetHotTrackedButton(CustomButton* hot_button) { |
| 469 menu_controller_->SetHotTrackedButton(hot_button); |
| 470 } |
| 471 |
| 472 void ExitMenuRun() { |
| 473 menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST); |
| 474 menu_controller_->ExitMenuRun(); |
| 475 } |
| 476 |
| 464 private: | 477 private: |
| 465 void DestroyMenuController() { | 478 void DestroyMenuController() { |
| 466 if (!menu_controller_) | 479 if (!menu_controller_) |
| 467 return; | 480 return; |
| 468 | 481 |
| 469 if (!owner_->IsClosed()) | 482 if (!owner_->IsClosed()) |
| 470 owner_->RemoveObserver(menu_controller_); | 483 owner_->RemoveObserver(menu_controller_); |
| 471 | 484 |
| 472 menu_controller_->showing_ = false; | 485 menu_controller_->showing_ = false; |
| 473 menu_controller_->owner_ = nullptr; | 486 menu_controller_->owner_ = nullptr; |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 delete button2; | 839 delete button2; |
| 827 | 840 |
| 828 // Incrementing selection should now set hot-tracked item to |button1|. | 841 // Incrementing selection should now set hot-tracked item to |button1|. |
| 829 // It should not crash. | 842 // It should not crash. |
| 830 IncrementSelection(); | 843 IncrementSelection(); |
| 831 EXPECT_EQ(5, pending_state_item()->GetCommand()); | 844 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 832 EXPECT_TRUE(button1->IsHotTracked()); | 845 EXPECT_TRUE(button1->IsHotTracked()); |
| 833 EXPECT_FALSE(button3->IsHotTracked()); | 846 EXPECT_FALSE(button3->IsHotTracked()); |
| 834 } | 847 } |
| 835 | 848 |
| 849 // Creates a menu with CustomButton child views, simulates running a nested |
| 850 // menu and tests that existing the nested run restores hot-tracked child view. |
| 851 TEST_F(MenuControllerTest, ChildButtonHotTrackedWhenNested) { |
| 852 AddButtonMenuItems(); |
| 853 |
| 854 // Handle searching for 'f'; should find "Four". |
| 855 SelectByChar('f'); |
| 856 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 857 |
| 858 View* buttons_view = menu_item()->GetSubmenu()->child_at(4); |
| 859 ASSERT_NE(nullptr, buttons_view); |
| 860 CustomButton* button1 = |
| 861 CustomButton::AsCustomButton(buttons_view->child_at(0)); |
| 862 ASSERT_NE(nullptr, button1); |
| 863 CustomButton* button2 = |
| 864 CustomButton::AsCustomButton(buttons_view->child_at(1)); |
| 865 ASSERT_NE(nullptr, button2); |
| 866 CustomButton* button3 = |
| 867 CustomButton::AsCustomButton(buttons_view->child_at(2)); |
| 868 ASSERT_NE(nullptr, button2); |
| 869 EXPECT_FALSE(button1->IsHotTracked()); |
| 870 EXPECT_FALSE(button2->IsHotTracked()); |
| 871 EXPECT_FALSE(button3->IsHotTracked()); |
| 872 |
| 873 // Increment twice to move selection to |button2|. |
| 874 IncrementSelection(); |
| 875 IncrementSelection(); |
| 876 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
| 877 EXPECT_FALSE(button1->IsHotTracked()); |
| 878 EXPECT_TRUE(button2->IsHotTracked()); |
| 879 EXPECT_FALSE(button3->IsHotTracked()); |
| 880 EXPECT_EQ(button2, GetHotButton()); |
| 881 |
| 882 MenuController* controller = menu_controller(); |
| 883 controller->SetAsyncRun(true); |
| 884 int mouse_event_flags = 0; |
| 885 MenuItemView* run_result = |
| 886 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
| 887 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
| 888 EXPECT_EQ(run_result, nullptr); |
| 889 |
| 890 // |button2| should stay in hot-tracked state but menu controller should not |
| 891 // track it anymore (preventing resetting hot-tracked state when changing |
| 892 // selection while a nested run is active). |
| 893 EXPECT_TRUE(button2->IsHotTracked()); |
| 894 EXPECT_EQ(nullptr, GetHotButton()); |
| 895 |
| 896 // Setting hot-tracked button while nested should get reverted when nested |
| 897 // menu run ends. |
| 898 SetHotTrackedButton(button1); |
| 899 EXPECT_TRUE(button1->IsHotTracked()); |
| 900 EXPECT_EQ(button1, GetHotButton()); |
| 901 |
| 902 ExitMenuRun(); |
| 903 EXPECT_FALSE(button1->IsHotTracked()); |
| 904 EXPECT_TRUE(button2->IsHotTracked()); |
| 905 EXPECT_EQ(button2, GetHotButton()); |
| 906 } |
| 907 |
| 836 // Tests that a menu opened asynchronously, will notify its | 908 // Tests that a menu opened asynchronously, will notify its |
| 837 // MenuControllerDelegate when Accept is called. | 909 // MenuControllerDelegate when Accept is called. |
| 838 TEST_F(MenuControllerTest, AsynchronousAccept) { | 910 TEST_F(MenuControllerTest, AsynchronousAccept) { |
| 839 MenuController* controller = menu_controller(); | 911 MenuController* controller = menu_controller(); |
| 840 controller->SetAsyncRun(true); | 912 controller->SetAsyncRun(true); |
| 841 | 913 |
| 842 int mouse_event_flags = 0; | 914 int mouse_event_flags = 0; |
| 843 MenuItemView* run_result = | 915 MenuItemView* run_result = |
| 844 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 916 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
| 845 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 917 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1103 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 1032 } | 1104 } |
| 1033 | 1105 |
| 1034 // Tests that an asynchronous menu reposts touch events that occur outside of | 1106 // Tests that an asynchronous menu reposts touch events that occur outside of |
| 1035 // the bounds of the menu, and that the menu closes. | 1107 // the bounds of the menu, and that the menu closes. |
| 1036 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) { | 1108 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) { |
| 1037 MenuController* controller = menu_controller(); | 1109 MenuController* controller = menu_controller(); |
| 1038 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1110 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
| 1039 controller->SetAsyncRun(true); | 1111 controller->SetAsyncRun(true); |
| 1040 | 1112 |
| 1041 // Show a sub menu to targert with a touch event. However have the event occur | 1113 // Show a sub menu to target with a touch event. However have the event occur |
| 1042 // outside of the bounds of the entire menu. | 1114 // outside of the bounds of the entire menu. |
| 1043 MenuItemView* item = menu_item(); | 1115 MenuItemView* item = menu_item(); |
| 1044 SubmenuView* sub_menu = item->GetSubmenu(); | 1116 SubmenuView* sub_menu = item->GetSubmenu(); |
| 1045 sub_menu->ShowAt(owner(), item->bounds(), false); | 1117 sub_menu->ShowAt(owner(), item->bounds(), false); |
| 1046 gfx::Point location(sub_menu->bounds().bottom_right()); | 1118 gfx::Point location(sub_menu->bounds().bottom_right()); |
| 1047 location.Offset(1, 1); | 1119 location.Offset(1, 1); |
| 1048 ui::TouchEvent event(ui::ET_TOUCH_PRESSED, location, 0, 0, | 1120 ui::TouchEvent event(ui::ET_TOUCH_PRESSED, location, 0, 0, |
| 1049 ui::EventTimeForNow(), 0, 0, 0, 0); | 1121 ui::EventTimeForNow(), 0, 0, 0, 0); |
| 1050 controller->OnTouchEvent(sub_menu, &event); | 1122 controller->OnTouchEvent(sub_menu, &event); |
| 1051 | 1123 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 // shutdown. This should not crash while attempting to repost the event. | 1194 // shutdown. This should not crash while attempting to repost the event. |
| 1123 SetSelectionOnPointerDown(sub_menu, &event); | 1195 SetSelectionOnPointerDown(sub_menu, &event); |
| 1124 | 1196 |
| 1125 // Close to remove observers before test TearDown | 1197 // Close to remove observers before test TearDown |
| 1126 sub_menu->Close(); | 1198 sub_menu->Close(); |
| 1127 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1199 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 1128 } | 1200 } |
| 1129 | 1201 |
| 1130 } // namespace test | 1202 } // namespace test |
| 1131 } // namespace views | 1203 } // namespace views |
| OLD | NEW |