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 #if defined(OS_WIN) |
| 8 #include <windowsx.h> |
| 9 #endif |
| 10 |
7 #include "base/i18n/case_conversion.h" | 11 #include "base/i18n/case_conversion.h" |
8 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
9 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
10 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
11 #include "base/time.h" | 15 #include "base/time.h" |
12 #include "ui/base/dragdrop/drag_utils.h" | 16 #include "ui/base/dragdrop/drag_utils.h" |
13 #include "ui/base/dragdrop/os_exchange_data.h" | 17 #include "ui/base/dragdrop/os_exchange_data.h" |
14 #include "ui/base/events/event_constants.h" | 18 #include "ui/base/events/event_constants.h" |
15 #include "ui/base/events/event_utils.h" | 19 #include "ui/base/events/event_utils.h" |
16 #include "ui/base/keycodes/keyboard_codes.h" | 20 #include "ui/base/keycodes/keyboard_codes.h" |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 if (event.IsRightMouseButton() && part.type == MenuPart::MENU_ITEM) { | 487 if (event.IsRightMouseButton() && part.type == MenuPart::MENU_ITEM) { |
484 MenuItemView* menu = part.menu; | 488 MenuItemView* menu = part.menu; |
485 // |menu| is NULL means this event is from an empty menu or a separator. | 489 // |menu| is NULL means this event is from an empty menu or a separator. |
486 // If it is from an empty menu, use parent context menu instead of that. | 490 // If it is from an empty menu, use parent context menu instead of that. |
487 if (menu == NULL && | 491 if (menu == NULL && |
488 part.submenu->child_count() == 1 && | 492 part.submenu->child_count() == 1 && |
489 part.submenu->child_at(0)->id() | 493 part.submenu->child_at(0)->id() |
490 == views::MenuItemView::kEmptyMenuItemViewID) | 494 == views::MenuItemView::kEmptyMenuItemViewID) |
491 menu = part.parent; | 495 menu = part.parent; |
492 | 496 |
493 if (menu != NULL && ShowContextMenu(menu, source, event)) | 497 if (menu != NULL && ShowContextMenu(menu, source, event, |
| 498 ui::MENU_SOURCE_MOUSE)) |
494 return; | 499 return; |
495 } | 500 } |
496 | 501 |
497 // We can use Ctrl+click or the middle mouse button to recursively open urls | 502 // We can use Ctrl+click or the middle mouse button to recursively open urls |
498 // for selected folder menu items. If it's only a left click, show the | 503 // for selected folder menu items. If it's only a left click, show the |
499 // contents of the folder. | 504 // contents of the folder. |
500 if (!part.is_scroll() && part.menu && | 505 if (!part.is_scroll() && part.menu && |
501 !(part.menu->HasSubmenu() && | 506 !(part.menu->HasSubmenu() && |
502 (event.flags() & ui::EF_LEFT_MOUSE_BUTTON))) { | 507 (event.flags() & ui::EF_LEFT_MOUSE_BUTTON))) { |
503 if (active_mouse_view_) { | 508 if (active_mouse_view_) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 #endif | 552 #endif |
548 | 553 |
549 void MenuController::OnGestureEvent(SubmenuView* source, | 554 void MenuController::OnGestureEvent(SubmenuView* source, |
550 ui::GestureEvent* event) { | 555 ui::GestureEvent* event) { |
551 MenuPart part = GetMenuPart(source, event->location()); | 556 MenuPart part = GetMenuPart(source, event->location()); |
552 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { | 557 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { |
553 SetSelectionOnPointerDown(source, *event); | 558 SetSelectionOnPointerDown(source, *event); |
554 event->StopPropagation(); | 559 event->StopPropagation(); |
555 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) { | 560 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) { |
556 if (part.type == MenuPart::MENU_ITEM && part.menu) { | 561 if (part.type == MenuPart::MENU_ITEM && part.menu) { |
557 if (ShowContextMenu(part.menu, source, *event)) | 562 if (ShowContextMenu(part.menu, source, *event, ui::MENU_SOURCE_TOUCH)) |
558 event->StopPropagation(); | 563 event->StopPropagation(); |
559 } | 564 } |
560 } else if (event->type() == ui::ET_GESTURE_TAP) { | 565 } else if (event->type() == ui::ET_GESTURE_TAP) { |
561 if (!part.is_scroll() && part.menu && | 566 if (!part.is_scroll() && part.menu && |
562 !(part.menu->HasSubmenu())) { | 567 !(part.menu->HasSubmenu())) { |
563 if (part.menu->GetDelegate()->IsTriggerableEvent( | 568 if (part.menu->GetDelegate()->IsTriggerableEvent( |
564 part.menu, *event)) { | 569 part.menu, *event)) { |
565 Accept(part.menu, event->flags()); | 570 Accept(part.menu, event->flags()); |
566 } | 571 } |
567 event->StopPropagation(); | 572 event->StopPropagation(); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 return false; | 955 return false; |
951 } | 956 } |
952 | 957 |
953 // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. | 958 // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. |
954 switch (msg.message) { | 959 switch (msg.message) { |
955 case WM_CONTEXTMENU: { | 960 case WM_CONTEXTMENU: { |
956 MenuItemView* item = pending_state_.item; | 961 MenuItemView* item = pending_state_.item; |
957 if (item && item->GetRootMenuItem() != item) { | 962 if (item && item->GetRootMenuItem() != item) { |
958 gfx::Point screen_loc(0, item->height()); | 963 gfx::Point screen_loc(0, item->height()); |
959 View::ConvertPointToScreen(item, &screen_loc); | 964 View::ConvertPointToScreen(item, &screen_loc); |
| 965 ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; |
| 966 if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1) |
| 967 source_type = ui::MENU_SOURCE_KEYBOARD; |
960 item->GetDelegate()->ShowContextMenu(item, item->GetCommand(), | 968 item->GetDelegate()->ShowContextMenu(item, item->GetCommand(), |
961 screen_loc, false); | 969 screen_loc, source_type); |
962 } | 970 } |
963 return true; | 971 return true; |
964 } | 972 } |
965 | 973 |
966 // NOTE: focus wasn't changed when the menu was shown. As such, don't | 974 // NOTE: focus wasn't changed when the menu was shown. As such, don't |
967 // dispatch key events otherwise the focused window will get the events. | 975 // dispatch key events otherwise the focused window will get the events. |
968 case WM_KEYDOWN: { | 976 case WM_KEYDOWN: { |
969 bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); | 977 bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); |
970 TranslateMessage(&msg); | 978 TranslateMessage(&msg); |
971 return result; | 979 return result; |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 alt_menu->PrepareForRun( | 1271 alt_menu->PrepareForRun( |
1264 false, has_mnemonics, | 1272 false, has_mnemonics, |
1265 source->GetMenuItem()->GetRootMenuItem()->show_mnemonics_); | 1273 source->GetMenuItem()->GetRootMenuItem()->show_mnemonics_); |
1266 alt_menu->controller_ = this; | 1274 alt_menu->controller_ = this; |
1267 SetSelection(alt_menu, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); | 1275 SetSelection(alt_menu, SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
1268 return true; | 1276 return true; |
1269 } | 1277 } |
1270 | 1278 |
1271 bool MenuController::ShowContextMenu(MenuItemView* menu_item, | 1279 bool MenuController::ShowContextMenu(MenuItemView* menu_item, |
1272 SubmenuView* source, | 1280 SubmenuView* source, |
1273 const ui::LocatedEvent& event) { | 1281 const ui::LocatedEvent& event, |
| 1282 ui::MenuSourceType source_type) { |
1274 // Set the selection immediately, making sure the submenu is only open | 1283 // Set the selection immediately, making sure the submenu is only open |
1275 // if it already was. | 1284 // if it already was. |
1276 int selection_types = SELECTION_UPDATE_IMMEDIATELY; | 1285 int selection_types = SELECTION_UPDATE_IMMEDIATELY; |
1277 if (state_.item == pending_state_.item && state_.submenu_open) | 1286 if (state_.item == pending_state_.item && state_.submenu_open) |
1278 selection_types |= SELECTION_OPEN_SUBMENU; | 1287 selection_types |= SELECTION_OPEN_SUBMENU; |
1279 SetSelection(pending_state_.item, selection_types); | 1288 SetSelection(pending_state_.item, selection_types); |
1280 gfx::Point loc(event.location()); | 1289 gfx::Point loc(event.location()); |
1281 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); | 1290 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc); |
1282 | 1291 |
1283 if (menu_item->GetDelegate()->ShowContextMenu( | 1292 if (menu_item->GetDelegate()->ShowContextMenu( |
1284 menu_item, menu_item->GetCommand(), loc, true)) { | 1293 menu_item, menu_item->GetCommand(), loc, source_type)) { |
1285 SendMouseCaptureLostToActiveView(); | 1294 SendMouseCaptureLostToActiveView(); |
1286 return true; | 1295 return true; |
1287 } | 1296 } |
1288 return false; | 1297 return false; |
1289 } | 1298 } |
1290 | 1299 |
1291 void MenuController::CloseAllNestedMenus() { | 1300 void MenuController::CloseAllNestedMenus() { |
1292 for (std::list<State>::iterator i = menu_stack_.begin(); | 1301 for (std::list<State>::iterator i = menu_stack_.begin(); |
1293 i != menu_stack_.end(); ++i) { | 1302 i != menu_stack_.end(); ++i) { |
1294 MenuItemView* last_item = i->item; | 1303 MenuItemView* last_item = i->item; |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 (!pending_state_.item->HasSubmenu() || | 2294 (!pending_state_.item->HasSubmenu() || |
2286 !pending_state_.item->GetSubmenu()->IsShowing())) { | 2295 !pending_state_.item->GetSubmenu()->IsShowing())) { |
2287 // On exit if the user hasn't selected an item with a submenu, move the | 2296 // On exit if the user hasn't selected an item with a submenu, move the |
2288 // selection back to the parent menu item. | 2297 // selection back to the parent menu item. |
2289 SetSelection(pending_state_.item->GetParentMenuItem(), | 2298 SetSelection(pending_state_.item->GetParentMenuItem(), |
2290 SELECTION_OPEN_SUBMENU); | 2299 SELECTION_OPEN_SUBMENU); |
2291 } | 2300 } |
2292 } | 2301 } |
2293 | 2302 |
2294 } // namespace views | 2303 } // namespace views |
OLD | NEW |