| 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/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "ui/aura/scoped_window_targeter.h" | 8 #include "ui/aura/scoped_window_targeter.h" |
| 9 #include "ui/aura/window.h" | 9 #include "ui/aura/window.h" |
| 10 #include "ui/events/event_handler.h" | 10 #include "ui/events/event_handler.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #undef Bool | 26 #undef Bool |
| 27 #undef None | 27 #undef None |
| 28 #include "ui/events/test/events_test_utils_x11.h" | 28 #include "ui/events/test/events_test_utils_x11.h" |
| 29 #endif | 29 #endif |
| 30 | 30 |
| 31 namespace views { | 31 namespace views { |
| 32 namespace test { | 32 namespace test { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // Test implementation of MenuDelegate that only reports calls of OnPerformDrop. |
| 37 class TestMenuDelegate : public MenuDelegate { |
| 38 public: |
| 39 TestMenuDelegate(); |
| 40 ~TestMenuDelegate() override; |
| 41 |
| 42 bool on_perform_drop_called() { return on_perform_drop_called_; } |
| 43 |
| 44 int OnPerformDrop(MenuItemView* menu, |
| 45 DropPosition position, |
| 46 const ui::DropTargetEvent& event) override; |
| 47 |
| 48 private: |
| 49 bool on_perform_drop_called_; |
| 50 DISALLOW_COPY_AND_ASSIGN(TestMenuDelegate); |
| 51 }; |
| 52 |
| 53 TestMenuDelegate::TestMenuDelegate() : on_perform_drop_called_(false) {} |
| 54 |
| 55 TestMenuDelegate::~TestMenuDelegate() {} |
| 56 |
| 57 int TestMenuDelegate::OnPerformDrop(MenuItemView* menu, |
| 58 DropPosition position, |
| 59 const ui::DropTargetEvent& event) { |
| 60 on_perform_drop_called_ = true; |
| 61 return ui::DragDropTypes::DRAG_COPY; |
| 62 } |
| 63 |
| 36 // Test implementation of MenuControllerDelegate that only reports the values | 64 // Test implementation of MenuControllerDelegate that only reports the values |
| 37 // called of OnMenuClosed. | 65 // called of OnMenuClosed. |
| 38 class TestMenuControllerDelegate : public internal::MenuControllerDelegate { | 66 class TestMenuControllerDelegate : public internal::MenuControllerDelegate { |
| 39 public: | 67 public: |
| 40 TestMenuControllerDelegate(); | 68 TestMenuControllerDelegate(); |
| 41 ~TestMenuControllerDelegate() override {} | 69 ~TestMenuControllerDelegate() override {} |
| 42 | 70 |
| 43 int on_menu_closed_called() { return on_menu_closed_called_; } | 71 int on_menu_closed_called() { return on_menu_closed_called_; } |
| 44 | 72 |
| 45 NotifyType on_menu_closed_notify_type() { | 73 NotifyType on_menu_closed_notify_type() { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return menu_controller_->FindNextSelectableMenuItem( | 262 return menu_controller_->FindNextSelectableMenuItem( |
| 235 parent, index, MenuController::INCREMENT_SELECTION_UP); | 263 parent, index, MenuController::INCREMENT_SELECTION_UP); |
| 236 } | 264 } |
| 237 | 265 |
| 238 internal::MenuControllerDelegate* GetCurrentDelegate() { | 266 internal::MenuControllerDelegate* GetCurrentDelegate() { |
| 239 return menu_controller_->delegate_; | 267 return menu_controller_->delegate_; |
| 240 } | 268 } |
| 241 | 269 |
| 242 bool IsAsyncRun() { return menu_controller_->async_run_; } | 270 bool IsAsyncRun() { return menu_controller_->async_run_; } |
| 243 | 271 |
| 272 bool IsShowing() { return menu_controller_->showing_; } |
| 273 |
| 244 void SelectByChar(base::char16 character) { | 274 void SelectByChar(base::char16 character) { |
| 245 menu_controller_->SelectByChar(character); | 275 menu_controller_->SelectByChar(character); |
| 246 } | 276 } |
| 247 | 277 |
| 278 void SetDropMenuItem(MenuItemView* target, |
| 279 MenuDelegate::DropPosition position) { |
| 280 menu_controller_->SetDropMenuItem(target, position); |
| 281 } |
| 282 |
| 248 void SetIsCombobox(bool is_combobox) { | 283 void SetIsCombobox(bool is_combobox) { |
| 249 menu_controller_->set_is_combobox(is_combobox); | 284 menu_controller_->set_is_combobox(is_combobox); |
| 250 } | 285 } |
| 251 | 286 |
| 252 void RunMenu() { | 287 void RunMenu() { |
| 253 menu_controller_->RunMessageLoop(false); | 288 menu_controller_->RunMessageLoop(false); |
| 254 } | 289 } |
| 255 | 290 |
| 256 void Accept(MenuItemView* item, int event_flags) { | 291 void Accept(MenuItemView* item, int event_flags) { |
| 257 menu_controller_->Accept(item, event_flags); | 292 menu_controller_->Accept(item, event_flags); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 280 event_generator_.reset( | 315 event_generator_.reset( |
| 281 new ui::test::EventGenerator(GetContext(), owner_->GetNativeWindow())); | 316 new ui::test::EventGenerator(GetContext(), owner_->GetNativeWindow())); |
| 282 owner_->Show(); | 317 owner_->Show(); |
| 283 | 318 |
| 284 SetupMenuItem(); | 319 SetupMenuItem(); |
| 285 | 320 |
| 286 SetupMenuController(); | 321 SetupMenuController(); |
| 287 } | 322 } |
| 288 | 323 |
| 289 void SetupMenuItem() { | 324 void SetupMenuItem() { |
| 290 menu_delegate_.reset(new MenuDelegate); | 325 menu_delegate_.reset(new TestMenuDelegate); |
| 291 menu_item_.reset(new TestMenuItemViewShown(menu_delegate_.get())); | 326 menu_item_.reset(new TestMenuItemViewShown(menu_delegate_.get())); |
| 292 menu_item_->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); | 327 menu_item_->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); |
| 293 menu_item_->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); | 328 menu_item_->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); |
| 294 menu_item_->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); | 329 menu_item_->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); |
| 295 menu_item_->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); | 330 menu_item_->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); |
| 296 } | 331 } |
| 297 | 332 |
| 298 void SetupMenuController() { | 333 void SetupMenuController() { |
| 299 menu_controller_delegate_.reset(new TestMenuControllerDelegate); | 334 menu_controller_delegate_.reset(new TestMenuControllerDelegate); |
| 300 menu_controller_ = | 335 menu_controller_ = |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 EXPECT_EQ(delegate, GetCurrentDelegate()); | 628 EXPECT_EQ(delegate, GetCurrentDelegate()); |
| 594 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 629 EXPECT_EQ(0, delegate->on_menu_closed_called()); |
| 595 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 630 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 596 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); | 631 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); |
| 597 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); | 632 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); |
| 598 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 633 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 599 nested_delegate->on_menu_closed_notify_type()); | 634 nested_delegate->on_menu_closed_notify_type()); |
| 600 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 635 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 601 } | 636 } |
| 602 | 637 |
| 638 // Tests that dropping within an asynchronous menu notifies the MenuDelegate, |
| 639 // and exits the MenuController. |
| 640 TEST_F(MenuControllerTest, AsynchronousPerformDrop) { |
| 641 MenuController* controller = menu_controller(); |
| 642 controller->SetAsyncRun(true); |
| 643 SubmenuView* source = menu_item()->GetSubmenu(); |
| 644 MenuItemView* target = source->GetMenuItemAt(0); |
| 645 |
| 646 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER); |
| 647 |
| 648 ui::OSExchangeData drop_data; |
| 649 gfx::Rect bounds(target->bounds()); |
| 650 gfx::Point location(bounds.x(), bounds.y()); |
| 651 ui::DropTargetEvent target_event(drop_data, location, location, |
| 652 ui::DragDropTypes::DRAG_MOVE); |
| 653 controller->OnPerformDrop(source, target_event); |
| 654 |
| 655 TestMenuDelegate* menu_delegate = |
| 656 static_cast<TestMenuDelegate*>(target->GetDelegate()); |
| 657 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
| 658 EXPECT_TRUE(menu_delegate->on_perform_drop_called()); |
| 659 EXPECT_FALSE(IsShowing()); |
| 660 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); |
| 661 |
| 662 // Closing from drag and drop is enqueued. The message to |
| 663 // MenuControllerDelegate occurs afterwards so that the destruction of |
| 664 // MenuController does no free the layers who are still referenced in enqueued |
| 665 // tasks. |
| 666 RunPendingMessages(); |
| 667 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
| 668 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
| 669 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 670 controller_delegate->on_menu_closed_notify_type()); |
| 671 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 672 } |
| 673 |
| 674 // Tests that dragging within an asynchronous menu notifies the |
| 675 // MenuControllerDelegate for shutdown. |
| 676 TEST_F(MenuControllerTest, AsynchronousDragComplete) { |
| 677 MenuController* controller = menu_controller(); |
| 678 controller->SetAsyncRun(true); |
| 679 |
| 680 controller->OnDragWillStart(); |
| 681 controller->OnDragComplete(true); |
| 682 |
| 683 EXPECT_FALSE(controller->drag_in_progress()); |
| 684 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
| 685 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); |
| 686 |
| 687 // Closing from drag and drop is enqueued. The message to |
| 688 // MenuControllerDelegate occurs afterwards so that the destruction of |
| 689 // MenuController does no free the layers who are still referenced in enqueued |
| 690 // tasks. |
| 691 RunPendingMessages(); |
| 692 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
| 693 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
| 694 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 695 controller_delegate->on_menu_closed_notify_type()); |
| 696 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 697 } |
| 698 |
| 699 // Tets that an asynchronous menu nested within an asynchronous menu closes both |
| 700 // menus, and notifies both delegates. |
| 701 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { |
| 702 MenuController* controller = menu_controller(); |
| 703 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
| 704 scoped_ptr<TestMenuControllerDelegate> nested_delegate( |
| 705 new TestMenuControllerDelegate()); |
| 706 |
| 707 ASSERT_FALSE(IsAsyncRun()); |
| 708 // Sets the run created in SetUp |
| 709 controller->SetAsyncRun(true); |
| 710 |
| 711 // Nested run |
| 712 controller->AddNestedDelegate(nested_delegate.get()); |
| 713 controller->SetAsyncRun(true); |
| 714 int mouse_event_flags = 0; |
| 715 MenuItemView* run_result = |
| 716 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
| 717 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
| 718 EXPECT_EQ(run_result, nullptr); |
| 719 |
| 720 controller->CancelAll(); |
| 721 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
| 722 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
| 723 } |
| 724 |
| 603 } // namespace test | 725 } // namespace test |
| 604 } // namespace views | 726 } // namespace views |
| OLD | NEW |