Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
| 8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 // If there are multiple matches this is the index of the item after the | 357 // If there are multiple matches this is the index of the item after the |
| 358 // currently selected item whose mnemonic matches. This may remain -1 even | 358 // currently selected item whose mnemonic matches. This may remain -1 even |
| 359 // though there are matches. | 359 // though there are matches. |
| 360 int next_match; | 360 int next_match; |
| 361 }; | 361 }; |
| 362 | 362 |
| 363 // MenuController:State ------------------------------------------------------ | 363 // MenuController:State ------------------------------------------------------ |
| 364 | 364 |
| 365 MenuController::State::State() | 365 MenuController::State::State() |
| 366 : item(NULL), | 366 : item(NULL), |
| 367 hot_button(NULL), | |
|
sky
2016/03/23 21:42:40
nullptr (feel free to change NULL on the previous
varkha
2016/03/24 18:36:18
Done.
| |
| 367 submenu_open(false), | 368 submenu_open(false), |
| 368 anchor(MENU_ANCHOR_TOPLEFT), | 369 anchor(MENU_ANCHOR_TOPLEFT), |
| 369 context_menu(false) { | 370 context_menu(false) { |
| 370 } | 371 } |
| 371 | 372 |
| 372 MenuController::State::State(const State& other) = default; | 373 MenuController::State::State(const State& other) = default; |
| 373 | 374 |
| 374 MenuController::State::~State() {} | 375 MenuController::State::~State() {} |
| 375 | 376 |
| 376 // MenuController ------------------------------------------------------------ | 377 // MenuController ------------------------------------------------------------ |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 } | 418 } |
| 418 } | 419 } |
| 419 } | 420 } |
| 420 | 421 |
| 421 bool nested_menu = showing_; | 422 bool nested_menu = showing_; |
| 422 if (showing_) { | 423 if (showing_) { |
| 423 // Only support nesting of blocking_run menus, nesting of | 424 // Only support nesting of blocking_run menus, nesting of |
| 424 // blocking/non-blocking shouldn't be needed. | 425 // blocking/non-blocking shouldn't be needed. |
| 425 DCHECK(blocking_run_); | 426 DCHECK(blocking_run_); |
| 426 | 427 |
| 428 state_.hot_button = pending_state_.hot_button; | |
| 427 // We're already showing, push the current state. | 429 // We're already showing, push the current state. |
| 428 menu_stack_.push_back( | 430 menu_stack_.push_back( |
| 429 std::make_pair(state_, make_linked_ptr(pressed_lock_.release()))); | 431 std::make_pair(state_, make_linked_ptr(pressed_lock_.release()))); |
| 430 | 432 |
| 431 // The context menu should be owned by the same parent. | 433 // The context menu should be owned by the same parent. |
| 432 DCHECK_EQ(owner_, parent); | 434 DCHECK_EQ(owner_, parent); |
| 433 } else { | 435 } else { |
| 434 showing_ = true; | 436 showing_ = true; |
| 435 | 437 |
| 436 #if defined(USE_AURA) | 438 #if defined(USE_AURA) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 | 553 |
| 552 current_mouse_pressed_state_ |= event.changed_button_flags(); | 554 current_mouse_pressed_state_ |= event.changed_button_flags(); |
| 553 | 555 |
| 554 if (forward_to_root) { | 556 if (forward_to_root) { |
| 555 ui::MouseEvent event_for_root(event); | 557 ui::MouseEvent event_for_root(event); |
| 556 // Reset hot-tracking if a different view is getting a mouse press. | 558 // Reset hot-tracking if a different view is getting a mouse press. |
| 557 ConvertLocatedEventForRootView(source, forward_to_root, &event_for_root); | 559 ConvertLocatedEventForRootView(source, forward_to_root, &event_for_root); |
| 558 View* view = | 560 View* view = |
| 559 forward_to_root->GetEventHandlerForPoint(event_for_root.location()); | 561 forward_to_root->GetEventHandlerForPoint(event_for_root.location()); |
| 560 CustomButton* button = CustomButton::AsCustomButton(view); | 562 CustomButton* button = CustomButton::AsCustomButton(view); |
| 561 if (hot_button_ && hot_button_ != button) | 563 if (pending_state_.hot_button != button) |
| 562 SetHotTrackedButton(nullptr); | 564 SetHotTrackedButton(button); |
| 563 | 565 |
| 564 // Empty menu items are always handled by the menu controller. | 566 // Empty menu items are always handled by the menu controller. |
| 565 if (!view || view->id() != MenuItemView::kEmptyMenuItemViewID) { | 567 if (!view || view->id() != MenuItemView::kEmptyMenuItemViewID) { |
| 566 bool processed = forward_to_root->ProcessMousePressed(event_for_root); | 568 bool processed = forward_to_root->ProcessMousePressed(event_for_root); |
| 567 // If the event was processed, the root view becomes our current mouse | 569 // If the event was processed, the root view becomes our current mouse |
| 568 // handler... | 570 // handler... |
| 569 if (processed && !current_mouse_event_target_) { | 571 if (processed && !current_mouse_event_target_) { |
| 570 current_mouse_event_target_ = forward_to_root; | 572 current_mouse_event_target_ = forward_to_root; |
| 571 } | 573 } |
| 572 | 574 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 void MenuController::OnGestureEvent(SubmenuView* source, | 753 void MenuController::OnGestureEvent(SubmenuView* source, |
| 752 ui::GestureEvent* event) { | 754 ui::GestureEvent* event) { |
| 753 MenuHostRootView* root_view = GetRootView(source, event->location()); | 755 MenuHostRootView* root_view = GetRootView(source, event->location()); |
| 754 if (root_view) { | 756 if (root_view) { |
| 755 // Reset hot-tracking if a different view is getting a touch event. | 757 // Reset hot-tracking if a different view is getting a touch event. |
| 756 ui::GestureEvent event_for_root(*event); | 758 ui::GestureEvent event_for_root(*event); |
| 757 ConvertLocatedEventForRootView(source, root_view, &event_for_root); | 759 ConvertLocatedEventForRootView(source, root_view, &event_for_root); |
| 758 View* view = | 760 View* view = |
| 759 root_view->GetEventHandlerForPoint(event_for_root.location()); | 761 root_view->GetEventHandlerForPoint(event_for_root.location()); |
| 760 CustomButton* button = CustomButton::AsCustomButton(view); | 762 CustomButton* button = CustomButton::AsCustomButton(view); |
| 761 if (hot_button_ && hot_button_ != button) | 763 if (pending_state_.hot_button && pending_state_.hot_button != button) |
| 762 SetHotTrackedButton(nullptr); | 764 SetHotTrackedButton(nullptr); |
| 763 } | 765 } |
| 764 | 766 |
| 765 MenuPart part = GetMenuPart(source, event->location()); | 767 MenuPart part = GetMenuPart(source, event->location()); |
| 766 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { | 768 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { |
| 767 SetSelectionOnPointerDown(source, event); | 769 SetSelectionOnPointerDown(source, event); |
| 768 event->StopPropagation(); | 770 event->StopPropagation(); |
| 769 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) { | 771 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) { |
| 770 if (part.type == MenuPart::MENU_ITEM && part.menu) { | 772 if (part.type == MenuPart::MENU_ITEM && part.menu) { |
| 771 gfx::Point screen_location(event->location()); | 773 gfx::Point screen_location(event->location()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 | 829 |
| 828 void MenuController::ViewHierarchyChanged( | 830 void MenuController::ViewHierarchyChanged( |
| 829 SubmenuView* source, | 831 SubmenuView* source, |
| 830 const View::ViewHierarchyChangedDetails& details) { | 832 const View::ViewHierarchyChangedDetails& details) { |
| 831 if (!details.is_add) { | 833 if (!details.is_add) { |
| 832 // If the current mouse handler is removed, remove it as the handler. | 834 // If the current mouse handler is removed, remove it as the handler. |
| 833 if (details.child == current_mouse_event_target_) { | 835 if (details.child == current_mouse_event_target_) { |
| 834 current_mouse_event_target_ = nullptr; | 836 current_mouse_event_target_ = nullptr; |
| 835 current_mouse_pressed_state_ = 0; | 837 current_mouse_pressed_state_ = 0; |
| 836 } | 838 } |
| 837 // Update |hot_button_| if it gets removed while a menu is up. | 839 // Update |pending_state_.hot_button| if it gets removed while a menu is up. |
| 838 if (details.child == hot_button_) | 840 if (details.child == pending_state_.hot_button) |
| 839 hot_button_ = nullptr; | 841 pending_state_.hot_button = nullptr; |
| 840 } | 842 } |
| 841 } | 843 } |
| 842 | 844 |
| 843 bool MenuController::GetDropFormats( | 845 bool MenuController::GetDropFormats( |
| 844 SubmenuView* source, | 846 SubmenuView* source, |
| 845 int* formats, | 847 int* formats, |
| 846 std::set<ui::Clipboard::FormatType>* format_types) { | 848 std::set<ui::Clipboard::FormatType>* format_types) { |
| 847 return source->GetMenuItem()->GetDelegate()->GetDropFormats( | 849 return source->GetMenuItem()->GetDelegate()->GetDropFormats( |
| 848 source->GetMenuItem(), formats, format_types); | 850 source->GetMenuItem(), formats, format_types); |
| 849 } | 851 } |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1309 drop_target_(NULL), | 1311 drop_target_(NULL), |
| 1310 drop_position_(MenuDelegate::DROP_UNKNOWN), | 1312 drop_position_(MenuDelegate::DROP_UNKNOWN), |
| 1311 owner_(NULL), | 1313 owner_(NULL), |
| 1312 possible_drag_(false), | 1314 possible_drag_(false), |
| 1313 drag_in_progress_(false), | 1315 drag_in_progress_(false), |
| 1314 did_initiate_drag_(false), | 1316 did_initiate_drag_(false), |
| 1315 valid_drop_coordinates_(false), | 1317 valid_drop_coordinates_(false), |
| 1316 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), | 1318 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), |
| 1317 showing_submenu_(false), | 1319 showing_submenu_(false), |
| 1318 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()), | 1320 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()), |
| 1319 hot_button_(nullptr), | |
| 1320 delegate_(delegate), | 1321 delegate_(delegate), |
| 1321 message_loop_depth_(0), | 1322 message_loop_depth_(0), |
| 1322 closing_event_time_(base::TimeDelta()), | 1323 closing_event_time_(base::TimeDelta()), |
| 1323 menu_start_time_(base::TimeTicks()), | 1324 menu_start_time_(base::TimeTicks()), |
| 1324 async_run_(false), | 1325 async_run_(false), |
| 1325 is_combobox_(false), | 1326 is_combobox_(false), |
| 1326 item_selected_by_touch_(false), | 1327 item_selected_by_touch_(false), |
| 1327 current_mouse_event_target_(nullptr), | 1328 current_mouse_event_target_(nullptr), |
| 1328 current_mouse_pressed_state_(0), | 1329 current_mouse_pressed_state_(0), |
| 1329 message_loop_(MenuMessageLoop::Create()) { | 1330 message_loop_(MenuMessageLoop::Create()) { |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2117 if (item->GetSubmenu()->GetMenuItemCount()) { | 2118 if (item->GetSubmenu()->GetMenuItemCount()) { |
| 2118 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction); | 2119 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction); |
| 2119 SetInitialHotTrackedView(to_select, direction); | 2120 SetInitialHotTrackedView(to_select, direction); |
| 2120 return; | 2121 return; |
| 2121 } | 2122 } |
| 2122 } | 2123 } |
| 2123 | 2124 |
| 2124 if (item->has_children()) { | 2125 if (item->has_children()) { |
| 2125 CustomButton* button = GetFirstHotTrackedView(item); | 2126 CustomButton* button = GetFirstHotTrackedView(item); |
| 2126 if (button) { | 2127 if (button) { |
| 2127 DCHECK_EQ(hot_button_, button); | 2128 DCHECK_EQ(pending_state_.hot_button, button); |
| 2128 SetHotTrackedButton(nullptr); | 2129 SetHotTrackedButton(nullptr); |
| 2129 } | 2130 } |
| 2130 bool direction_is_down = direction == INCREMENT_SELECTION_DOWN; | 2131 bool direction_is_down = direction == INCREMENT_SELECTION_DOWN; |
| 2131 View* to_make_hot = button | 2132 View* to_make_hot = button |
| 2132 ? GetNextFocusableView(item, button, direction_is_down) | 2133 ? GetNextFocusableView(item, button, direction_is_down) |
| 2133 : GetInitialFocusableView(item, direction_is_down); | 2134 : GetInitialFocusableView(item, direction_is_down); |
| 2134 CustomButton* hot_button = CustomButton::AsCustomButton(to_make_hot); | 2135 CustomButton* hot_button = CustomButton::AsCustomButton(to_make_hot); |
| 2135 if (hot_button) { | 2136 if (hot_button) { |
| 2136 SetHotTrackedButton(hot_button); | 2137 SetHotTrackedButton(hot_button); |
| 2137 return; | 2138 return; |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2581 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); | 2582 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); |
| 2582 | 2583 |
| 2583 // Set exit_all_, which makes sure all nested loops exit immediately. | 2584 // Set exit_all_, which makes sure all nested loops exit immediately. |
| 2584 if (exit_type_ != EXIT_DESTROYED) | 2585 if (exit_type_ != EXIT_DESTROYED) |
| 2585 SetExitType(EXIT_ALL); | 2586 SetExitType(EXIT_ALL); |
| 2586 } else { | 2587 } else { |
| 2587 TerminateNestedMessageLoopIfNecessary(); | 2588 TerminateNestedMessageLoopIfNecessary(); |
| 2588 } | 2589 } |
| 2589 } | 2590 } |
| 2590 | 2591 |
| 2591 // Reset our pressed lock to the previous state's, if there was one. | 2592 // Reset our pressed lock and hot-tracked state to the previous state's, if |
| 2592 // The lock handles the case if the button was destroyed. | 2593 // they were active. The lock handles the case if the button was destroyed. |
| 2593 pressed_lock_.reset(nested_pressed_lock.release()); | 2594 pressed_lock_.reset(nested_pressed_lock.release()); |
| 2595 if (pending_state_.hot_button) | |
| 2596 pending_state_.hot_button->SetHotTracked(true); | |
| 2594 | 2597 |
| 2595 return result; | 2598 return result; |
| 2596 } | 2599 } |
| 2597 | 2600 |
| 2598 void MenuController::HandleMouseLocation(SubmenuView* source, | 2601 void MenuController::HandleMouseLocation(SubmenuView* source, |
| 2599 const gfx::Point& mouse_location) { | 2602 const gfx::Point& mouse_location) { |
| 2600 if (showing_submenu_) | 2603 if (showing_submenu_) |
| 2601 return; | 2604 return; |
| 2602 | 2605 |
| 2603 // Ignore mouse events if we're closing the menu. | 2606 // Ignore mouse events if we're closing the menu. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 2632 SelectionIncrementDirectionType direction) { | 2635 SelectionIncrementDirectionType direction) { |
| 2633 if (!item) | 2636 if (!item) |
| 2634 return; | 2637 return; |
| 2635 SetSelection(item, SELECTION_DEFAULT); | 2638 SetSelection(item, SELECTION_DEFAULT); |
| 2636 View* hot_view = | 2639 View* hot_view = |
| 2637 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN); | 2640 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN); |
| 2638 SetHotTrackedButton(CustomButton::AsCustomButton(hot_view)); | 2641 SetHotTrackedButton(CustomButton::AsCustomButton(hot_view)); |
| 2639 } | 2642 } |
| 2640 | 2643 |
| 2641 void MenuController::SetHotTrackedButton(CustomButton* hot_button) { | 2644 void MenuController::SetHotTrackedButton(CustomButton* hot_button) { |
| 2642 if (hot_button == hot_button_) { | 2645 if (hot_button == pending_state_.hot_button) { |
| 2643 // Hot-tracked state may change outside of the MenuController. Correct it. | 2646 // Hot-tracked state may change outside of the MenuController. Correct it. |
| 2644 if (hot_button && !hot_button->IsHotTracked()) | 2647 if (hot_button && !hot_button->IsHotTracked()) |
| 2645 hot_button->SetHotTracked(true); | 2648 hot_button->SetHotTracked(true); |
| 2646 return; | 2649 return; |
| 2647 } | 2650 } |
| 2648 if (hot_button_) | 2651 if (pending_state_.hot_button) |
| 2649 hot_button_->SetHotTracked(false); | 2652 pending_state_.hot_button->SetHotTracked(false); |
| 2650 hot_button_ = hot_button; | 2653 pending_state_.hot_button = hot_button; |
| 2651 if (hot_button) | 2654 if (hot_button) |
| 2652 hot_button->SetHotTracked(true); | 2655 hot_button->SetHotTracked(true); |
| 2653 } | 2656 } |
| 2654 | 2657 |
| 2655 } // namespace views | 2658 } // namespace views |
| OLD | NEW |