Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Side by Side Diff: views/controls/menu/menu_item_view.cc

Issue 6931039: Add MenuItemView API to add and remove items at a particular index. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed another spurious OVERRIDE. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "grit/app_strings.h" 8 #include "grit/app_strings.h"
9 #include "ui/base/accessibility/accessible_view_state.h" 9 #include "ui/base/accessibility/accessible_view_state.h"
10 #include "ui/base/l10n/l10n_util.h" 10 #include "ui/base/l10n/l10n_util.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 Init(NULL, 0, SUBMENU, delegate); 94 Init(NULL, 0, SUBMENU, delegate);
95 } 95 }
96 96
97 MenuItemView::~MenuItemView() { 97 MenuItemView::~MenuItemView() {
98 // TODO(sky): ownership is bit wrong now. In particular if a nested message 98 // TODO(sky): ownership is bit wrong now. In particular if a nested message
99 // loop is running deletion can't be done, otherwise the stack gets 99 // loop is running deletion can't be done, otherwise the stack gets
100 // thoroughly screwed. The destructor should be made private, and 100 // thoroughly screwed. The destructor should be made private, and
101 // MenuController should be the only place handling deletion of the menu. 101 // MenuController should be the only place handling deletion of the menu.
102 // (57890). 102 // (57890).
103 delete submenu_; 103 delete submenu_;
104 DeleteRemovedItems();
104 } 105 }
105 106
106 bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { 107 bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) {
107 *tooltip = UTF16ToWideHack(tooltip_); 108 *tooltip = UTF16ToWideHack(tooltip_);
108 if (!tooltip->empty()) 109 if (!tooltip->empty())
109 return true; 110 return true;
110 if (GetType() != SEPARATOR) { 111 if (GetType() != SEPARATOR) {
111 gfx::Point location(p); 112 gfx::Point location(p);
112 ConvertPointToScreen(this, &location); 113 ConvertPointToScreen(this, &location);
113 *tooltip = GetDelegate()->GetTooltipText(command_, location); 114 *tooltip = GetDelegate()->GetTooltipText(command_, location);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 controller_->Run(parent, NULL, this, bounds, anchor, NULL); 244 controller_->Run(parent, NULL, this, bounds, anchor, NULL);
244 } 245 }
245 246
246 void MenuItemView::Cancel() { 247 void MenuItemView::Cancel() {
247 if (controller_ && !canceled_) { 248 if (controller_ && !canceled_) {
248 canceled_ = true; 249 canceled_ = true;
249 controller_->Cancel(MenuController::EXIT_ALL); 250 controller_->Cancel(MenuController::EXIT_ALL);
250 } 251 }
251 } 252 }
252 253
254 MenuItemView* MenuItemView::AddMenuItemAt(int index,
255 int item_id,
256 const std::wstring& label,
257 const SkBitmap& icon,
258 Type type) {
259 DCHECK_LE(0, index);
260 if (!submenu_)
261 CreateSubmenu();
262 DCHECK_GE(submenu_->child_count(), index);
263 if (type == SEPARATOR) {
264 submenu_->AddChildViewAt(new MenuSeparator(), index);
265 return NULL;
266 }
267 MenuItemView* item = new MenuItemView(this, item_id, type);
268 if (label.empty() && GetDelegate())
269 item->SetTitle(GetDelegate()->GetLabel(item_id));
270 else
271 item->SetTitle(label);
272 item->SetIcon(icon);
273 if (type == SUBMENU)
274 item->CreateSubmenu();
275 submenu_->AddChildViewAt(item, index);
276 return item;
277 }
278
279 void MenuItemView::RemoveMenuItemAt(int index)
280 {
sky 2011/05/06 16:17:00 { on previous line.
rhashimoto 2011/05/11 00:44:53 Done.
281 DCHECK(submenu_);
282 DCHECK_LE(0, index);
283 DCHECK_GT(submenu_->child_count(), index);
284
285 View* item = submenu_->GetChildViewAt(index);
286 DCHECK(item);
287 submenu_->RemoveChildView(item);
288
289 // RemoveChildView() does not delete the item, which is a good thing
290 // in case a submenu is being displayed while items are being removed.
291 // Deletion will be done in DeleteRemovedItems().
292 removed_items_.push_back(item);
sky 2011/05/06 16:17:00 Why do we need to do this? BookmarkMenuController
rhashimoto 2011/05/11 00:44:53 The use case is for the ChromiumOS network menu wh
293 }
294
253 MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model, 295 MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model,
254 int index, 296 int index,
255 int id) { 297 int id) {
256 SkBitmap icon; 298 SkBitmap icon;
257 bool has_icon = false; 299 bool has_icon = false;
258 std::wstring label; 300 std::wstring label;
259 MenuItemView::Type type; 301 MenuItemView::Type type;
260 ui::MenuModel::ItemType menu_type = model->GetTypeAt(index); 302 ui::MenuModel::ItemType menu_type = model->GetTypeAt(index);
261 switch (menu_type) { 303 switch (menu_type) {
262 case ui::MenuModel::TYPE_COMMAND: 304 case ui::MenuModel::TYPE_COMMAND:
(...skipping 22 matching lines...) Expand all
285 break; 327 break;
286 } 328 }
287 329
288 return AppendMenuItemImpl(id, label, has_icon ? icon : SkBitmap(), type); 330 return AppendMenuItemImpl(id, label, has_icon ? icon : SkBitmap(), type);
289 } 331 }
290 332
291 MenuItemView* MenuItemView::AppendMenuItemImpl(int item_id, 333 MenuItemView* MenuItemView::AppendMenuItemImpl(int item_id,
292 const std::wstring& label, 334 const std::wstring& label,
293 const SkBitmap& icon, 335 const SkBitmap& icon,
294 Type type) { 336 Type type) {
295 if (!submenu_) 337 const int index = submenu_ ? submenu_->child_count() : 0;
296 CreateSubmenu(); 338 return AddMenuItemAt(index, item_id, label, icon, type);
297 if (type == SEPARATOR) {
298 submenu_->AddChildView(new MenuSeparator());
299 return NULL;
300 }
301 MenuItemView* item = new MenuItemView(this, item_id, type);
302 if (label.empty() && GetDelegate())
303 item->SetTitle(GetDelegate()->GetLabel(item_id));
304 else
305 item->SetTitle(label);
306 item->SetIcon(icon);
307 if (type == SUBMENU)
308 item->CreateSubmenu();
309 submenu_->AddChildView(item);
310 return item;
311 } 339 }
312 340
313 SubmenuView* MenuItemView::CreateSubmenu() { 341 SubmenuView* MenuItemView::CreateSubmenu() {
314 if (!submenu_) 342 if (!submenu_)
315 submenu_ = new SubmenuView(this); 343 submenu_ = new SubmenuView(this);
316 return submenu_; 344 return submenu_;
317 } 345 }
318 346
319 bool MenuItemView::HasSubmenu() const { 347 bool MenuItemView::HasSubmenu() const {
320 return (submenu_ != NULL); 348 return (submenu_ != NULL);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 GetMenuItemByID(id); 441 GetMenuItemByID(id);
414 if (result) 442 if (result)
415 return result; 443 return result;
416 } 444 }
417 } 445 }
418 return NULL; 446 return NULL;
419 } 447 }
420 448
421 void MenuItemView::ChildrenChanged() { 449 void MenuItemView::ChildrenChanged() {
422 MenuController* controller = GetMenuController(); 450 MenuController* controller = GetMenuController();
423 if (!controller) 451 if (controller) {
424 return; // We're not showing, nothing to do. 452 // Handles the case where we were empty and are no longer empty.
453 RemoveEmptyMenus();
425 454
426 // Handles the case where we were empty and are no longer empty. 455 // Handles the case where we were not empty, but now are.
427 RemoveEmptyMenus(); 456 AddEmptyMenus();
428 457
429 // Handles the case where we were not empty, but now are. 458 controller->MenuChildrenChanged(this);
430 AddEmptyMenus();
431 459
432 controller->MenuChildrenChanged(this); 460 if (submenu_) {
461 // Force a paint and layout. This handles the case of the top
462 // level window's size remaining the same, resulting in no
463 // change to the submenu's size and no layout.
464 submenu_->Layout();
465 submenu_->SchedulePaint();
466 }
467 }
433 468
434 if (submenu_) { 469 DeleteRemovedItems();
435 // Force a paint and layout. This handles the case of the top level window's
436 // size remaining the same, resulting in no change to the submenu's size and
437 // no layout.
438 submenu_->Layout();
439 submenu_->SchedulePaint();
440 }
441 } 470 }
442 471
443 void MenuItemView::Layout() { 472 void MenuItemView::Layout() {
444 if (!has_children()) 473 if (!has_children())
445 return; 474 return;
446 475
447 // Child views are laid out right aligned and given the full height. To right 476 // Child views are laid out right aligned and given the full height. To right
448 // align start with the last view and progress to the first. 477 // align start with the last view and progress to the first.
449 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0; 478 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0;
450 --i) { 479 --i) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 return width; 711 return width;
683 } 712 }
684 713
685 string16 MenuItemView::GetAcceleratorText() { 714 string16 MenuItemView::GetAcceleratorText() {
686 Accelerator accelerator; 715 Accelerator accelerator;
687 return (GetDelegate() && 716 return (GetDelegate() &&
688 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? 717 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ?
689 accelerator.GetShortcutText() : string16(); 718 accelerator.GetShortcutText() : string16();
690 } 719 }
691 720
721 void MenuItemView::DeleteRemovedItems() {
722 for (size_t i = 0; i < removed_items_.size(); ++i)
sky 2011/05/06 16:17:00 STLDeleteElements in each place instead of this me
rhashimoto 2011/05/11 00:44:53 Done.
723 delete removed_items_[i];
724 removed_items_.clear();
725 }
726
692 } // namespace views 727 } // namespace views
OLDNEW
« views/controls/menu/menu_item_view.h ('K') | « views/controls/menu/menu_item_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698