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

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: Rebase to trunk. 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/i18n/case_conversion.h" 7 #include "base/i18n/case_conversion.h"
8 #include "base/stl_util-inl.h"
8 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
9 #include "grit/app_strings.h" 10 #include "grit/app_strings.h"
10 #include "ui/base/accessibility/accessible_view_state.h" 11 #include "ui/base/accessibility/accessible_view_state.h"
11 #include "ui/base/l10n/l10n_util.h" 12 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/base/models/menu_model.h" 13 #include "ui/base/models/menu_model.h"
13 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
14 #include "views/controls/button/text_button.h" 15 #include "views/controls/button/text_button.h"
15 #include "views/controls/button/menu_button.h" 16 #include "views/controls/button/menu_button.h"
16 #include "views/controls/menu/menu_config.h" 17 #include "views/controls/menu/menu_config.h"
17 #include "views/controls/menu/menu_controller.h" 18 #include "views/controls/menu/menu_controller.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 Init(NULL, 0, SUBMENU, delegate); 96 Init(NULL, 0, SUBMENU, delegate);
96 } 97 }
97 98
98 MenuItemView::~MenuItemView() { 99 MenuItemView::~MenuItemView() {
99 // TODO(sky): ownership is bit wrong now. In particular if a nested message 100 // TODO(sky): ownership is bit wrong now. In particular if a nested message
100 // loop is running deletion can't be done, otherwise the stack gets 101 // loop is running deletion can't be done, otherwise the stack gets
101 // thoroughly screwed. The destructor should be made private, and 102 // thoroughly screwed. The destructor should be made private, and
102 // MenuController should be the only place handling deletion of the menu. 103 // MenuController should be the only place handling deletion of the menu.
103 // (57890). 104 // (57890).
104 delete submenu_; 105 delete submenu_;
106 STLDeleteElements(&removed_items_);
105 } 107 }
106 108
107 bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { 109 bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) {
108 *tooltip = UTF16ToWideHack(tooltip_); 110 *tooltip = UTF16ToWideHack(tooltip_);
109 if (!tooltip->empty()) 111 if (!tooltip->empty())
110 return true; 112 return true;
111 if (GetType() != SEPARATOR) { 113 if (GetType() != SEPARATOR) {
112 gfx::Point location(p); 114 gfx::Point location(p);
113 ConvertPointToScreen(this, &location); 115 ConvertPointToScreen(this, &location);
114 *tooltip = GetDelegate()->GetTooltipText(command_, location); 116 *tooltip = GetDelegate()->GetTooltipText(command_, location);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 controller_->Run(parent, NULL, this, bounds, anchor, NULL); 246 controller_->Run(parent, NULL, this, bounds, anchor, NULL);
245 } 247 }
246 248
247 void MenuItemView::Cancel() { 249 void MenuItemView::Cancel() {
248 if (controller_ && !canceled_) { 250 if (controller_ && !canceled_) {
249 canceled_ = true; 251 canceled_ = true;
250 controller_->Cancel(MenuController::EXIT_ALL); 252 controller_->Cancel(MenuController::EXIT_ALL);
251 } 253 }
252 } 254 }
253 255
256 MenuItemView* MenuItemView::AddMenuItemAt(int index,
257 int item_id,
258 const std::wstring& label,
259 const SkBitmap& icon,
260 Type type) {
261 DCHECK_LE(0, index);
262 if (!submenu_)
263 CreateSubmenu();
264 DCHECK_GE(submenu_->child_count(), index);
265 if (type == SEPARATOR) {
266 submenu_->AddChildViewAt(new MenuSeparator(), index);
267 return NULL;
268 }
269 MenuItemView* item = new MenuItemView(this, item_id, type);
270 if (label.empty() && GetDelegate())
271 item->SetTitle(GetDelegate()->GetLabel(item_id));
272 else
273 item->SetTitle(label);
274 item->SetIcon(icon);
275 if (type == SUBMENU)
276 item->CreateSubmenu();
277 submenu_->AddChildViewAt(item, index);
278 return item;
279 }
280
281 void MenuItemView::RemoveMenuItemAt(int index) {
282 DCHECK(submenu_);
283 DCHECK_LE(0, index);
284 DCHECK_GT(submenu_->child_count(), index);
285
286 View* item = submenu_->GetChildViewAt(index);
287 DCHECK(item);
288 submenu_->RemoveChildView(item);
289
290 // RemoveChildView() does not delete the item, which is a good thing
291 // in case a submenu is being displayed while items are being removed.
292 // Deletion will be done by ChildrenChanged() or at destruction.
293 removed_items_.push_back(item);
294 }
295
254 MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model, 296 MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model,
255 int index, 297 int index,
256 int id) { 298 int id) {
257 SkBitmap icon; 299 SkBitmap icon;
258 bool has_icon = false; 300 bool has_icon = false;
259 std::wstring label; 301 std::wstring label;
260 MenuItemView::Type type; 302 MenuItemView::Type type;
261 ui::MenuModel::ItemType menu_type = model->GetTypeAt(index); 303 ui::MenuModel::ItemType menu_type = model->GetTypeAt(index);
262 switch (menu_type) { 304 switch (menu_type) {
263 case ui::MenuModel::TYPE_COMMAND: 305 case ui::MenuModel::TYPE_COMMAND:
(...skipping 22 matching lines...) Expand all
286 break; 328 break;
287 } 329 }
288 330
289 return AppendMenuItemImpl(id, label, has_icon ? icon : SkBitmap(), type); 331 return AppendMenuItemImpl(id, label, has_icon ? icon : SkBitmap(), type);
290 } 332 }
291 333
292 MenuItemView* MenuItemView::AppendMenuItemImpl(int item_id, 334 MenuItemView* MenuItemView::AppendMenuItemImpl(int item_id,
293 const std::wstring& label, 335 const std::wstring& label,
294 const SkBitmap& icon, 336 const SkBitmap& icon,
295 Type type) { 337 Type type) {
296 if (!submenu_) 338 const int index = submenu_ ? submenu_->child_count() : 0;
297 CreateSubmenu(); 339 return AddMenuItemAt(index, item_id, label, icon, type);
298 if (type == SEPARATOR) {
299 submenu_->AddChildView(new MenuSeparator());
300 return NULL;
301 }
302 MenuItemView* item = new MenuItemView(this, item_id, type);
303 if (label.empty() && GetDelegate())
304 item->SetTitle(GetDelegate()->GetLabel(item_id));
305 else
306 item->SetTitle(label);
307 item->SetIcon(icon);
308 if (type == SUBMENU)
309 item->CreateSubmenu();
310 submenu_->AddChildView(item);
311 return item;
312 } 340 }
313 341
314 SubmenuView* MenuItemView::CreateSubmenu() { 342 SubmenuView* MenuItemView::CreateSubmenu() {
315 if (!submenu_) 343 if (!submenu_)
316 submenu_ = new SubmenuView(this); 344 submenu_ = new SubmenuView(this);
317 return submenu_; 345 return submenu_;
318 } 346 }
319 347
320 bool MenuItemView::HasSubmenu() const { 348 bool MenuItemView::HasSubmenu() const {
321 return (submenu_ != NULL); 349 return (submenu_ != NULL);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 GetMenuItemByID(id); 446 GetMenuItemByID(id);
419 if (result) 447 if (result)
420 return result; 448 return result;
421 } 449 }
422 } 450 }
423 return NULL; 451 return NULL;
424 } 452 }
425 453
426 void MenuItemView::ChildrenChanged() { 454 void MenuItemView::ChildrenChanged() {
427 MenuController* controller = GetMenuController(); 455 MenuController* controller = GetMenuController();
428 if (!controller) 456 if (controller) {
429 return; // We're not showing, nothing to do. 457 // Handles the case where we were empty and are no longer empty.
458 RemoveEmptyMenus();
430 459
431 // Handles the case where we were empty and are no longer empty. 460 // Handles the case where we were not empty, but now are.
432 RemoveEmptyMenus(); 461 AddEmptyMenus();
433 462
434 // Handles the case where we were not empty, but now are. 463 controller->MenuChildrenChanged(this);
435 AddEmptyMenus();
436 464
437 controller->MenuChildrenChanged(this); 465 if (submenu_) {
466 // Force a paint and layout. This handles the case of the top
467 // level window's size remaining the same, resulting in no
468 // change to the submenu's size and no layout.
469 submenu_->Layout();
470 submenu_->SchedulePaint();
471 }
472 }
438 473
439 if (submenu_) { 474 STLDeleteElements(&removed_items_);
440 // Force a paint and layout. This handles the case of the top level window's
441 // size remaining the same, resulting in no change to the submenu's size and
442 // no layout.
443 submenu_->Layout();
444 submenu_->SchedulePaint();
445 }
446 } 475 }
447 476
448 void MenuItemView::Layout() { 477 void MenuItemView::Layout() {
449 if (!has_children()) 478 if (!has_children())
450 return; 479 return;
451 480
452 // Child views are laid out right aligned and given the full height. To right 481 // Child views are laid out right aligned and given the full height. To right
453 // align start with the last view and progress to the first. 482 // align start with the last view and progress to the first.
454 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0; 483 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0;
455 --i) { 484 --i) {
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 } 719 }
691 720
692 string16 MenuItemView::GetAcceleratorText() { 721 string16 MenuItemView::GetAcceleratorText() {
693 Accelerator accelerator; 722 Accelerator accelerator;
694 return (GetDelegate() && 723 return (GetDelegate() &&
695 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? 724 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ?
696 accelerator.GetShortcutText() : string16(); 725 accelerator.GetShortcutText() : string16();
697 } 726 }
698 727
699 } // namespace views 728 } // namespace views
OLDNEW
« views/controls/menu/menu_controller.cc ('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