| Index: chrome/browser/ui/views/wrench_menu.cc
|
| diff --git a/chrome/browser/ui/views/wrench_menu.cc b/chrome/browser/ui/views/wrench_menu.cc
|
| index f8f8c546a930ffa774a729d5d821d48ee0d1bbab..16ef501f2db680faa2e6667fc3fd9d1891e32176 100644
|
| --- a/chrome/browser/ui/views/wrench_menu.cc
|
| +++ b/chrome/browser/ui/views/wrench_menu.cc
|
| @@ -19,7 +19,9 @@
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_window.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
|
| #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
|
| +#include "chrome/browser/ui/views/recent_tabs_menu_model_delegate.h"
|
| #include "chrome/browser/ui/views/wrench_menu_observer.h"
|
| #include "content/public/browser/host_zoom_map.h"
|
| #include "content/public/browser/notification_observer.h"
|
| @@ -48,6 +50,7 @@
|
| #include "ui/views/controls/label.h"
|
| #include "ui/views/controls/menu/menu_config.h"
|
| #include "ui/views/controls/menu/menu_item_view.h"
|
| +#include "ui/views/controls/menu/menu_model_adapter.h"
|
| #include "ui/views/controls/menu/menu_runner.h"
|
| #include "ui/views/controls/menu/menu_scroll_view_container.h"
|
| #include "ui/views/controls/menu/submenu_view.h"
|
| @@ -86,6 +89,16 @@ const int kHorizontalTouchPadding = 15;
|
| // Menu items which have embedded buttons should have this height in pixel.
|
| const int kMenuItemContainingButtonsHeight = 43;
|
|
|
| +// First ID to use for the items in the recent tabs submenu, must be more than
|
| +// maximum possible number of items in wrench menu and all its submenus except
|
| +// recent babs submenu.
|
| +const int kFirstRecentTabsCommandId = 200;
|
| +
|
| +// First ID to use for the items representing bookmarks in the bookmark menu,
|
| +// must be more than kFirstRecentTabsCommandId + maximum possible number of
|
| +// items in recent tabs submenu.
|
| +const int kFirstBookmarkCommandId = 400;
|
| +
|
| // Subclass of ImageButton whose preferred size includes the size of the border.
|
| class FullscreenButton : public ImageButton {
|
| public:
|
| @@ -756,71 +769,6 @@ class WrenchMenu::ZoomView : public WrenchMenuView {
|
| DISALLOW_COPY_AND_ASSIGN(ZoomView);
|
| };
|
|
|
| -// RecentTabsMenuModelDelegate -------------------------------------------------
|
| -
|
| -// Provides the ui::MenuModelDelegate implementation for RecentTabsSubMenuModel
|
| -// items.
|
| -class WrenchMenu::RecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
|
| - public:
|
| - RecentTabsMenuModelDelegate(ui::MenuModel* model,
|
| - views::MenuItemView* menu_item)
|
| - : model_(model),
|
| - menu_item_(menu_item) {
|
| - model_->SetMenuModelDelegate(this);
|
| - }
|
| -
|
| - virtual ~RecentTabsMenuModelDelegate() {
|
| - model_->SetMenuModelDelegate(NULL);
|
| - }
|
| -
|
| - // ui::MenuModelDelegate implementation:
|
| - virtual void OnIconChanged(int index) OVERRIDE {
|
| - // |index| specifies position in children items of |menu_item_| starting at
|
| - // 0, its corresponding command id as used in the children menu item views
|
| - // follows that of the parent menu item view |menu_item_|.
|
| - int command_id = menu_item_->GetCommand() + 1 + index;
|
| - views::MenuItemView* item = menu_item_->GetMenuItemByID(command_id);
|
| - DCHECK(item);
|
| - gfx::Image icon;
|
| - if (model_->GetIconAt(index, &icon))
|
| - item->SetIcon(*icon.ToImageSkia());
|
| - }
|
| -
|
| - // Return the specific menu width of recent tab menu item if |command_id|
|
| - // refers to one of recent tabs menu items, else return -1.
|
| - int GetMaxWidthForMenu(MenuItemView* menu) {
|
| - views::SubmenuView* submenu = menu_item_->GetSubmenu();
|
| - if (!submenu)
|
| - return -1;
|
| - const int kMaxMenuItemWidth = 320;
|
| - return menu->GetCommand() >= menu_item_->GetCommand() &&
|
| - menu->GetCommand() <=
|
| - menu_item_->GetCommand() + submenu->GetMenuItemCount() ?
|
| - kMaxMenuItemWidth : -1;
|
| - }
|
| -
|
| - const gfx::Font* GetLabelFontAt(int index) const {
|
| - return model_->GetLabelFontAt(index);
|
| - }
|
| -
|
| - bool GetForegroundColor(int command_id,
|
| - bool is_hovered,
|
| - SkColor* override_color) const {
|
| - // The items for which we get a font, should be shown in black.
|
| - if (GetLabelFontAt(command_id)) {
|
| - *override_color = SK_ColorBLACK;
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - private:
|
| - ui::MenuModel* model_;
|
| - views::MenuItemView* menu_item_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(RecentTabsMenuModelDelegate);
|
| -};
|
| -
|
| // WrenchMenu ------------------------------------------------------------------
|
|
|
| WrenchMenu::WrenchMenu(Browser* browser,
|
| @@ -832,9 +780,6 @@ WrenchMenu::WrenchMenu(Browser* browser,
|
| selected_index_(0),
|
| bookmark_menu_(NULL),
|
| feedback_menu_item_(NULL),
|
| - first_bookmark_command_id_(0),
|
| - first_recent_tabs_command_id_(-1),
|
| - last_recent_tabs_command_id_(-1),
|
| use_new_menu_(use_new_menu),
|
| supports_new_separators_(supports_new_separators) {
|
| registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
|
| @@ -858,7 +803,7 @@ void WrenchMenu::Init(ui::MenuModel* model) {
|
| // so we get the taller menu style.
|
| int next_id = 1;
|
| PopulateMenu(root_, model, &next_id);
|
| - first_bookmark_command_id_ = next_id + 1;
|
| + DCHECK_LT(next_id, kFirstRecentTabsCommandId);
|
| menu_runner_.reset(new views::MenuRunner(root_));
|
| }
|
|
|
| @@ -905,20 +850,17 @@ void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) {
|
| observer_list_.RemoveObserver(observer);
|
| }
|
|
|
| -const gfx::Font* WrenchMenu::GetLabelFont(int index) const {
|
| - if (is_recent_tabs_command(index)) {
|
| - return recent_tabs_menu_model_delegate_->GetLabelFontAt(
|
| - index - first_recent_tabs_command_id_);
|
| - }
|
| - return NULL;
|
| +const gfx::Font* WrenchMenu::GetLabelFont(int id) const {
|
| + return IsRecentTabsCommand(id) ?
|
| + recent_tabs_menu_model_delegate_->GetLabelFontAt(id) : NULL;
|
| }
|
|
|
| bool WrenchMenu::GetForegroundColor(int command_id,
|
| bool is_hovered,
|
| SkColor* override_color) const {
|
| - if (is_recent_tabs_command(command_id)) {
|
| + if (IsRecentTabsCommand(command_id)) {
|
| return recent_tabs_menu_model_delegate_->GetForegroundColor(
|
| - command_id - first_recent_tabs_command_id_,
|
| + command_id,
|
| is_hovered,
|
| override_color);
|
| }
|
| @@ -927,13 +869,13 @@ bool WrenchMenu::GetForegroundColor(int command_id,
|
|
|
| string16 WrenchMenu::GetTooltipText(int id,
|
| const gfx::Point& p) const {
|
| - return is_bookmark_command(id) ?
|
| + return IsBookmarkCommand(id) ?
|
| bookmark_menu_delegate_->GetTooltipText(id, p) : string16();
|
| }
|
|
|
| bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu,
|
| const ui::Event& e) {
|
| - return is_bookmark_command(menu->GetCommand()) ?
|
| + return IsBookmarkCommand(menu->GetCommand()) ?
|
| bookmark_menu_delegate_->IsTriggerableEvent(menu, e) :
|
| MenuDelegate::IsTriggerableEvent(menu, e);
|
| }
|
| @@ -964,7 +906,7 @@ int WrenchMenu::GetDropOperation(
|
| MenuItemView* item,
|
| const ui::DropTargetEvent& event,
|
| DropPosition* position) {
|
| - return is_bookmark_command(item->GetCommand()) ?
|
| + return IsBookmarkCommand(item->GetCommand()) ?
|
| bookmark_menu_delegate_->GetDropOperation(item, event, position) :
|
| ui::DragDropTypes::DRAG_NONE;
|
| }
|
| @@ -972,7 +914,7 @@ int WrenchMenu::GetDropOperation(
|
| int WrenchMenu::OnPerformDrop(MenuItemView* menu,
|
| DropPosition position,
|
| const ui::DropTargetEvent& event) {
|
| - if (!is_bookmark_command(menu->GetCommand()))
|
| + if (!IsBookmarkCommand(menu->GetCommand()))
|
| return ui::DragDropTypes::DRAG_NONE;
|
|
|
| int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event);
|
| @@ -983,31 +925,31 @@ bool WrenchMenu::ShowContextMenu(MenuItemView* source,
|
| int id,
|
| const gfx::Point& p,
|
| ui::MenuSourceType source_type) {
|
| - return is_bookmark_command(id) ?
|
| + return IsBookmarkCommand(id) ?
|
| bookmark_menu_delegate_->ShowContextMenu(source, id, p,
|
| source_type) :
|
| false;
|
| }
|
|
|
| bool WrenchMenu::CanDrag(MenuItemView* menu) {
|
| - return is_bookmark_command(menu->GetCommand()) ?
|
| + return IsBookmarkCommand(menu->GetCommand()) ?
|
| bookmark_menu_delegate_->CanDrag(menu) : false;
|
| }
|
|
|
| void WrenchMenu::WriteDragData(MenuItemView* sender,
|
| ui::OSExchangeData* data) {
|
| - DCHECK(is_bookmark_command(sender->GetCommand()));
|
| + DCHECK(IsBookmarkCommand(sender->GetCommand()));
|
| return bookmark_menu_delegate_->WriteDragData(sender, data);
|
| }
|
|
|
| int WrenchMenu::GetDragOperations(MenuItemView* sender) {
|
| - return is_bookmark_command(sender->GetCommand()) ?
|
| + return IsBookmarkCommand(sender->GetCommand()) ?
|
| bookmark_menu_delegate_->GetDragOperations(sender) :
|
| MenuDelegate::GetDragOperations(sender);
|
| }
|
|
|
| int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) {
|
| - if (is_bookmark_command(menu->GetCommand()))
|
| + if (IsBookmarkCommand(menu->GetCommand()))
|
| return bookmark_menu_delegate_->GetMaxWidthForMenu(menu);
|
| int max_width = -1;
|
| // If recent tabs menu is available, it will decide if |menu| is one of recent
|
| @@ -1021,7 +963,7 @@ int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) {
|
| }
|
|
|
| bool WrenchMenu::IsItemChecked(int id) const {
|
| - if (is_bookmark_command(id))
|
| + if (IsBookmarkCommand(id))
|
| return false;
|
|
|
| const Entry& entry = id_to_entry_.find(id)->second;
|
| @@ -1029,7 +971,7 @@ bool WrenchMenu::IsItemChecked(int id) const {
|
| }
|
|
|
| bool WrenchMenu::IsCommandEnabled(int id) const {
|
| - if (is_bookmark_command(id))
|
| + if (IsBookmarkCommand(id))
|
| return true;
|
|
|
| if (id == 0)
|
| @@ -1045,7 +987,7 @@ bool WrenchMenu::IsCommandEnabled(int id) const {
|
| }
|
|
|
| void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) {
|
| - if (is_bookmark_command(id)) {
|
| + if (IsBookmarkCommand(id)) {
|
| bookmark_menu_delegate_->ExecuteCommand(id, mouse_event_flags);
|
| return;
|
| }
|
| @@ -1065,7 +1007,7 @@ void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) {
|
| }
|
|
|
| bool WrenchMenu::GetAccelerator(int id, ui::Accelerator* accelerator) {
|
| - if (is_bookmark_command(id))
|
| + if (IsBookmarkCommand(id))
|
| return false;
|
| IDToEntry::iterator ix = id_to_entry_.find(id);
|
| if (ix == id_to_entry_.end()) {
|
| @@ -1108,6 +1050,53 @@ void WrenchMenu::WillHideMenu(MenuItemView* menu) {
|
| }
|
| }
|
|
|
| +void WrenchMenu::OnItemAdded(MenuItemView* parent,
|
| + int menu_index,
|
| + ui::MenuModel* model,
|
| + int model_index,
|
| + int item_id) {
|
| + int id = item_id;
|
| + AddMenuItem(parent, menu_index, model,
|
| + model_index, model->GetTypeAt(model_index),
|
| + &id, 0);
|
| +}
|
| +
|
| +void WrenchMenu::OnItemRemoved(MenuItemView* parent, int menu_index,
|
| + int item_id) {
|
| + parent->RemoveMenuItemAt(menu_index);
|
| + id_to_entry_.erase(item_id);
|
| +}
|
| +
|
| +void WrenchMenu::UpdateMapOfMenuItemIdAndModel(ui::MenuModel* model,
|
| + std::vector<int>& item_ids) {
|
| + for (int i = 0; i < static_cast<int>(item_ids.size()); ++i) {
|
| + int id = item_ids[i];
|
| + CHECK(id_to_entry_[id].first == model); // kk
|
| + if (id_to_entry_[id].second != i)
|
| +{
|
| +LOG(ERROR) << "kk chnged: map[" << id << "] = {" << id_to_entry_[id].first << "," << id_to_entry_[id].second << "}, idx=" << i;
|
| + id_to_entry_[id].second = i;
|
| +}
|
| + }
|
| +
|
| +//#if defined(DEBUG) // kk
|
| + // Verify that all mappings between id and index is unique i.e. 1-1.
|
| + std::vector<bool> id_exists;
|
| + id_exists.resize(model->GetItemCount(), false);
|
| + for (IDToEntry::const_iterator iter = id_to_entry_.begin();
|
| + iter != id_to_entry_.end(); ++iter) {
|
| + const Entry& entry = iter->second;
|
| + if (entry.first != model)
|
| + continue;
|
| + CHECK(!id_exists[entry.second]) // kk
|
| + << "id_to_map[" << iter->first << "].index = " << entry.second
|
| + << " already exists!";
|
| +LOG(ERROR) << "id_to_map[" << iter->first << "].index = " << entry.second;
|
| + id_exists[entry.second] = true;
|
| + }
|
| +// #endif // defined(DEBUG) // kk
|
| +}
|
| +
|
| void WrenchMenu::BookmarkModelChanged() {
|
| DCHECK(bookmark_menu_delegate_.get());
|
| if (!bookmark_menu_delegate_->is_mutating_model())
|
| @@ -1140,17 +1129,19 @@ void WrenchMenu::PopulateMenu(MenuItemView* parent,
|
| model->GetCommandIdAt(i) == IDC_ZOOM_MINUS))
|
| height = kMenuItemContainingButtonsHeight;
|
|
|
| - MenuItemView* item = AppendMenuItem(
|
| - parent, model, i, model->GetTypeAt(i), next_id, height);
|
| + // Add the menu item at the end.
|
| + int menu_index = parent->HasSubmenu() ?
|
| + parent->GetSubmenu()->child_count() : 0;
|
| + MenuItemView* item = AddMenuItem(
|
| + parent, menu_index, model, i, model->GetTypeAt(i), next_id, height);
|
|
|
| if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) {
|
| - bool is_recent_tabs_menu =
|
| - model->GetCommandIdAt(i) == IDC_RECENT_TABS_MENU;
|
| - if (is_recent_tabs_menu)
|
| - first_recent_tabs_command_id_ = *next_id;
|
| - PopulateMenu(item, model->GetSubmenuModelAt(i), next_id);
|
| - if (is_recent_tabs_menu)
|
| - last_recent_tabs_command_id_ = *next_id - 1;
|
| + // Only populate submenus if it's not Recent Tabs submenu.
|
| + // RecentTabsMenuModelDelegate will populate the Recent Tabs submenu
|
| + // below; the submenu consists of both dynamic and constant items, which
|
| + // require special handling of their Id's.
|
| + if (model->GetCommandIdAt(i) != IDC_RECENT_TABS_MENU)
|
| + PopulateMenu(item, model->GetSubmenuModelAt(i), next_id);
|
| }
|
|
|
| const ui::NativeTheme* native_theme = GetNativeTheme();
|
| @@ -1192,8 +1183,14 @@ void WrenchMenu::PopulateMenu(MenuItemView* parent,
|
| case IDC_RECENT_TABS_MENU:
|
| DCHECK(!recent_tabs_menu_model_delegate_.get());
|
| recent_tabs_menu_model_delegate_.reset(
|
| - new RecentTabsMenuModelDelegate(model->GetSubmenuModelAt(i),
|
| - item));
|
| + new RecentTabsMenuModelDelegate(
|
| + this,
|
| + static_cast<RecentTabsSubMenuModel*>(
|
| + model->GetSubmenuModelAt(i)),
|
| + item,
|
| + kFirstRecentTabsCommandId,
|
| + kFirstBookmarkCommandId - 1));
|
| + recent_tabs_menu_model_delegate_->PopulateMenu();
|
| break;
|
|
|
| default:
|
| @@ -1202,36 +1199,40 @@ void WrenchMenu::PopulateMenu(MenuItemView* parent,
|
| }
|
| }
|
|
|
| -MenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent,
|
| - MenuModel* model,
|
| - int index,
|
| - MenuModel::ItemType menu_type,
|
| - int* next_id,
|
| - int height) {
|
| +MenuItemView* WrenchMenu::AddMenuItem(MenuItemView* parent,
|
| + int menu_index,
|
| + MenuModel* model,
|
| + int model_index,
|
| + MenuModel::ItemType menu_type,
|
| + int* next_id,
|
| + int height) {
|
| int id = (*next_id)++;
|
|
|
| + DCHECK(id_to_entry_.find(id) == id_to_entry_.end());
|
| +
|
| id_to_entry_[id].first = model;
|
| - id_to_entry_[id].second = index;
|
| + id_to_entry_[id].second = model_index;
|
|
|
| MenuItemView* menu_item = NULL;
|
| if (height > 0) {
|
| // For menu items with a special menu height we use our special class to be
|
| // able to modify the item height.
|
| menu_item = new ButtonContainerMenuItemView(parent, id, height);
|
| - parent->GetSubmenu()->AddChildView(menu_item);
|
| + parent->GetSubmenu()->AddChildViewAt(menu_item, menu_index);
|
| } else {
|
| // For all other cases we use the more generic way to add menu items.
|
| - menu_item = parent->AppendMenuItemFromModel(model, index, id);
|
| + menu_item = views::MenuModelAdapter::AddMenuItemFromModelAt(
|
| + model, model_index, parent, menu_index, id);
|
| }
|
|
|
| if (menu_item) {
|
| // Flush all buttons to the right side of the menu for the new menu type.
|
| menu_item->set_use_right_margin(!use_new_menu_);
|
| - menu_item->SetVisible(model->IsVisibleAt(index));
|
| + menu_item->SetVisible(model->IsVisibleAt(model_index));
|
|
|
| if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) {
|
| gfx::Image icon;
|
| - if (model->GetIconAt(index, &icon))
|
| + if (model->GetIconAt(model_index, &icon))
|
| menu_item->SetIcon(*icon.ToImageSkia());
|
| }
|
| }
|
| @@ -1263,9 +1264,19 @@ void WrenchMenu::CreateBookmarkMenu() {
|
| new BookmarkMenuDelegate(browser_,
|
| browser_,
|
| parent,
|
| - first_bookmark_command_id_));
|
| + kFirstBookmarkCommandId));
|
| bookmark_menu_delegate_->Init(
|
| this, bookmark_menu_, model->bookmark_bar_node(), 0,
|
| BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
|
| bookmark_utils::LAUNCH_WRENCH_MENU);
|
| }
|
| +
|
| +bool WrenchMenu::IsBookmarkCommand(int id) const {
|
| + return bookmark_menu_delegate_.get() && id >= kFirstBookmarkCommandId;
|
| +}
|
| +
|
| +bool WrenchMenu::IsRecentTabsCommand(int id) const {
|
| + return (recent_tabs_menu_model_delegate_.get() &&
|
| + id >= kFirstRecentTabsCommandId &&
|
| + id < kFirstBookmarkCommandId);
|
| +}
|
|
|