| 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 | |
| 61 namespace views { | 56 namespace views { |
| 62 | 57 |
| 63 namespace { | 58 namespace { |
| 64 | 59 |
| 65 // The spacing offset for the bubble tip. | 60 // The spacing offset for the bubble tip. |
| 66 const int kBubbleTipSizeLeftRight = 12; | 61 const int kBubbleTipSizeLeftRight = 12; |
| 67 const int kBubbleTipSizeTopBottom = 11; | 62 const int kBubbleTipSizeTopBottom = 11; |
| 68 | 63 |
| 69 // Returns true if the mnemonic of |menu| matches key. | 64 // Returns true if the mnemonic of |menu| matches key. |
| 70 bool MatchesMnemonic(MenuItemView* menu, char16 key) { | 65 bool MatchesMnemonic(MenuItemView* menu, char16 key) { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 MenuButton* button, | 279 MenuButton* button, |
| 285 MenuItemView* root, | 280 MenuItemView* root, |
| 286 const gfx::Rect& bounds, | 281 const gfx::Rect& bounds, |
| 287 MenuItemView::AnchorPosition position, | 282 MenuItemView::AnchorPosition position, |
| 288 bool context_menu, | 283 bool context_menu, |
| 289 int* result_event_flags) { | 284 int* result_event_flags) { |
| 290 exit_type_ = EXIT_NONE; | 285 exit_type_ = EXIT_NONE; |
| 291 possible_drag_ = false; | 286 possible_drag_ = false; |
| 292 drag_in_progress_ = false; | 287 drag_in_progress_ = false; |
| 293 closing_event_time_ = base::TimeDelta(); | 288 closing_event_time_ = base::TimeDelta(); |
| 294 menu_start_time_ = base::TimeTicks::Now(); | |
| 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); | |
| 301 | 289 |
| 302 bool nested_menu = showing_; | 290 bool nested_menu = showing_; |
| 303 if (showing_) { | 291 if (showing_) { |
| 304 // Only support nesting of blocking_run menus, nesting of | 292 // Only support nesting of blocking_run menus, nesting of |
| 305 // blocking/non-blocking shouldn't be needed. | 293 // blocking/non-blocking shouldn't be needed. |
| 306 DCHECK(blocking_run_); | 294 DCHECK(blocking_run_); |
| 307 | 295 |
| 308 // We're already showing, push the current state. | 296 // We're already showing, push the current state. |
| 309 menu_stack_.push_back(state_); | 297 menu_stack_.push_back(state_); |
| 310 | 298 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 return; | 489 return; |
| 502 } | 490 } |
| 503 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu( | 491 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu( |
| 504 part.menu->GetCommand(), event)) { | 492 part.menu->GetCommand(), event)) { |
| 505 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(), | 493 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(), |
| 506 event.flags()); | 494 event.flags()); |
| 507 return; | 495 return; |
| 508 } | 496 } |
| 509 if (!part.menu->NonIconChildViewsCount() && | 497 if (!part.menu->NonIconChildViewsCount() && |
| 510 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) { | 498 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) { |
| 511 int64 time_since_menu_start = | 499 Accept(part.menu, event.flags()); |
| 512 (base::TimeTicks::Now() - menu_start_time_).InMilliseconds(); | |
| 513 if (!state_.context_menu || !View::ShouldShowContextMenuOnMousePress() || | |
| 514 time_since_menu_start > kContextMenuSelectionHoldTimeMs) | |
| 515 Accept(part.menu, event.flags()); | |
| 516 return; | 500 return; |
| 517 } | 501 } |
| 518 } else if (part.type == MenuPart::MENU_ITEM) { | 502 } else if (part.type == MenuPart::MENU_ITEM) { |
| 519 // User either clicked on empty space, or a menu that has children. | 503 // User either clicked on empty space, or a menu that has children. |
| 520 SetSelection(part.menu ? part.menu : state_.item, | 504 SetSelection(part.menu ? part.menu : state_.item, |
| 521 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); | 505 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); |
| 522 } | 506 } |
| 523 SendMouseCaptureLostToActiveView(); | 507 SendMouseCaptureLostToActiveView(); |
| 524 } | 508 } |
| 525 | 509 |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 possible_drag_(false), | 1086 possible_drag_(false), |
| 1103 drag_in_progress_(false), | 1087 drag_in_progress_(false), |
| 1104 valid_drop_coordinates_(false), | 1088 valid_drop_coordinates_(false), |
| 1105 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), | 1089 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), |
| 1106 showing_submenu_(false), | 1090 showing_submenu_(false), |
| 1107 menu_button_(NULL), | 1091 menu_button_(NULL), |
| 1108 active_mouse_view_(NULL), | 1092 active_mouse_view_(NULL), |
| 1109 delegate_(delegate), | 1093 delegate_(delegate), |
| 1110 message_loop_depth_(0), | 1094 message_loop_depth_(0), |
| 1111 menu_config_(theme), | 1095 menu_config_(theme), |
| 1112 closing_event_time_(base::TimeDelta()), | 1096 closing_event_time_(base::TimeDelta()) { |
| 1113 menu_start_time_(base::TimeTicks()) { | |
| 1114 active_instance_ = this; | 1097 active_instance_ = this; |
| 1115 } | 1098 } |
| 1116 | 1099 |
| 1117 MenuController::~MenuController() { | 1100 MenuController::~MenuController() { |
| 1118 DCHECK(!showing_); | 1101 DCHECK(!showing_); |
| 1119 if (owner_) | 1102 if (owner_) |
| 1120 owner_->RemoveObserver(this); | 1103 owner_->RemoveObserver(this); |
| 1121 if (active_instance_ == this) | 1104 if (active_instance_ == this) |
| 1122 active_instance_ = NULL; | 1105 active_instance_ = NULL; |
| 1123 StopShowTimer(); | 1106 StopShowTimer(); |
| (...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 (!pending_state_.item->HasSubmenu() || | 2253 (!pending_state_.item->HasSubmenu() || |
| 2271 !pending_state_.item->GetSubmenu()->IsShowing())) { | 2254 !pending_state_.item->GetSubmenu()->IsShowing())) { |
| 2272 // On exit if the user hasn't selected an item with a submenu, move the | 2255 // On exit if the user hasn't selected an item with a submenu, move the |
| 2273 // selection back to the parent menu item. | 2256 // selection back to the parent menu item. |
| 2274 SetSelection(pending_state_.item->GetParentMenuItem(), | 2257 SetSelection(pending_state_.item->GetParentMenuItem(), |
| 2275 SELECTION_OPEN_SUBMENU); | 2258 SELECTION_OPEN_SUBMENU); |
| 2276 } | 2259 } |
| 2277 } | 2260 } |
| 2278 | 2261 |
| 2279 } // namespace views | 2262 } // namespace views |
| OLD | NEW |