| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "views/controls/menu/menu_item_view.h" | 5 #include "views/controls/menu/menu_item_view.h" |
| 6 | 6 |
| 7 #include "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
| 8 #include "app/l10n_util.h" | 8 #include "app/l10n_util.h" |
| 9 #include "grit/app_strings.h" | 9 #include "grit/app_strings.h" |
| 10 #include "views/controls/menu/menu_config.h" | 10 #include "views/controls/menu/menu_config.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // static | 59 // static |
| 60 int MenuItemView::pref_menu_height_; | 60 int MenuItemView::pref_menu_height_; |
| 61 | 61 |
| 62 MenuItemView::MenuItemView(MenuDelegate* delegate) { | 62 MenuItemView::MenuItemView(MenuDelegate* delegate) { |
| 63 // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes supplies a | 63 // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes supplies a |
| 64 // NULL delegate. | 64 // NULL delegate. |
| 65 Init(NULL, 0, SUBMENU, delegate); | 65 Init(NULL, 0, SUBMENU, delegate); |
| 66 } | 66 } |
| 67 | 67 |
| 68 MenuItemView::~MenuItemView() { | 68 MenuItemView::~MenuItemView() { |
| 69 if (controller_) { | 69 // TODO(sky): ownership is bit wrong now. In particular if a nested message |
| 70 // We're currently showing. | 70 // loop is running deletion can't be done, otherwise the stack gets |
| 71 | 71 // thoroughly screwed. The destructor should be made private, and |
| 72 // We can't delete ourselves while we're blocking. | 72 // MenuController should be the only place handling deletion of the menu. |
| 73 DCHECK(!controller_->IsBlockingRun()); | |
| 74 | |
| 75 // Invoking Cancel is going to call us back and notify the delegate. | |
| 76 // Notifying the delegate from the destructor can be problematic. To avoid | |
| 77 // this the delegate is set to NULL. | |
| 78 delegate_ = NULL; | |
| 79 | |
| 80 controller_->Cancel(true); | |
| 81 } | |
| 82 delete submenu_; | 73 delete submenu_; |
| 83 } | 74 } |
| 84 | 75 |
| 85 void MenuItemView::RunMenuAt(gfx::NativeWindow parent, | 76 void MenuItemView::RunMenuAt(gfx::NativeWindow parent, |
| 77 MenuButton* button, |
| 86 const gfx::Rect& bounds, | 78 const gfx::Rect& bounds, |
| 87 AnchorPosition anchor, | 79 AnchorPosition anchor, |
| 88 bool has_mnemonics) { | 80 bool has_mnemonics) { |
| 89 PrepareForRun(has_mnemonics); | 81 PrepareForRun(has_mnemonics); |
| 90 | 82 |
| 91 int mouse_event_flags; | 83 int mouse_event_flags; |
| 92 | 84 |
| 93 MenuController* controller = MenuController::GetActiveInstance(); | 85 MenuController* controller = MenuController::GetActiveInstance(); |
| 94 if (controller && !controller->IsBlockingRun()) { | 86 if (controller && !controller->IsBlockingRun()) { |
| 95 // A menu is already showing, but it isn't a blocking menu. Cancel it. | 87 // A menu is already showing, but it isn't a blocking menu. Cancel it. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 108 // A menu is already showing, use the same controller. | 100 // A menu is already showing, use the same controller. |
| 109 | 101 |
| 110 // Don't support blocking from within non-blocking. | 102 // Don't support blocking from within non-blocking. |
| 111 DCHECK(controller->IsBlockingRun()); | 103 DCHECK(controller->IsBlockingRun()); |
| 112 } | 104 } |
| 113 | 105 |
| 114 controller_ = controller; | 106 controller_ = controller; |
| 115 | 107 |
| 116 // Run the loop. | 108 // Run the loop. |
| 117 MenuItemView* result = | 109 MenuItemView* result = |
| 118 controller->Run(parent, this, bounds, anchor, &mouse_event_flags); | 110 controller->Run(parent, button, this, bounds, anchor, &mouse_event_flags); |
| 119 | 111 |
| 120 RemoveEmptyMenus(); | 112 RemoveEmptyMenus(); |
| 121 | 113 |
| 122 controller_ = NULL; | 114 controller_ = NULL; |
| 123 | 115 |
| 124 if (owns_controller) { | 116 if (owns_controller) { |
| 125 // We created the controller and need to delete it. | 117 // We created the controller and need to delete it. |
| 126 if (MenuController::GetActiveInstance() == controller) | 118 if (MenuController::GetActiveInstance() == controller) |
| 127 MenuController::SetActiveInstance(NULL); | 119 MenuController::SetActiveInstance(NULL); |
| 128 delete controller; | 120 delete controller; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 144 if (current_controller) { | 136 if (current_controller) { |
| 145 current_controller->Cancel(true); | 137 current_controller->Cancel(true); |
| 146 } | 138 } |
| 147 | 139 |
| 148 // Always create a new controller for non-blocking. | 140 // Always create a new controller for non-blocking. |
| 149 controller_ = new MenuController(false); | 141 controller_ = new MenuController(false); |
| 150 | 142 |
| 151 // Set the instance, that way it can be canceled by another menu. | 143 // Set the instance, that way it can be canceled by another menu. |
| 152 MenuController::SetActiveInstance(controller_); | 144 MenuController::SetActiveInstance(controller_); |
| 153 | 145 |
| 154 controller_->Run(parent, this, bounds, anchor, NULL); | 146 controller_->Run(parent, NULL, this, bounds, anchor, NULL); |
| 155 } | 147 } |
| 156 | 148 |
| 157 void MenuItemView::Cancel() { | 149 void MenuItemView::Cancel() { |
| 158 if (controller_ && !canceled_) { | 150 if (controller_ && !canceled_) { |
| 159 canceled_ = true; | 151 canceled_ = true; |
| 160 controller_->Cancel(true); | 152 controller_->Cancel(true); |
| 161 } | 153 } |
| 162 } | 154 } |
| 163 | 155 |
| 164 SubmenuView* MenuItemView::CreateSubmenu() { | 156 SubmenuView* MenuItemView::CreateSubmenu() { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 // Our delegate is null when invoked from the destructor. | 322 // Our delegate is null when invoked from the destructor. |
| 331 delegate_->DropMenuClosed(this); | 323 delegate_->DropMenuClosed(this); |
| 332 } | 324 } |
| 333 // WARNING: its possible the delegate deleted us at this point. | 325 // WARNING: its possible the delegate deleted us at this point. |
| 334 } | 326 } |
| 335 | 327 |
| 336 void MenuItemView::PrepareForRun(bool has_mnemonics) { | 328 void MenuItemView::PrepareForRun(bool has_mnemonics) { |
| 337 // Currently we only support showing the root. | 329 // Currently we only support showing the root. |
| 338 DCHECK(!parent_menu_item_); | 330 DCHECK(!parent_menu_item_); |
| 339 | 331 |
| 340 // Don't invoke run from within run on the same menu. | |
| 341 DCHECK(!controller_); | |
| 342 | |
| 343 // Force us to have a submenu. | 332 // Force us to have a submenu. |
| 344 CreateSubmenu(); | 333 CreateSubmenu(); |
| 345 | 334 |
| 346 canceled_ = false; | 335 canceled_ = false; |
| 347 | 336 |
| 348 has_mnemonics_ = has_mnemonics; | 337 has_mnemonics_ = has_mnemonics; |
| 349 | 338 |
| 350 AddEmptyMenus(); | 339 AddEmptyMenus(); |
| 351 | 340 |
| 352 if (!MenuController::GetActiveInstance()) { | 341 if (!MenuController::GetActiveInstance()) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 415 } |
| 427 | 416 |
| 428 int MenuItemView::GetBottomMargin() { | 417 int MenuItemView::GetBottomMargin() { |
| 429 MenuItemView* root = GetRootMenuItem(); | 418 MenuItemView* root = GetRootMenuItem(); |
| 430 return root && root->has_icons_ | 419 return root && root->has_icons_ |
| 431 ? MenuConfig::instance().item_bottom_margin : | 420 ? MenuConfig::instance().item_bottom_margin : |
| 432 MenuConfig::instance().item_no_icon_bottom_margin; | 421 MenuConfig::instance().item_no_icon_bottom_margin; |
| 433 } | 422 } |
| 434 | 423 |
| 435 } // namespace views | 424 } // namespace views |
| OLD | NEW |