| 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/run_loop.h" | 7 #include "base/run_loop.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "ui/events/event_handler.h" | 9 #include "ui/events/event_handler.h" |
| 10 #include "ui/events/null_event_targeter.h" | 10 #include "ui/events/null_event_targeter.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #undef None | 27 #undef None |
| 28 #include "ui/events/devices/x11/device_data_manager_x11.h" | 28 #include "ui/events/devices/x11/device_data_manager_x11.h" |
| 29 #include "ui/events/test/events_test_utils_x11.h" | 29 #include "ui/events/test/events_test_utils_x11.h" |
| 30 #elif defined(USE_OZONE) | 30 #elif defined(USE_OZONE) |
| 31 #include "ui/events/event.h" | 31 #include "ui/events/event.h" |
| 32 #elif defined(OS_MACOSX) | 32 #elif defined(OS_MACOSX) |
| 33 #include "ui/events/test/event_generator.h" | 33 #include "ui/events/test/event_generator.h" |
| 34 #endif | 34 #endif |
| 35 | 35 |
| 36 namespace views { | 36 namespace views { |
| 37 namespace test { |
| 37 | 38 |
| 38 namespace { | 39 namespace { |
| 39 | 40 |
| 40 class TestMenuItemView : public MenuItemView { | 41 class TestMenuItemView : public MenuItemView { |
| 41 public: | 42 public: |
| 42 TestMenuItemView() : MenuItemView(nullptr) {} | 43 TestMenuItemView() : MenuItemView(nullptr) {} |
| 43 ~TestMenuItemView() override {} | 44 ~TestMenuItemView() override {} |
| 44 | 45 |
| 45 private: | 46 private: |
| 46 DISALLOW_COPY_AND_ASSIGN(TestMenuItemView); | 47 DISALLOW_COPY_AND_ASSIGN(TestMenuItemView); |
| 47 }; | 48 }; |
| 48 | 49 |
| 50 class SubmenuViewShown : public SubmenuView { |
| 51 public: |
| 52 SubmenuViewShown(MenuItemView* parent) : SubmenuView(parent) {} |
| 53 ~SubmenuViewShown() override {} |
| 54 bool IsShowing() override { return true; } |
| 55 |
| 56 private: |
| 57 DISALLOW_COPY_AND_ASSIGN(SubmenuViewShown); |
| 58 }; |
| 59 |
| 49 class TestPlatformEventSource : public ui::PlatformEventSource { | 60 class TestPlatformEventSource : public ui::PlatformEventSource { |
| 50 public: | 61 public: |
| 51 TestPlatformEventSource() { | 62 TestPlatformEventSource() { |
| 52 #if defined(USE_X11) | 63 #if defined(USE_X11) |
| 53 ui::DeviceDataManagerX11::CreateInstance(); | 64 ui::DeviceDataManagerX11::CreateInstance(); |
| 54 #endif | 65 #endif |
| 55 } | 66 } |
| 56 ~TestPlatformEventSource() override {} | 67 ~TestPlatformEventSource() override {} |
| 57 | 68 |
| 58 uint32_t Dispatch(const ui::PlatformEvent& event) { | 69 uint32_t Dispatch(const ui::PlatformEvent& event) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 } | 107 } |
| 97 | 108 |
| 98 base::MessagePumpDispatcher* dispatcher_; | 109 base::MessagePumpDispatcher* dispatcher_; |
| 99 | 110 |
| 100 DISALLOW_COPY_AND_ASSIGN(TestDispatcherClient); | 111 DISALLOW_COPY_AND_ASSIGN(TestDispatcherClient); |
| 101 }; | 112 }; |
| 102 #endif // USE_AURA | 113 #endif // USE_AURA |
| 103 | 114 |
| 104 } // namespace | 115 } // namespace |
| 105 | 116 |
| 117 class TestMenuItemViewShown : public MenuItemView { |
| 118 public: |
| 119 TestMenuItemViewShown() : MenuItemView(nullptr) { |
| 120 submenu_ = new SubmenuViewShown(this); |
| 121 } |
| 122 ~TestMenuItemViewShown() override {} |
| 123 |
| 124 private: |
| 125 DISALLOW_COPY_AND_ASSIGN(TestMenuItemViewShown); |
| 126 }; |
| 127 |
| 106 class MenuControllerTest : public ViewsTestBase { | 128 class MenuControllerTest : public ViewsTestBase { |
| 107 public: | 129 public: |
| 108 MenuControllerTest() : controller_(nullptr) {} | 130 MenuControllerTest() : controller_(nullptr) {} |
| 109 ~MenuControllerTest() override { ResetMenuController(); } | 131 ~MenuControllerTest() override { ResetMenuController(); } |
| 110 | 132 |
| 111 // Dispatches |count| number of items, each in a separate iteration of the | 133 // Dispatches |count| number of items, each in a separate iteration of the |
| 112 // message-loop, by posting a task. | 134 // message-loop, by posting a task. |
| 113 void Step3_DispatchEvents(int count) { | 135 void Step3_DispatchEvents(int count) { |
| 114 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); | 136 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 115 base::MessageLoop::ScopedNestableTaskAllower allow(loop); | 137 base::MessageLoop::ScopedNestableTaskAllower allow(loop); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 #endif | 185 #endif |
| 164 return widget.Pass(); | 186 return widget.Pass(); |
| 165 } | 187 } |
| 166 | 188 |
| 167 const MenuItemView* pending_state_item() const { | 189 const MenuItemView* pending_state_item() const { |
| 168 return controller_->pending_state_.item; | 190 return controller_->pending_state_.item; |
| 169 } | 191 } |
| 170 | 192 |
| 171 void SetPendingStateItem(MenuItemView* item) { | 193 void SetPendingStateItem(MenuItemView* item) { |
| 172 controller_->pending_state_.item = item; | 194 controller_->pending_state_.item = item; |
| 195 controller_->pending_state_.submenu_open = true; |
| 173 } | 196 } |
| 174 | 197 |
| 175 void ResetSelection() { | 198 void ResetSelection() { |
| 176 controller_->SetSelection(nullptr, | 199 controller_->SetSelection(nullptr, |
| 177 MenuController::SELECTION_EXIT | | 200 MenuController::SELECTION_EXIT | |
| 178 MenuController::SELECTION_UPDATE_IMMEDIATELY); | 201 MenuController::SELECTION_UPDATE_IMMEDIATELY); |
| 179 } | 202 } |
| 180 | 203 |
| 181 void IncrementSelection(int delta) { | 204 void IncrementSelection() { |
| 182 controller_->IncrementSelection(delta); | 205 controller_->IncrementSelection(MenuController::INCREMENT_SELECTION_DOWN); |
| 183 } | 206 } |
| 184 | 207 |
| 185 MenuItemView* FindFirstSelectableMenuItem(MenuItemView* parent) { | 208 void DecrementSelection() { |
| 186 return controller_->FindFirstSelectableMenuItem(parent); | 209 controller_->IncrementSelection(MenuController::INCREMENT_SELECTION_UP); |
| 210 } |
| 211 |
| 212 MenuItemView* FindInitialSelectableMenuItemDown(MenuItemView* parent) { |
| 213 return controller_->FindInitialSelectableMenuItem( |
| 214 parent, MenuController::INCREMENT_SELECTION_DOWN); |
| 215 } |
| 216 |
| 217 MenuItemView* FindInitialSelectableMenuItemUp(MenuItemView* parent) { |
| 218 return controller_->FindInitialSelectableMenuItem( |
| 219 parent, MenuController::INCREMENT_SELECTION_UP); |
| 187 } | 220 } |
| 188 | 221 |
| 189 MenuItemView* FindNextSelectableMenuItem(MenuItemView* parent, | 222 MenuItemView* FindNextSelectableMenuItem(MenuItemView* parent, |
| 190 int index, | 223 int index) { |
| 191 int delta) { | 224 return controller_->FindNextSelectableMenuItem( |
| 192 return controller_->FindNextSelectableMenuItem(parent, index, delta); | 225 parent, index, MenuController::INCREMENT_SELECTION_DOWN); |
| 193 } | 226 } |
| 227 |
| 228 MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent, |
| 229 int index) { |
| 230 return controller_->FindNextSelectableMenuItem( |
| 231 parent, index, MenuController::INCREMENT_SELECTION_UP); |
| 232 } |
| 233 |
| 194 void SetupMenu(views::Widget* owner, views::MenuItemView* item) { | 234 void SetupMenu(views::Widget* owner, views::MenuItemView* item) { |
| 195 ResetMenuController(); | 235 ResetMenuController(); |
| 196 controller_ = new MenuController(nullptr, true, nullptr); | 236 controller_ = new MenuController(nullptr, true, nullptr); |
| 197 controller_->owner_ = owner; | 237 controller_->owner_ = owner; |
| 198 controller_->showing_ = true; | 238 controller_->showing_ = true; |
| 199 controller_->SetSelection(item, | 239 controller_->SetSelection(item, |
| 200 MenuController::SELECTION_UPDATE_IMMEDIATELY); | 240 MenuController::SELECTION_UPDATE_IMMEDIATELY); |
| 201 } | 241 } |
| 202 | 242 |
| 203 void RunMenu(views::Widget* owner) { | 243 void RunMenu(views::Widget* owner) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 break; | 374 break; |
| 335 } | 375 } |
| 336 } | 376 } |
| 337 | 377 |
| 338 int outstanding_touches() const { return outstanding_touches_; } | 378 int outstanding_touches() const { return outstanding_touches_; } |
| 339 | 379 |
| 340 private: | 380 private: |
| 341 int outstanding_touches_; | 381 int outstanding_touches_; |
| 342 }; | 382 }; |
| 343 | 383 |
| 344 // Tests that touch event ids are released correctly. See | 384 // Tests that touch event ids are released correctly. See crbug.com/439051 for |
| 345 // crbug.com/439051 for details. When the ids aren't managed | 385 // details. When the ids aren't managed correctly, we get stuck down touches. |
| 346 // correctly, we get stuck down touches. | |
| 347 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { | 386 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { |
| 348 scoped_ptr<Widget> owner(CreateOwnerWidget()); | 387 scoped_ptr<Widget> owner(CreateOwnerWidget()); |
| 349 TestEventHandler test_event_handler; | 388 TestEventHandler test_event_handler; |
| 350 owner->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( | 389 owner->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( |
| 351 &test_event_handler); | 390 &test_event_handler); |
| 352 | 391 |
| 353 std::vector<int> devices; | 392 std::vector<int> devices; |
| 354 devices.push_back(1); | 393 devices.push_back(1); |
| 355 ui::SetUpTouchDevicesForTest(devices); | 394 ui::SetUpTouchDevicesForTest(devices); |
| 356 | 395 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 368 base::Unretained(this), MenuController::EXIT_OUTERMOST)); | 407 base::Unretained(this), MenuController::EXIT_OUTERMOST)); |
| 369 | 408 |
| 370 RunMenu(owner.get()); | 409 RunMenu(owner.get()); |
| 371 EXPECT_EQ(0, test_event_handler.outstanding_touches()); | 410 EXPECT_EQ(0, test_event_handler.outstanding_touches()); |
| 372 | 411 |
| 373 owner->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( | 412 owner->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( |
| 374 &test_event_handler); | 413 &test_event_handler); |
| 375 } | 414 } |
| 376 #endif // defined(USE_X11) | 415 #endif // defined(USE_X11) |
| 377 | 416 |
| 378 TEST_F(MenuControllerTest, FirstSelectedItem) { | 417 // Tests that initial selected menu items are correct when items are enabled or |
| 418 // disabled. |
| 419 TEST_F(MenuControllerTest, InitialSelectedItem) { |
| 379 scoped_ptr<Widget> owner(CreateOwnerWidget()); | 420 scoped_ptr<Widget> owner(CreateOwnerWidget()); |
| 380 scoped_ptr<TestMenuItemView> menu_item(new TestMenuItemView); | 421 scoped_ptr<TestMenuItemView> menu_item(new TestMenuItemView); |
| 381 menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); | 422 menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); |
| 382 menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); | 423 menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); |
| 383 // Disabling the item "One" gets it skipped when a menu is first opened. | 424 menu_item->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); |
| 384 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false); | |
| 385 | |
| 386 SetupMenu(owner.get(), menu_item.get()); | 425 SetupMenu(owner.get(), menu_item.get()); |
| 387 | 426 |
| 388 // First selectable item should be item "Two". | 427 // Leave items "Two" and "Three" enabled. |
| 389 MenuItemView* first_selectable = FindFirstSelectableMenuItem(menu_item.get()); | 428 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false); |
| 429 // The first selectable item should be item "Two". |
| 430 MenuItemView* first_selectable = |
| 431 FindInitialSelectableMenuItemDown(menu_item.get()); |
| 432 ASSERT_NE(nullptr, first_selectable); |
| 390 EXPECT_EQ(2, first_selectable->GetCommand()); | 433 EXPECT_EQ(2, first_selectable->GetCommand()); |
| 434 // The last selectable item should be item "Three". |
| 435 MenuItemView* last_selectable = |
| 436 FindInitialSelectableMenuItemUp(menu_item.get()); |
| 437 ASSERT_NE(nullptr, last_selectable); |
| 438 EXPECT_EQ(3, last_selectable->GetCommand()); |
| 439 |
| 440 // Leave items "One" and "Two" enabled. |
| 441 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(true); |
| 442 menu_item->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(true); |
| 443 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false); |
| 444 // The first selectable item should be item "One". |
| 445 first_selectable = FindInitialSelectableMenuItemDown(menu_item.get()); |
| 446 ASSERT_NE(nullptr, first_selectable); |
| 447 EXPECT_EQ(1, first_selectable->GetCommand()); |
| 448 // The last selectable item should be item "Two". |
| 449 last_selectable = FindInitialSelectableMenuItemUp(menu_item.get()); |
| 450 ASSERT_NE(nullptr, last_selectable); |
| 451 EXPECT_EQ(2, last_selectable->GetCommand()); |
| 452 |
| 453 // Leave only a single item "One" enabled. |
| 454 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(true); |
| 455 menu_item->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(false); |
| 456 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false); |
| 457 // The first selectable item should be item "One". |
| 458 first_selectable = FindInitialSelectableMenuItemDown(menu_item.get()); |
| 459 ASSERT_NE(nullptr, first_selectable); |
| 460 EXPECT_EQ(1, first_selectable->GetCommand()); |
| 461 // The last selectable item should be item "One". |
| 462 last_selectable = FindInitialSelectableMenuItemUp(menu_item.get()); |
| 463 ASSERT_NE(nullptr, last_selectable); |
| 464 EXPECT_EQ(1, last_selectable->GetCommand()); |
| 465 |
| 466 // Leave only a single item "Three" enabled. |
| 467 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false); |
| 468 menu_item->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(false); |
| 469 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(true); |
| 470 // The first selectable item should be item "Three". |
| 471 first_selectable = FindInitialSelectableMenuItemDown(menu_item.get()); |
| 472 ASSERT_NE(nullptr, first_selectable); |
| 473 EXPECT_EQ(3, first_selectable->GetCommand()); |
| 474 // The last selectable item should be item "Three". |
| 475 last_selectable = FindInitialSelectableMenuItemUp(menu_item.get()); |
| 476 ASSERT_NE(nullptr, last_selectable); |
| 477 EXPECT_EQ(3, last_selectable->GetCommand()); |
| 478 |
| 479 // Leave only a single item ("Two") selected. It should be the first and the |
| 480 // last selectable item. |
| 481 menu_item->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false); |
| 482 menu_item->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(true); |
| 483 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false); |
| 484 first_selectable = FindInitialSelectableMenuItemDown(menu_item.get()); |
| 485 ASSERT_NE(nullptr, first_selectable); |
| 486 EXPECT_EQ(2, first_selectable->GetCommand()); |
| 487 last_selectable = FindInitialSelectableMenuItemUp(menu_item.get()); |
| 488 ASSERT_NE(nullptr, last_selectable); |
| 489 EXPECT_EQ(2, last_selectable->GetCommand()); |
| 391 | 490 |
| 392 // There should be no next or previous selectable item since there is only a | 491 // There should be no next or previous selectable item since there is only a |
| 393 // single enabled item in the menu. | 492 // single enabled item in the menu. |
| 394 SetPendingStateItem(first_selectable); | 493 EXPECT_EQ(nullptr, FindNextSelectableMenuItem(menu_item.get(), 1)); |
| 395 EXPECT_EQ(nullptr, FindNextSelectableMenuItem(menu_item.get(), 1, 1)); | 494 EXPECT_EQ(nullptr, FindPreviousSelectableMenuItem(menu_item.get(), 1)); |
| 396 EXPECT_EQ(nullptr, FindNextSelectableMenuItem(menu_item.get(), 1, -1)); | |
| 397 | 495 |
| 398 // Clear references in menu controller to the menu item that is going away. | 496 // Clear references in menu controller to the menu item that is going away. |
| 399 ResetSelection(); | 497 ResetSelection(); |
| 400 } | 498 } |
| 401 | 499 |
| 500 // Tests that opening menu and pressing 'Down' and 'Up' iterates over enabled |
| 501 // items. |
| 402 TEST_F(MenuControllerTest, NextSelectedItem) { | 502 TEST_F(MenuControllerTest, NextSelectedItem) { |
| 403 scoped_ptr<Widget> owner(CreateOwnerWidget()); | 503 scoped_ptr<Widget> owner(CreateOwnerWidget()); |
| 404 scoped_ptr<TestMenuItemView> menu_item(new TestMenuItemView); | 504 scoped_ptr<TestMenuItemView> menu_item(new TestMenuItemView); |
| 405 menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); | 505 menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); |
| 406 menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); | 506 menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); |
| 407 menu_item->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); | 507 menu_item->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); |
| 408 menu_item->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); | 508 menu_item->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); |
| 409 // Disabling the item "Three" gets it skipped when using keyboard to navigate. | 509 // Disabling the item "Three" gets it skipped when using keyboard to navigate. |
| 410 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false); | 510 menu_item->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false); |
| 411 | 511 |
| 412 SetupMenu(owner.get(), menu_item.get()); | 512 SetupMenu(owner.get(), menu_item.get()); |
| 413 | 513 |
| 414 // Fake initial hot selection. | 514 // Fake initial hot selection. |
| 415 SetPendingStateItem(menu_item->GetSubmenu()->GetMenuItemAt(0)); | 515 SetPendingStateItem(menu_item->GetSubmenu()->GetMenuItemAt(0)); |
| 416 EXPECT_EQ(1, pending_state_item()->GetCommand()); | 516 EXPECT_EQ(1, pending_state_item()->GetCommand()); |
| 417 | 517 |
| 418 // Move down in the menu. | 518 // Move down in the menu. |
| 419 // Select next item. | 519 // Select next item. |
| 420 IncrementSelection(1); | 520 IncrementSelection(); |
| 421 EXPECT_EQ(2, pending_state_item()->GetCommand()); | 521 EXPECT_EQ(2, pending_state_item()->GetCommand()); |
| 422 | 522 |
| 423 // Skip disabled item. | 523 // Skip disabled item. |
| 424 IncrementSelection(1); | 524 IncrementSelection(); |
| 425 EXPECT_EQ(4, pending_state_item()->GetCommand()); | 525 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 426 | 526 |
| 427 // Wrap around. | 527 // Wrap around. |
| 428 IncrementSelection(1); | 528 IncrementSelection(); |
| 429 EXPECT_EQ(1, pending_state_item()->GetCommand()); | 529 EXPECT_EQ(1, pending_state_item()->GetCommand()); |
| 430 | 530 |
| 431 // Move up in the menu. | 531 // Move up in the menu. |
| 432 // Wrap around. | 532 // Wrap around. |
| 433 IncrementSelection(-1); | 533 DecrementSelection(); |
| 434 EXPECT_EQ(4, pending_state_item()->GetCommand()); | 534 EXPECT_EQ(4, pending_state_item()->GetCommand()); |
| 435 | 535 |
| 436 // Skip disabled item. | 536 // Skip disabled item. |
| 437 IncrementSelection(-1); | 537 DecrementSelection(); |
| 438 EXPECT_EQ(2, pending_state_item()->GetCommand()); | 538 EXPECT_EQ(2, pending_state_item()->GetCommand()); |
| 439 | 539 |
| 440 // Select previous item. | 540 // Select previous item. |
| 441 IncrementSelection(-1); | 541 DecrementSelection(); |
| 442 EXPECT_EQ(1, pending_state_item()->GetCommand()); | 542 EXPECT_EQ(1, pending_state_item()->GetCommand()); |
| 443 | 543 |
| 444 // Clear references in menu controller to the menu item that is going away. | 544 // Clear references in menu controller to the menu item that is going away. |
| 445 ResetSelection(); | 545 ResetSelection(); |
| 446 } | 546 } |
| 447 | 547 |
| 548 // Tests that opening menu and pressing 'Up' selects the last enabled menu item. |
| 549 TEST_F(MenuControllerTest, PreviousSelectedItem) { |
| 550 scoped_ptr<Widget> owner(CreateOwnerWidget()); |
| 551 scoped_ptr<TestMenuItemViewShown> menu_item(new TestMenuItemViewShown); |
| 552 menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One")); |
| 553 menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two")); |
| 554 menu_item->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three")); |
| 555 menu_item->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four")); |
| 556 // Disabling the item "Four" gets it skipped when using keyboard to navigate. |
| 557 menu_item->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false); |
| 558 |
| 559 SetupMenu(owner.get(), menu_item.get()); |
| 560 |
| 561 // Fake initial root item selection and submenu showing. |
| 562 SetPendingStateItem(menu_item.get()); |
| 563 EXPECT_EQ(0, pending_state_item()->GetCommand()); |
| 564 |
| 565 // Move up and select a previous (in our case the last enabled) item. |
| 566 DecrementSelection(); |
| 567 EXPECT_EQ(3, pending_state_item()->GetCommand()); |
| 568 |
| 569 // Clear references in menu controller to the menu item that is going away. |
| 570 ResetSelection(); |
| 571 } |
| 572 |
| 573 } // namespace test |
| 448 } // namespace views | 574 } // namespace views |
| OLD | NEW |