| 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/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "ui/aura/scoped_window_targeter.h" | 12 #include "ui/aura/scoped_window_targeter.h" |
| 13 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
| 14 #include "ui/events/event.h" | 14 #include "ui/events/event.h" |
| 15 #include "ui/events/event_constants.h" | 15 #include "ui/events/event_constants.h" |
| 16 #include "ui/events/event_handler.h" | 16 #include "ui/events/event_handler.h" |
| 17 #include "ui/events/event_utils.h" | 17 #include "ui/events/event_utils.h" |
| 18 #include "ui/events/null_event_targeter.h" | 18 #include "ui/events/null_event_targeter.h" |
| 19 #include "ui/events/test/event_generator.h" | 19 #include "ui/events/test/event_generator.h" |
| 20 #include "ui/gfx/geometry/point.h" | 20 #include "ui/gfx/geometry/point.h" |
| 21 #include "ui/gfx/geometry/rect.h" | 21 #include "ui/gfx/geometry/rect.h" |
| 22 #include "ui/views/controls/menu/menu_controller_delegate.h" | 22 #include "ui/views/controls/menu/menu_controller_delegate.h" |
| 23 #include "ui/views/controls/menu/menu_delegate.h" | 23 #include "ui/views/controls/menu/menu_delegate.h" |
| 24 #include "ui/views/controls/menu/menu_host.h" |
| 24 #include "ui/views/controls/menu/menu_item_view.h" | 25 #include "ui/views/controls/menu/menu_item_view.h" |
| 25 #include "ui/views/controls/menu/menu_message_loop.h" | 26 #include "ui/views/controls/menu/menu_message_loop.h" |
| 26 #include "ui/views/controls/menu/menu_scroll_view_container.h" | 27 #include "ui/views/controls/menu/menu_scroll_view_container.h" |
| 27 #include "ui/views/controls/menu/submenu_view.h" | 28 #include "ui/views/controls/menu/submenu_view.h" |
| 28 #include "ui/views/test/menu_test_utils.h" | 29 #include "ui/views/test/menu_test_utils.h" |
| 29 #include "ui/views/test/views_test_base.h" | 30 #include "ui/views/test/views_test_base.h" |
| 30 | 31 |
| 31 #if defined(USE_AURA) | 32 #if defined(USE_AURA) |
| 32 #include "ui/aura/scoped_window_targeter.h" | 33 #include "ui/aura/scoped_window_targeter.h" |
| 33 #include "ui/aura/window.h" | 34 #include "ui/aura/window.h" |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 } | 372 } |
| 372 | 373 |
| 373 internal::MenuControllerDelegate* GetCurrentDelegate() { | 374 internal::MenuControllerDelegate* GetCurrentDelegate() { |
| 374 return menu_controller_->delegate_; | 375 return menu_controller_->delegate_; |
| 375 } | 376 } |
| 376 | 377 |
| 377 bool IsAsyncRun() { return menu_controller_->async_run_; } | 378 bool IsAsyncRun() { return menu_controller_->async_run_; } |
| 378 | 379 |
| 379 bool IsShowing() { return menu_controller_->showing_; } | 380 bool IsShowing() { return menu_controller_->showing_; } |
| 380 | 381 |
| 382 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; } |
| 383 |
| 384 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); } |
| 385 |
| 386 void MenuHostOnDragComplete(MenuHost* host) { host->OnDragComplete(); } |
| 387 |
| 381 void SelectByChar(base::char16 character) { | 388 void SelectByChar(base::char16 character) { |
| 382 menu_controller_->SelectByChar(character); | 389 menu_controller_->SelectByChar(character); |
| 383 } | 390 } |
| 384 | 391 |
| 385 void SetDropMenuItem(MenuItemView* target, | 392 void SetDropMenuItem(MenuItemView* target, |
| 386 MenuDelegate::DropPosition position) { | 393 MenuDelegate::DropPosition position) { |
| 387 menu_controller_->SetDropMenuItem(target, position); | 394 menu_controller_->SetDropMenuItem(target, position); |
| 388 } | 395 } |
| 389 | 396 |
| 390 void SetIsCombobox(bool is_combobox) { | 397 void SetIsCombobox(bool is_combobox) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 for (int i = 0; i < 3; ++i) { | 451 for (int i = 0; i < 3; ++i) { |
| 445 LabelButton* button = | 452 LabelButton* button = |
| 446 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); | 453 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); |
| 447 // This is an in-menu button. Hence it must be always focusable. | 454 // This is an in-menu button. Hence it must be always focusable. |
| 448 button->SetFocusBehavior(View::FocusBehavior::ALWAYS); | 455 button->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
| 449 item_view->AddChildView(button); | 456 item_view->AddChildView(button); |
| 450 } | 457 } |
| 451 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); | 458 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); |
| 452 } | 459 } |
| 453 | 460 |
| 461 void DestroyMenuItem() { menu_item_.reset(); } |
| 462 |
| 454 CustomButton* GetHotButton() { | 463 CustomButton* GetHotButton() { |
| 455 return menu_controller_->hot_button_; | 464 return menu_controller_->hot_button_; |
| 456 } | 465 } |
| 457 | 466 |
| 458 void SetHotTrackedButton(CustomButton* hot_button) { | 467 void SetHotTrackedButton(CustomButton* hot_button) { |
| 459 menu_controller_->SetHotTrackedButton(hot_button); | 468 menu_controller_->SetHotTrackedButton(hot_button); |
| 460 } | 469 } |
| 461 | 470 |
| 462 void ExitMenuRun() { | 471 void ExitMenuRun() { |
| 463 menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST); | 472 menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST); |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1021 |
| 1013 EXPECT_FALSE(controller->drag_in_progress()); | 1022 EXPECT_FALSE(controller->drag_in_progress()); |
| 1014 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); | 1023 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
| 1015 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); | 1024 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
| 1016 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); | 1025 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
| 1017 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1026 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 1018 controller_delegate->on_menu_closed_notify_type()); | 1027 controller_delegate->on_menu_closed_notify_type()); |
| 1019 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1028 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
| 1020 } | 1029 } |
| 1021 | 1030 |
| 1031 // Tests that if a menu is destroyed while drag operations are occuring, that |
| 1032 // the MenuHost does not crash as the drag completes. |
| 1033 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) { |
| 1034 MenuController* controller = menu_controller(); |
| 1035 controller->SetAsyncRun(true); |
| 1036 |
| 1037 SubmenuView* submenu = menu_item()->GetSubmenu(); |
| 1038 submenu->ShowAt(owner(), menu_item()->bounds(), false); |
| 1039 MenuHost* host = GetMenuHost(submenu); |
| 1040 MenuHostOnDragWillStart(host); |
| 1041 submenu->Close(); |
| 1042 DestroyMenuItem(); |
| 1043 MenuHostOnDragComplete(host); |
| 1044 } |
| 1045 |
| 1022 // Tets that an asynchronous menu nested within an asynchronous menu closes both | 1046 // Tets that an asynchronous menu nested within an asynchronous menu closes both |
| 1023 // menus, and notifies both delegates. | 1047 // menus, and notifies both delegates. |
| 1024 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { | 1048 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { |
| 1025 MenuController* controller = menu_controller(); | 1049 MenuController* controller = menu_controller(); |
| 1026 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1050 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
| 1027 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1051 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
| 1028 new TestMenuControllerDelegate()); | 1052 new TestMenuControllerDelegate()); |
| 1029 | 1053 |
| 1030 ASSERT_FALSE(IsAsyncRun()); | 1054 ASSERT_FALSE(IsAsyncRun()); |
| 1031 // Sets the run created in SetUp | 1055 // Sets the run created in SetUp |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 // This creates a nested message loop. | 1270 // This creates a nested message loop. |
| 1247 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(), | 1271 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(), |
| 1248 gfx::Rect(), MENU_ANCHOR_TOPLEFT, | 1272 gfx::Rect(), MENU_ANCHOR_TOPLEFT, |
| 1249 false, false, &result_event_flags)); | 1273 false, false, &result_event_flags)); |
| 1250 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called()); | 1274 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called()); |
| 1251 EXPECT_TRUE(nested_delegate->on_menu_closed_called()); | 1275 EXPECT_TRUE(nested_delegate->on_menu_closed_called()); |
| 1252 } | 1276 } |
| 1253 | 1277 |
| 1254 } // namespace test | 1278 } // namespace test |
| 1255 } // namespace views | 1279 } // namespace views |
| OLD | NEW |