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

Side by Side Diff: chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc

Issue 1005873012: Makes bookmark menu lazily create menus and removes limits (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 5 years, 8 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
OLDNEW
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 "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" 5 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
6 6
7 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 10 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
10 #include "chrome/browser/bookmarks/chrome_bookmark_client.h" 11 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
11 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h" 12 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 14 #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h"
14 #include "chrome/browser/ui/bookmarks/bookmark_utils.h" 15 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
15 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 17 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
17 #include "chrome/browser/ui/views/event_utils.h" 18 #include "chrome/browser/ui/views/event_utils.h"
18 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
(...skipping 16 matching lines...) Expand all
35 using bookmarks::BookmarkNodeData; 36 using bookmarks::BookmarkNodeData;
36 using content::PageNavigator; 37 using content::PageNavigator;
37 using views::MenuItemView; 38 using views::MenuItemView;
38 39
39 // Max width of a menu. There does not appear to be an OS value for this, yet 40 // Max width of a menu. There does not appear to be an OS value for this, yet
40 // both IE and FF restrict the max width of a menu. 41 // both IE and FF restrict the max width of a menu.
41 static const int kMaxMenuWidth = 400; 42 static const int kMaxMenuWidth = 400;
42 43
43 BookmarkMenuDelegate::BookmarkMenuDelegate(Browser* browser, 44 BookmarkMenuDelegate::BookmarkMenuDelegate(Browser* browser,
44 PageNavigator* navigator, 45 PageNavigator* navigator,
45 views::Widget* parent, 46 views::Widget* parent)
46 int first_menu_id,
47 int max_menu_id)
48 : browser_(browser), 47 : browser_(browser),
49 profile_(browser->profile()), 48 profile_(browser->profile()),
50 page_navigator_(navigator), 49 page_navigator_(navigator),
51 parent_(parent), 50 parent_(parent),
52 menu_(NULL), 51 menu_(NULL),
53 parent_menu_item_(NULL), 52 parent_menu_item_(NULL),
54 next_menu_id_(first_menu_id), 53 next_menu_id_(IDC_FIRST_BOOKMARK_MENU),
55 min_menu_id_(first_menu_id),
56 max_menu_id_(max_menu_id),
57 real_delegate_(NULL), 54 real_delegate_(NULL),
58 is_mutating_model_(false), 55 is_mutating_model_(false),
59 location_(BOOKMARK_LAUNCH_LOCATION_NONE) {} 56 location_(BOOKMARK_LAUNCH_LOCATION_NONE) {
57 }
60 58
61 BookmarkMenuDelegate::~BookmarkMenuDelegate() { 59 BookmarkMenuDelegate::~BookmarkMenuDelegate() {
62 GetBookmarkModel()->RemoveObserver(this); 60 GetBookmarkModel()->RemoveObserver(this);
63 } 61 }
64 62
65 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate, 63 void BookmarkMenuDelegate::Init(views::MenuDelegate* real_delegate,
66 MenuItemView* parent, 64 MenuItemView* parent,
67 const BookmarkNode* node, 65 const BookmarkNode* node,
68 int start_child_index, 66 int start_child_index,
69 ShowOptions show_options, 67 ShowOptions show_options,
(...skipping 14 matching lines...) Expand all
84 bool show_managed = show_forced_folders && !client->managed_node()->empty(); 82 bool show_managed = show_forced_folders && !client->managed_node()->empty();
85 bool show_supervised = 83 bool show_supervised =
86 show_forced_folders && !client->supervised_node()->empty(); 84 show_forced_folders && !client->supervised_node()->empty();
87 bool has_children = (start_child_index < node->child_count()) || 85 bool has_children = (start_child_index < node->child_count()) ||
88 show_managed || show_supervised; 86 show_managed || show_supervised;
89 int initial_count = parent->GetSubmenu() ? 87 int initial_count = parent->GetSubmenu() ?
90 parent->GetSubmenu()->GetMenuItemCount() : 0; 88 parent->GetSubmenu()->GetMenuItemCount() : 0;
91 if (has_children && initial_count > 0) 89 if (has_children && initial_count > 0)
92 parent->AppendSeparator(); 90 parent->AppendSeparator();
93 if (show_managed) 91 if (show_managed)
94 BuildMenuForManagedNode(parent, &next_menu_id_); 92 BuildMenuForManagedNode(parent);
95 if (show_supervised) 93 if (show_supervised)
96 BuildMenuForSupervisedNode(parent, &next_menu_id_); 94 BuildMenuForSupervisedNode(parent);
97 BuildMenu(node, start_child_index, parent, &next_menu_id_); 95 BuildMenu(node, start_child_index, parent);
98 if (show_options == SHOW_PERMANENT_FOLDERS) 96 if (show_options == SHOW_PERMANENT_FOLDERS)
99 BuildMenusForPermanentNodes(parent, &next_menu_id_); 97 BuildMenusForPermanentNodes(parent);
100 } else { 98 } else {
101 menu_ = CreateMenu(node, start_child_index, show_options); 99 menu_ = CreateMenu(node, start_child_index, show_options);
102 } 100 }
103 } 101 }
104 102
105 void BookmarkMenuDelegate::SetPageNavigator(PageNavigator* navigator) { 103 void BookmarkMenuDelegate::SetPageNavigator(PageNavigator* navigator) {
106 page_navigator_ = navigator; 104 page_navigator_ = navigator;
107 if (context_menu_.get()) 105 if (context_menu_.get())
108 context_menu_->SetPageNavigator(navigator); 106 context_menu_->SetPageNavigator(navigator);
109 } 107 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 338
341 int BookmarkMenuDelegate::GetDragOperations(MenuItemView* sender) { 339 int BookmarkMenuDelegate::GetDragOperations(MenuItemView* sender) {
342 return chrome::GetBookmarkDragOperation( 340 return chrome::GetBookmarkDragOperation(
343 profile_, menu_id_to_node_map_[sender->GetCommand()]); 341 profile_, menu_id_to_node_map_[sender->GetCommand()]);
344 } 342 }
345 343
346 int BookmarkMenuDelegate::GetMaxWidthForMenu(MenuItemView* menu) { 344 int BookmarkMenuDelegate::GetMaxWidthForMenu(MenuItemView* menu) {
347 return kMaxMenuWidth; 345 return kMaxMenuWidth;
348 } 346 }
349 347
348 void BookmarkMenuDelegate::WillShowMenu(MenuItemView* menu) {
349 const int command = menu->GetCommand();
350 if (menu_id_to_node_map_.find(command) == menu_id_to_node_map_.end())
Peter Kasting 2015/03/30 21:35:24 Nit: Shorter and slightly more efficient: auto
sky 2015/03/31 15:17:39 Done.
351 return;
352 const bookmarks::BookmarkNode* node = menu_id_to_node_map_[command];
353 if (node->child_count() && menu->GetSubmenu()->GetMenuItemCount() == 0)
354 BuildMenu(node, 0, menu);
355 }
356
350 void BookmarkMenuDelegate::BookmarkModelChanged() { 357 void BookmarkMenuDelegate::BookmarkModelChanged() {
351 } 358 }
352 359
353 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged( 360 void BookmarkMenuDelegate::BookmarkNodeFaviconChanged(
354 BookmarkModel* model, 361 BookmarkModel* model,
355 const BookmarkNode* node) { 362 const BookmarkNode* node) {
356 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node); 363 NodeToMenuMap::iterator menu_pair = node_to_menu_map_.find(node);
357 if (menu_pair == node_to_menu_map_.end()) 364 if (menu_pair == node_to_menu_map_.end())
358 return; // We're not showing a menu item for the node. 365 return; // We're not showing a menu item for the node.
359 366
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 GetBookmarkModel()->AddObserver(this); 430 GetBookmarkModel()->AddObserver(this);
424 DCHECK(is_mutating_model_); 431 DCHECK(is_mutating_model_);
425 is_mutating_model_ = false; 432 is_mutating_model_ = false;
426 } 433 }
427 434
428 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent, 435 MenuItemView* BookmarkMenuDelegate::CreateMenu(const BookmarkNode* parent,
429 int start_child_index, 436 int start_child_index,
430 ShowOptions show_options) { 437 ShowOptions show_options) {
431 MenuItemView* menu = new MenuItemView(real_delegate_); 438 MenuItemView* menu = new MenuItemView(real_delegate_);
432 menu->SetCommand(next_menu_id_++); 439 menu->SetCommand(next_menu_id_++);
433 menu_id_to_node_map_[menu->GetCommand()] = parent; 440 AddMenuToMaps(menu, parent);
434 menu->set_has_icons(true); 441 menu->set_has_icons(true);
435 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS; 442 bool show_permanent = show_options == SHOW_PERMANENT_FOLDERS;
436 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) { 443 if (show_permanent && parent == GetBookmarkModel()->bookmark_bar_node()) {
437 BuildMenuForManagedNode(menu, &next_menu_id_); 444 BuildMenuForManagedNode(menu);
438 BuildMenuForSupervisedNode(menu, &next_menu_id_); 445 BuildMenuForSupervisedNode(menu);
439 } 446 }
440 BuildMenu(parent, start_child_index, menu, &next_menu_id_); 447 BuildMenu(parent, start_child_index, menu);
441 if (show_permanent) 448 if (show_permanent)
442 BuildMenusForPermanentNodes(menu, &next_menu_id_); 449 BuildMenusForPermanentNodes(menu);
443 return menu; 450 return menu;
444 } 451 }
445 452
446 void BookmarkMenuDelegate::BuildMenusForPermanentNodes( 453 void BookmarkMenuDelegate::BuildMenusForPermanentNodes(
447 views::MenuItemView* menu, 454 views::MenuItemView* menu) {
448 int* next_menu_id) {
449 BookmarkModel* model = GetBookmarkModel(); 455 BookmarkModel* model = GetBookmarkModel();
450 bool added_separator = false; 456 bool added_separator = false;
451 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu, 457 BuildMenuForPermanentNode(model->other_node(), IDR_BOOKMARK_BAR_FOLDER, menu,
452 next_menu_id, &added_separator); 458 &added_separator);
453 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu, 459 BuildMenuForPermanentNode(model->mobile_node(), IDR_BOOKMARK_BAR_FOLDER, menu,
454 next_menu_id, &added_separator); 460 &added_separator);
455 } 461 }
456 462
457 void BookmarkMenuDelegate::BuildMenuForPermanentNode( 463 void BookmarkMenuDelegate::BuildMenuForPermanentNode(
458 const BookmarkNode* node, 464 const BookmarkNode* node,
459 int icon_resource_id, 465 int icon_resource_id,
460 MenuItemView* menu, 466 MenuItemView* menu,
461 int* next_menu_id,
462 bool* added_separator) { 467 bool* added_separator) {
463 if (!node->IsVisible() || node->GetTotalNodeCount() == 1) 468 if (!node->IsVisible() || node->GetTotalNodeCount() == 1)
464 return; // No children, don't create a menu. 469 return; // No children, don't create a menu.
465 470
466 int id = *next_menu_id;
467 // Don't create the submenu if its menu ID will be outside the range allowed.
468 if (IsOutsideMenuIdRange(id))
469 return;
470 (*next_menu_id)++;
471
472 if (!*added_separator) { 471 if (!*added_separator) {
473 *added_separator = true; 472 *added_separator = true;
474 menu->AppendSeparator(); 473 menu->AppendSeparator();
475 } 474 }
476 475
477 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 476 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
478 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id); 477 gfx::ImageSkia* folder_icon = rb->GetImageSkiaNamed(icon_resource_id);
479 MenuItemView* submenu = menu->AppendSubMenuWithIcon( 478 AddMenuToMaps(menu->AppendSubMenuWithIcon(next_menu_id_++, node->GetTitle(),
480 id, node->GetTitle(), *folder_icon); 479 *folder_icon),
481 BuildMenu(node, 0, submenu, next_menu_id); 480 node);
Peter Kasting 2015/03/30 21:35:24 Just so I'm sure, the removal of this BuildMenu()
sky 2015/03/31 15:17:39 That's right.
482 menu_id_to_node_map_[id] = node;
483 } 481 }
484 482
485 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu, 483 void BookmarkMenuDelegate::BuildMenuForManagedNode(MenuItemView* menu) {
486 int* next_menu_id) {
487 // Don't add a separator for this menu. 484 // Don't add a separator for this menu.
488 bool added_separator = true; 485 bool added_separator = true;
489 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node(); 486 const BookmarkNode* node = GetChromeBookmarkClient()->managed_node();
490 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu, 487 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_MANAGED, menu,
491 next_menu_id, &added_separator); 488 &added_separator);
492 } 489 }
493 490
494 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu, 491 void BookmarkMenuDelegate::BuildMenuForSupervisedNode(MenuItemView* menu) {
495 int* next_menu_id) {
496 // Don't add a separator for this menu. 492 // Don't add a separator for this menu.
497 bool added_separator = true; 493 bool added_separator = true;
498 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node(); 494 const BookmarkNode* node = GetChromeBookmarkClient()->supervised_node();
499 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu, 495 BuildMenuForPermanentNode(node, IDR_BOOKMARK_BAR_FOLDER_SUPERVISED, menu,
500 next_menu_id, &added_separator); 496 &added_separator);
501 } 497 }
502 498
503 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent, 499 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent,
504 int start_child_index, 500 int start_child_index,
505 MenuItemView* menu, 501 MenuItemView* menu) {
506 int* next_menu_id) {
507 node_to_menu_map_[parent] = menu;
508 DCHECK(parent->empty() || start_child_index < parent->child_count()); 502 DCHECK(parent->empty() || start_child_index < parent->child_count());
509 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 503 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
510 for (int i = start_child_index; i < parent->child_count(); ++i) { 504 for (int i = start_child_index; i < parent->child_count(); ++i) {
511 const BookmarkNode* node = parent->GetChild(i); 505 const BookmarkNode* node = parent->GetChild(i);
Peter Kasting 2015/03/30 21:35:24 Nit: Shorter, avoids violating the "don't handle D
sky 2015/03/31 15:17:39 The calls to add the menus are slightly different,
512 const int id = *next_menu_id; 506 const int id = next_menu_id_++;
513 // Don't create the item if its menu ID will be outside the range allowed.
514 if (IsOutsideMenuIdRange(id))
515 break;
516 507
517 (*next_menu_id)++; 508 MenuItemView* child_menu_item = nullptr;
518
519 menu_id_to_node_map_[id] = node;
520 if (node->is_url()) { 509 if (node->is_url()) {
521 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node); 510 const gfx::Image& image = GetBookmarkModel()->GetFavicon(node);
522 const gfx::ImageSkia* icon = image.IsEmpty() ? 511 const gfx::ImageSkia* icon = image.IsEmpty() ?
523 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia(); 512 rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON) : image.ToImageSkia();
524 node_to_menu_map_[node] = 513 child_menu_item =
525 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon); 514 menu->AppendMenuItemWithIcon(id, node->GetTitle(), *icon);
526 } else if (node->is_folder()) { 515 } else if (node->is_folder()) {
527 gfx::ImageSkia* folder_icon = 516 gfx::ImageSkia* folder_icon =
528 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); 517 rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER);
529 MenuItemView* submenu = menu->AppendSubMenuWithIcon( 518 child_menu_item =
530 id, node->GetTitle(), *folder_icon); 519 menu->AppendSubMenuWithIcon(id, node->GetTitle(), *folder_icon);
531 BuildMenu(node, 0, submenu, next_menu_id);
532 } else { 520 } else {
533 NOTREACHED(); 521 NOTREACHED();
534 } 522 }
523 AddMenuToMaps(child_menu_item, node);
535 } 524 }
536 } 525 }
537 526
538 bool BookmarkMenuDelegate::IsOutsideMenuIdRange(int menu_id) const { 527 void BookmarkMenuDelegate::AddMenuToMaps(MenuItemView* menu,
539 return menu_id < min_menu_id_ || menu_id > max_menu_id_; 528 const BookmarkNode* node) {
529 menu_id_to_node_map_[menu->GetCommand()] = node;
530 node_to_menu_map_[node] = menu;
540 } 531 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698