| 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 |