| 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/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 // Period of the scroll timer (in milliseconds). | 46 // Period of the scroll timer (in milliseconds). |
| 47 static const int kScrollTimerMS = 30; | 47 static const int kScrollTimerMS = 30; |
| 48 | 48 |
| 49 // Amount of time from when the drop exits the menu and the menu is hidden. | 49 // Amount of time from when the drop exits the menu and the menu is hidden. |
| 50 static const int kCloseOnExitTime = 1200; | 50 static const int kCloseOnExitTime = 1200; |
| 51 | 51 |
| 52 // If a context menu is invoked by touch, we shift the menu by this offset so | 52 // If a context menu is invoked by touch, we shift the menu by this offset so |
| 53 // that the finger does not obscure the menu. | 53 // that the finger does not obscure the menu. |
| 54 static const int kCenteredContextMenuYOffset = -15; | 54 static const int kCenteredContextMenuYOffset = -15; |
| 55 | 55 |
| 56 // When showing context menu on mouse down, the user might accidentally select |
| 57 // the menu item on the subsequent mouse up. To prevent this, we add the |
| 58 // following delay before the user is able to select an item. |
| 59 static const int kContextMenuSelectionHoldTimeMs = 200; |
| 60 |
| 56 namespace views { | 61 namespace views { |
| 57 | 62 |
| 58 namespace { | 63 namespace { |
| 59 | 64 |
| 60 // The spacing offset for the bubble tip. | 65 // The spacing offset for the bubble tip. |
| 61 const int kBubbleTipSizeLeftRight = 12; | 66 const int kBubbleTipSizeLeftRight = 12; |
| 62 const int kBubbleTipSizeTopBottom = 11; | 67 const int kBubbleTipSizeTopBottom = 11; |
| 63 | 68 |
| 64 // Returns true if the mnemonic of |menu| matches key. | 69 // Returns true if the mnemonic of |menu| matches key. |
| 65 bool MatchesMnemonic(MenuItemView* menu, char16 key) { | 70 bool MatchesMnemonic(MenuItemView* menu, char16 key) { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 MenuButton* button, | 284 MenuButton* button, |
| 280 MenuItemView* root, | 285 MenuItemView* root, |
| 281 const gfx::Rect& bounds, | 286 const gfx::Rect& bounds, |
| 282 MenuItemView::AnchorPosition position, | 287 MenuItemView::AnchorPosition position, |
| 283 bool context_menu, | 288 bool context_menu, |
| 284 int* result_event_flags) { | 289 int* result_event_flags) { |
| 285 exit_type_ = EXIT_NONE; | 290 exit_type_ = EXIT_NONE; |
| 286 possible_drag_ = false; | 291 possible_drag_ = false; |
| 287 drag_in_progress_ = false; | 292 drag_in_progress_ = false; |
| 288 closing_event_time_ = base::TimeDelta(); | 293 closing_event_time_ = base::TimeDelta(); |
| 294 menu_start_time_ = ui::EventTimeForNow(); |
| 295 |
| 296 // If we are shown on mouse press, we will eat the subsequent mouse down and |
| 297 // the parent widget will not be able to reset its state (it might have mouse |
| 298 // capture from the mouse down). So we clear its state here. |
| 299 if (parent && parent->GetRootView()) |
| 300 parent->GetRootView()->SetMouseHandler(NULL); |
| 289 | 301 |
| 290 bool nested_menu = showing_; | 302 bool nested_menu = showing_; |
| 291 if (showing_) { | 303 if (showing_) { |
| 292 // Only support nesting of blocking_run menus, nesting of | 304 // Only support nesting of blocking_run menus, nesting of |
| 293 // blocking/non-blocking shouldn't be needed. | 305 // blocking/non-blocking shouldn't be needed. |
| 294 DCHECK(blocking_run_); | 306 DCHECK(blocking_run_); |
| 295 | 307 |
| 296 // We're already showing, push the current state. | 308 // We're already showing, push the current state. |
| 297 menu_stack_.push_back(state_); | 309 menu_stack_.push_back(state_); |
| 298 | 310 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 return; | 501 return; |
| 490 } | 502 } |
| 491 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu( | 503 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu( |
| 492 part.menu->GetCommand(), event)) { | 504 part.menu->GetCommand(), event)) { |
| 493 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(), | 505 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(), |
| 494 event.flags()); | 506 event.flags()); |
| 495 return; | 507 return; |
| 496 } | 508 } |
| 497 if (!part.menu->NonIconChildViewsCount() && | 509 if (!part.menu->NonIconChildViewsCount() && |
| 498 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) { | 510 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) { |
| 499 Accept(part.menu, event.flags()); | 511 int64 time_since_menu_start = |
| 512 (ui::EventTimeForNow() - menu_start_time_).InMilliseconds(); |
| 513 if (!state_.context_menu || !View::ShouldShowContextMenuOnMousePress() || |
| 514 time_since_menu_start > kContextMenuSelectionHoldTimeMs) |
| 515 Accept(part.menu, event.flags()); |
| 500 return; | 516 return; |
| 501 } | 517 } |
| 502 } else if (part.type == MenuPart::MENU_ITEM) { | 518 } else if (part.type == MenuPart::MENU_ITEM) { |
| 503 // User either clicked on empty space, or a menu that has children. | 519 // User either clicked on empty space, or a menu that has children. |
| 504 SetSelection(part.menu ? part.menu : state_.item, | 520 SetSelection(part.menu ? part.menu : state_.item, |
| 505 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); | 521 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
| 506 } | 522 } |
| 507 SendMouseCaptureLostToActiveView(); | 523 SendMouseCaptureLostToActiveView(); |
| 508 } | 524 } |
| 509 | 525 |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 possible_drag_(false), | 1102 possible_drag_(false), |
| 1087 drag_in_progress_(false), | 1103 drag_in_progress_(false), |
| 1088 valid_drop_coordinates_(false), | 1104 valid_drop_coordinates_(false), |
| 1089 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), | 1105 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), |
| 1090 showing_submenu_(false), | 1106 showing_submenu_(false), |
| 1091 menu_button_(NULL), | 1107 menu_button_(NULL), |
| 1092 active_mouse_view_(NULL), | 1108 active_mouse_view_(NULL), |
| 1093 delegate_(delegate), | 1109 delegate_(delegate), |
| 1094 message_loop_depth_(0), | 1110 message_loop_depth_(0), |
| 1095 menu_config_(theme), | 1111 menu_config_(theme), |
| 1096 closing_event_time_(base::TimeDelta()) { | 1112 closing_event_time_(base::TimeDelta()), |
| 1113 menu_start_time_(base::TimeDelta()) { |
| 1097 active_instance_ = this; | 1114 active_instance_ = this; |
| 1098 } | 1115 } |
| 1099 | 1116 |
| 1100 MenuController::~MenuController() { | 1117 MenuController::~MenuController() { |
| 1101 DCHECK(!showing_); | 1118 DCHECK(!showing_); |
| 1102 if (owner_) | 1119 if (owner_) |
| 1103 owner_->RemoveObserver(this); | 1120 owner_->RemoveObserver(this); |
| 1104 if (active_instance_ == this) | 1121 if (active_instance_ == this) |
| 1105 active_instance_ = NULL; | 1122 active_instance_ = NULL; |
| 1106 StopShowTimer(); | 1123 StopShowTimer(); |
| (...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2253 (!pending_state_.item->HasSubmenu() || | 2270 (!pending_state_.item->HasSubmenu() || |
| 2254 !pending_state_.item->GetSubmenu()->IsShowing())) { | 2271 !pending_state_.item->GetSubmenu()->IsShowing())) { |
| 2255 // On exit if the user hasn't selected an item with a submenu, move the | 2272 // On exit if the user hasn't selected an item with a submenu, move the |
| 2256 // selection back to the parent menu item. | 2273 // selection back to the parent menu item. |
| 2257 SetSelection(pending_state_.item->GetParentMenuItem(), | 2274 SetSelection(pending_state_.item->GetParentMenuItem(), |
| 2258 SELECTION_OPEN_SUBMENU); | 2275 SELECTION_OPEN_SUBMENU); |
| 2259 } | 2276 } |
| 2260 } | 2277 } |
| 2261 | 2278 |
| 2262 } // namespace views | 2279 } // namespace views |
| OLD | NEW |