| 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/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "ui/aura/scoped_window_targeter.h" | 10 #include "ui/aura/scoped_window_targeter.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #undef Bool | 33 #undef Bool |
| 34 #undef None | 34 #undef None |
| 35 #include "ui/events/test/events_test_utils_x11.h" | 35 #include "ui/events/test/events_test_utils_x11.h" |
| 36 #endif | 36 #endif |
| 37 | 37 |
| 38 namespace views { | 38 namespace views { |
| 39 namespace test { | 39 namespace test { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 // Test implementation of MenuDelegate that only reports calls of OnPerformDrop. |
| 44 class TestMenuDelegate : public MenuDelegate { |
| 45 public: |
| 46 TestMenuDelegate(); |
| 47 ~TestMenuDelegate() override; |
| 48 |
| 49 bool on_perform_drop_called() { return on_perform_drop_called_; } |
| 50 |
| 51 int OnPerformDrop(MenuItemView* menu, |
| 52 DropPosition position, |
| 53 const ui::DropTargetEvent& event) override; |
| 54 |
| 55 private: |
| 56 bool on_perform_drop_called_; |
| 57 DISALLOW_COPY_AND_ASSIGN(TestMenuDelegate); |
| 58 }; |
| 59 |
| 60 TestMenuDelegate::TestMenuDelegate() : on_perform_drop_called_(false) {} |
| 61 |
| 62 TestMenuDelegate::~TestMenuDelegate() {} |
| 63 |
| 64 int TestMenuDelegate::OnPerformDrop(MenuItemView* menu, |
| 65 DropPosition position, |
| 66 const ui::DropTargetEvent& event) { |
| 67 on_perform_drop_called_ = true; |
| 68 return ui::DragDropTypes::DRAG_COPY; |
| 69 } |
| 70 |
| 43 // Test implementation of MenuControllerDelegate that only reports the values | 71 // Test implementation of MenuControllerDelegate that only reports the values |
| 44 // called of OnMenuClosed. | 72 // called of OnMenuClosed. |
| 45 class TestMenuControllerDelegate : public internal::MenuControllerDelegate { | 73 class TestMenuControllerDelegate : public internal::MenuControllerDelegate { |
| 46 public: | 74 public: |
| 47 TestMenuControllerDelegate(); | 75 TestMenuControllerDelegate(); |
| 48 ~TestMenuControllerDelegate() override {} | 76 ~TestMenuControllerDelegate() override {} |
| 49 | 77 |
| 50 int on_menu_closed_called() { return on_menu_closed_called_; } | 78 int on_menu_closed_called() { return on_menu_closed_called_; } |
| 51 | 79 |
| 52 NotifyType on_menu_closed_notify_type() { | 80 NotifyType on_menu_closed_notify_type() { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 return menu_controller_->FindNextSelectableMenuItem( | 364 return menu_controller_->FindNextSelectableMenuItem( |
| 337 parent, index, MenuController::INCREMENT_SELECTION_UP); | 365 parent, index, MenuController::INCREMENT_SELECTION_UP); |
| 338 } | 366 } |
| 339 | 367 |
| 340 internal::MenuControllerDelegate* GetCurrentDelegate() { | 368 internal::MenuControllerDelegate* GetCurrentDelegate() { |
| 341 return menu_controller_->delegate_; | 369 return menu_controller_->delegate_; |
| 342 } | 370 } |
| 343 | 371 |
| 344 bool IsAsyncRun() { return menu_controller_->async_run_; } | 372 bool IsAsyncRun() { return menu_controller_->async_run_; } |
| 345 | 373 |
| 374 bool IsShowing() { return menu_controller_->showing_; } |
| 375 |
| 346 void SelectByChar(base::char16 character) { | 376 void SelectByChar(base::char16 character) { |
| 347 menu_controller_->SelectByChar(character); | 377 menu_controller_->SelectByChar(character); |
| 348 } | 378 } |
| 349 | 379 |
| 380 void SetDropMenuItem(MenuItemView* target, |
| 381 MenuDelegate::DropPosition position) { |
| 382 menu_controller_->SetDropMenuItem(target, position); |
| 383 } |
| 384 |
| 350 void SetIsCombobox(bool is_combobox) { | 385 void SetIsCombobox(bool is_combobox) { |
| 351 menu_controller_->set_is_combobox(is_combobox); | 386 menu_controller_->set_is_combobox(is_combobox); |
| 352 } | 387 } |
| 353 | 388 |
| 354 void RunMenu() { | 389 void RunMenu() { |
| 355 menu_controller_->message_loop_depth_++; | 390 menu_controller_->message_loop_depth_++; |
| 356 menu_controller_->RunMessageLoop(false); | 391 menu_controller_->RunMessageLoop(false); |
| 357 menu_controller_->message_loop_depth_--; | 392 menu_controller_->message_loop_depth_--; |
| 358 } | 393 } |
| 359 | 394 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 aura::client::SetDispatcherClient(owner_->GetNativeView()->GetRootWindow(), | 431 aura::client::SetDispatcherClient(owner_->GetNativeView()->GetRootWindow(), |
| 397 dispatcher_client_.get()); | 432 dispatcher_client_.get()); |
| 398 #endif | 433 #endif |
| 399 | 434 |
| 400 SetupMenuItem(); | 435 SetupMenuItem(); |
| 401 | 436 |
| 402 SetupMenuController(); | 437 SetupMenuController(); |
| 403 } | 438 } |
| 404 | 439 |
| 405 void SetupMenuItem() { | 440 void SetupMenuItem() { |
| 406 menu_delegate_.reset(new MenuDelegate); | 441 menu_delegate_.reset(new TestMenuDelegate); |
| 407 menu_item_.reset(new TestMenuItemViewShown(menu_delegate_.get())); | 442 menu_item_.reset(new TestMenuItemViewShown(menu_delegate_.get())); |
| 408 menu_item_->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); | 443 menu_item_->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); |
| 409 menu_item_->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); | 444 menu_item_->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); |
| 410 menu_item_->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); | 445 menu_item_->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); |
| 411 menu_item_->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); | 446 menu_item_->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); |
| 412 } | 447 } |
| 413 | 448 |
| 414 void SetupMenuController() { | 449 void SetupMenuController() { |
| 415 menu_controller_delegate_.reset(new TestMenuControllerDelegate); | 450 menu_controller_delegate_.reset(new TestMenuControllerDelegate); |
| 416 menu_controller_ = | 451 menu_controller_ = |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 EXPECT_EQ(delegate, GetCurrentDelegate()); | 749 EXPECT_EQ(delegate, GetCurrentDelegate()); |
| 715 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 750 EXPECT_EQ(0, delegate->on_menu_closed_called()); |
| 716 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 751 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 717 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); | 752 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); |
| 718 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); | 753 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); |
| 719 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 754 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 720 nested_delegate->on_menu_closed_notify_type()); | 755 nested_delegate->on_menu_closed_notify_type()); |
| 721 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 756 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 722 } | 757 } |
| 723 | 758 |
| 759 // Tests that dropping within an asynchronous menu stops the menu from showing |
| 760 // and does not notify the controller. |
| 761 TEST_F(MenuControllerTest, AsynchronousPerformDrop) { |
| 762 MenuController* controller = menu_controller(); |
| 763 controller->SetAsyncRun(true); |
| 764 SubmenuView* source = menu_item()->GetSubmenu(); |
| 765 MenuItemView* target = source->GetMenuItemAt(0); |
| 766 |
| 767 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER); |
| 768 |
| 769 ui::OSExchangeData drop_data; |
| 770 gfx::Rect bounds(target->bounds()); |
| 771 gfx::Point location(bounds.x(), bounds.y()); |
| 772 ui::DropTargetEvent target_event(drop_data, location, location, |
| 773 ui::DragDropTypes::DRAG_MOVE); |
| 774 controller->OnPerformDrop(source, target_event); |
| 775 |
| 776 TestMenuDelegate* menu_delegate = |
| 777 static_cast<TestMenuDelegate*>(target->GetDelegate()); |
| 778 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
| 779 EXPECT_TRUE(menu_delegate->on_perform_drop_called()); |
| 780 EXPECT_FALSE(IsShowing()); |
| 781 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); |
| 782 } |
| 783 |
| 784 // Tests that dragging within an asynchronous menu notifies the |
| 785 // MenuControllerDelegate for shutdown. |
| 786 TEST_F(MenuControllerTest, AsynchronousDragComplete) { |
| 787 MenuController* controller = menu_controller(); |
| 788 controller->SetAsyncRun(true); |
| 789 |
| 790 controller->OnDragWillStart(); |
| 791 controller->OnDragComplete(true); |
| 792 |
| 793 EXPECT_FALSE(controller->drag_in_progress()); |
| 794 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
| 795 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
| 796 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
| 797 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 798 controller_delegate->on_menu_closed_notify_type()); |
| 799 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 800 } |
| 801 |
| 802 // Tets that an asynchronous menu nested within an asynchronous menu closes both |
| 803 // menus, and notifies both delegates. |
| 804 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { |
| 805 MenuController* controller = menu_controller(); |
| 806 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
| 807 scoped_ptr<TestMenuControllerDelegate> nested_delegate( |
| 808 new TestMenuControllerDelegate()); |
| 809 |
| 810 ASSERT_FALSE(IsAsyncRun()); |
| 811 // Sets the run created in SetUp |
| 812 controller->SetAsyncRun(true); |
| 813 |
| 814 // Nested run |
| 815 controller->AddNestedDelegate(nested_delegate.get()); |
| 816 controller->SetAsyncRun(true); |
| 817 int mouse_event_flags = 0; |
| 818 MenuItemView* run_result = |
| 819 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
| 820 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
| 821 EXPECT_EQ(run_result, nullptr); |
| 822 |
| 823 controller->CancelAll(); |
| 824 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
| 825 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 826 } |
| 827 |
| 724 // Tests that if you exit all menus when an asynchrnous menu is nested within a | 828 // Tests that if you exit all menus when an asynchrnous menu is nested within a |
| 725 // synchronous menu, the message loop for the parent menu finishes running. | 829 // synchronous menu, the message loop for the parent menu finishes running. |
| 726 TEST_F(MenuControllerTest, AsynchronousNestedExitAll) { | 830 TEST_F(MenuControllerTest, AsynchronousNestedExitAll) { |
| 727 InstallTestMenuMessageLoop(); | 831 InstallTestMenuMessageLoop(); |
| 728 | 832 |
| 729 base::MessageLoopForUI::current()->PostTask( | 833 base::MessageLoopForUI::current()->PostTask( |
| 730 FROM_HERE, base::Bind(&MenuControllerTest::TestAsynchronousNestedExitAll, | 834 FROM_HERE, base::Bind(&MenuControllerTest::TestAsynchronousNestedExitAll, |
| 731 base::Unretained(this))); | 835 base::Unretained(this))); |
| 732 | 836 |
| 733 RunMenu(); | 837 RunMenu(); |
| 734 } | 838 } |
| 735 | 839 |
| 736 // Tests that if you exit the nested menu when an asynchrnous menu is nested | 840 // Tests that if you exit the nested menu when an asynchrnous menu is nested |
| 737 // within a synchronous menu, the message loop for the parent menu remains | 841 // within a synchronous menu, the message loop for the parent menu remains |
| 738 // running. | 842 // running. |
| 739 TEST_F(MenuControllerTest, AsynchronousNestedExitOutermost) { | 843 TEST_F(MenuControllerTest, AsynchronousNestedExitOutermost) { |
| 740 InstallTestMenuMessageLoop(); | 844 InstallTestMenuMessageLoop(); |
| 741 | 845 |
| 742 base::MessageLoopForUI::current()->PostTask( | 846 base::MessageLoopForUI::current()->PostTask( |
| 743 FROM_HERE, | 847 FROM_HERE, |
| 744 base::Bind(&MenuControllerTest::TestAsynchronousNestedExitOutermost, | 848 base::Bind(&MenuControllerTest::TestAsynchronousNestedExitOutermost, |
| 745 base::Unretained(this))); | 849 base::Unretained(this))); |
| 746 | 850 |
| 747 RunMenu(); | 851 RunMenu(); |
| 748 } | 852 } |
| 749 | 853 |
| 750 } // namespace test | 854 } // namespace test |
| 751 } // namespace views | 855 } // namespace views |
| OLD | NEW |