Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/wrench_menu.h" | 5 #include "chrome/browser/ui/views/wrench_menu.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/app/chrome_command_ids.h" | 13 #include "chrome/app/chrome_command_ids.h" |
| 14 #include "chrome/browser/bookmarks/bookmark_model.h" | 14 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 15 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 15 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| 16 #include "chrome/browser/bookmarks/bookmark_stats.h" | 16 #include "chrome/browser/bookmarks/bookmark_stats.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/search/search.h" | 19 #include "chrome/browser/search/search.h" |
| 20 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/browser/ui/browser_window.h" | 21 #include "chrome/browser/ui/browser_window.h" |
| 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 23 #include "chrome/browser/ui/toolbar/wrench_menu_model.h" | |
| 23 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" | 24 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" |
| 24 #include "chrome/browser/ui/views/wrench_menu_observer.h" | 25 #include "chrome/browser/ui/views/wrench_menu_observer.h" |
| 25 #include "content/public/browser/host_zoom_map.h" | 26 #include "content/public/browser/host_zoom_map.h" |
| 26 #include "content/public/browser/notification_observer.h" | 27 #include "content/public/browser/notification_observer.h" |
| 27 #include "content/public/browser/notification_registrar.h" | 28 #include "content/public/browser/notification_registrar.h" |
| 28 #include "content/public/browser/notification_source.h" | 29 #include "content/public/browser/notification_source.h" |
| 29 #include "content/public/browser/notification_types.h" | 30 #include "content/public/browser/notification_types.h" |
| 30 #include "content/public/browser/user_metrics.h" | 31 #include "content/public/browser/user_metrics.h" |
| 31 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 32 #include "grit/chromium_strings.h" | 33 #include "grit/chromium_strings.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 const SkColor kTouchButtonText = 0xff5a5a5a; | 82 const SkColor kTouchButtonText = 0xff5a5a5a; |
| 82 | 83 |
| 83 // Horizontal padding on the edges of the buttons. | 84 // Horizontal padding on the edges of the buttons. |
| 84 const int kHorizontalPadding = 6; | 85 const int kHorizontalPadding = 6; |
| 85 // Horizontal padding for a touch enabled menu. | 86 // Horizontal padding for a touch enabled menu. |
| 86 const int kHorizontalTouchPadding = 15; | 87 const int kHorizontalTouchPadding = 15; |
| 87 | 88 |
| 88 // Menu items which have embedded buttons should have this height in pixel. | 89 // Menu items which have embedded buttons should have this height in pixel. |
| 89 const int kMenuItemContainingButtonsHeight = 43; | 90 const int kMenuItemContainingButtonsHeight = 43; |
| 90 | 91 |
| 92 // Returns true if |command_id| identifies a bookmark menu item. | |
| 93 bool IsBookmarkCommand(int command_id) { | |
| 94 return command_id >= WrenchMenuModel::kMinBookmarkCommandId && | |
| 95 command_id <= WrenchMenuModel::kMaxBookmarkCommandId; | |
| 96 } | |
| 97 | |
| 98 // Returns true if |command_id| identifies a recent tabs menu item. | |
| 99 bool IsRecentTabsCommand(int command_id) { | |
| 100 return command_id >= WrenchMenuModel::kMinRecentTabsCommandId && | |
| 101 command_id <= WrenchMenuModel::kMaxRecentTabsCommandId; | |
| 102 } | |
| 103 | |
| 91 // Subclass of ImageButton whose preferred size includes the size of the border. | 104 // Subclass of ImageButton whose preferred size includes the size of the border. |
| 92 class FullscreenButton : public ImageButton { | 105 class FullscreenButton : public ImageButton { |
| 93 public: | 106 public: |
| 94 explicit FullscreenButton(views::ButtonListener* listener) | 107 explicit FullscreenButton(views::ButtonListener* listener) |
| 95 : ImageButton(listener) { } | 108 : ImageButton(listener) { } |
| 96 | 109 |
| 97 // Overridden from ImageButton. | 110 // Overridden from ImageButton. |
| 98 virtual gfx::Size GetPreferredSize() OVERRIDE { | 111 virtual gfx::Size GetPreferredSize() OVERRIDE { |
| 99 gfx::Size pref = ImageButton::GetPreferredSize(); | 112 gfx::Size pref = ImageButton::GetPreferredSize(); |
| 100 if (border()) { | 113 if (border()) { |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 // WARNING: this may be NULL during shutdown. | 417 // WARNING: this may be NULL during shutdown. |
| 405 MenuModel* menu_model_; | 418 MenuModel* menu_model_; |
| 406 | 419 |
| 407 DISALLOW_COPY_AND_ASSIGN(WrenchMenuView); | 420 DISALLOW_COPY_AND_ASSIGN(WrenchMenuView); |
| 408 }; | 421 }; |
| 409 | 422 |
| 410 class ButtonContainerMenuItemView : public MenuItemView { | 423 class ButtonContainerMenuItemView : public MenuItemView { |
| 411 public: | 424 public: |
| 412 // Constructor for use with button containing menu items which have a | 425 // Constructor for use with button containing menu items which have a |
| 413 // different height then normal items. | 426 // different height then normal items. |
| 414 ButtonContainerMenuItemView(MenuItemView* parent, int id, int height) | 427 ButtonContainerMenuItemView(MenuItemView* parent, int command_id, int height) |
| 415 : MenuItemView(parent, id, MenuItemView::NORMAL), | 428 : MenuItemView(parent, command_id, MenuItemView::NORMAL), |
| 416 height_(height) { | 429 height_(height) { |
| 417 }; | 430 }; |
| 418 | 431 |
| 419 // Overridden from MenuItemView. | 432 // Overridden from MenuItemView. |
| 420 virtual gfx::Size GetChildPreferredSize() OVERRIDE { | 433 virtual gfx::Size GetChildPreferredSize() OVERRIDE { |
| 421 gfx::Size size = MenuItemView::GetChildPreferredSize(); | 434 gfx::Size size = MenuItemView::GetChildPreferredSize(); |
| 422 // When there is a height override given, we need to deduct our spacing | 435 // When there is a height override given, we need to deduct our spacing |
| 423 // above and below to get to the correct height to return here for the | 436 // above and below to get to the correct height to return here for the |
| 424 // child item. | 437 // child item. |
| 425 int height = height_ - GetTopMargin() - GetBottomMargin(); | 438 int height = height_ - GetTopMargin() - GetBottomMargin(); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 menu_item_(menu_item) { | 770 menu_item_(menu_item) { |
| 758 model_->SetMenuModelDelegate(this); | 771 model_->SetMenuModelDelegate(this); |
| 759 } | 772 } |
| 760 | 773 |
| 761 virtual ~RecentTabsMenuModelDelegate() { | 774 virtual ~RecentTabsMenuModelDelegate() { |
| 762 model_->SetMenuModelDelegate(NULL); | 775 model_->SetMenuModelDelegate(NULL); |
| 763 } | 776 } |
| 764 | 777 |
| 765 // ui::MenuModelDelegate implementation: | 778 // ui::MenuModelDelegate implementation: |
| 766 virtual void OnIconChanged(int index) OVERRIDE { | 779 virtual void OnIconChanged(int index) OVERRIDE { |
| 767 // |index| specifies position in children items of |menu_item_| starting at | 780 int command_id = model_->GetCommandIdAt(index); |
| 768 // 0, its corresponding command id as used in the children menu item views | |
| 769 // follows that of the parent menu item view |menu_item_|. | |
| 770 int command_id = menu_item_->GetCommand() + 1 + index; | |
| 771 views::MenuItemView* item = menu_item_->GetMenuItemByID(command_id); | 781 views::MenuItemView* item = menu_item_->GetMenuItemByID(command_id); |
| 772 DCHECK(item); | 782 DCHECK(item); |
| 773 gfx::Image icon; | 783 gfx::Image icon; |
| 774 if (model_->GetIconAt(index, &icon)) | 784 if (model_->GetIconAt(index, &icon)) |
| 775 item->SetIcon(*icon.ToImageSkia()); | 785 item->SetIcon(*icon.ToImageSkia()); |
| 776 } | 786 } |
| 777 | 787 |
| 778 // Return the specific menu width of recent tab menu item if |command_id| | 788 // Return the specific menu width of recent tab menu item if |command_id| |
| 779 // refers to one of recent tabs menu items, else return -1. | 789 // refers to one of recent tabs menu items, else return -1. |
| 780 int GetMaxWidthForMenu(MenuItemView* menu) { | 790 int GetMaxWidthForMenu(MenuItemView* menu) { |
| 781 views::SubmenuView* submenu = menu_item_->GetSubmenu(); | 791 views::SubmenuView* submenu = menu_item_->GetSubmenu(); |
| 782 if (!submenu) | 792 if (!submenu) |
| 783 return -1; | 793 return -1; |
| 784 const int kMaxMenuItemWidth = 320; | 794 const int kMaxMenuItemWidth = 320; |
| 785 return menu->GetCommand() >= menu_item_->GetCommand() && | 795 return menu->GetCommand() == menu_item_->GetCommand() ? |
| 786 menu->GetCommand() <= | |
| 787 menu_item_->GetCommand() + submenu->GetMenuItemCount() ? | |
| 788 kMaxMenuItemWidth : -1; | 796 kMaxMenuItemWidth : -1; |
| 789 } | 797 } |
| 790 | 798 |
| 791 const gfx::Font* GetLabelFontAt(int index) const { | 799 const gfx::Font* GetLabelFontAt(int index) const { |
| 792 return model_->GetLabelFontAt(index); | 800 return model_->GetLabelFontAt(index); |
| 793 } | 801 } |
| 794 | 802 |
| 795 bool GetForegroundColor(int command_id, | 803 bool GetForegroundColorAt(int index, |
| 796 bool is_hovered, | 804 bool is_hovered, |
| 797 SkColor* override_color) const { | 805 SkColor* override_color) const { |
| 798 // The items for which we get a font, should be shown in black. | 806 // The items for which we get a font, should be shown in black. |
| 799 if (GetLabelFontAt(command_id)) { | 807 if (GetLabelFontAt(index)) { |
| 800 *override_color = SK_ColorBLACK; | 808 *override_color = SK_ColorBLACK; |
| 801 return true; | 809 return true; |
| 802 } | 810 } |
| 803 return false; | 811 return false; |
| 804 } | 812 } |
| 805 | 813 |
| 806 private: | 814 private: |
| 807 ui::MenuModel* model_; | 815 ui::MenuModel* model_; |
| 808 views::MenuItemView* menu_item_; | 816 views::MenuItemView* menu_item_; |
| 809 | 817 |
| 810 DISALLOW_COPY_AND_ASSIGN(RecentTabsMenuModelDelegate); | 818 DISALLOW_COPY_AND_ASSIGN(RecentTabsMenuModelDelegate); |
| 811 }; | 819 }; |
| 812 | 820 |
| 813 // WrenchMenu ------------------------------------------------------------------ | 821 // WrenchMenu ------------------------------------------------------------------ |
| 814 | 822 |
| 815 WrenchMenu::WrenchMenu(Browser* browser, | 823 WrenchMenu::WrenchMenu(Browser* browser, |
| 816 bool use_new_menu, | 824 bool use_new_menu, |
| 817 bool supports_new_separators) | 825 bool supports_new_separators) |
| 818 : root_(NULL), | 826 : root_(NULL), |
| 819 browser_(browser), | 827 browser_(browser), |
| 820 selected_menu_model_(NULL), | 828 selected_menu_model_(NULL), |
| 821 selected_index_(0), | 829 selected_index_(0), |
| 822 bookmark_menu_(NULL), | 830 bookmark_menu_(NULL), |
| 823 feedback_menu_item_(NULL), | 831 feedback_menu_item_(NULL), |
| 824 first_bookmark_command_id_(0), | |
| 825 first_recent_tabs_command_id_(-1), | |
| 826 last_recent_tabs_command_id_(-1), | |
| 827 use_new_menu_(use_new_menu), | 832 use_new_menu_(use_new_menu), |
| 828 supports_new_separators_(supports_new_separators) { | 833 supports_new_separators_(supports_new_separators) { |
| 829 registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, | 834 registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, |
| 830 content::Source<Profile>(browser_->profile())); | 835 content::Source<Profile>(browser_->profile())); |
| 831 } | 836 } |
| 832 | 837 |
| 833 WrenchMenu::~WrenchMenu() { | 838 WrenchMenu::~WrenchMenu() { |
| 834 if (bookmark_menu_delegate_.get()) { | 839 if (bookmark_menu_delegate_.get()) { |
| 835 BookmarkModel* model = BookmarkModelFactory::GetForProfile( | 840 BookmarkModel* model = BookmarkModelFactory::GetForProfile( |
| 836 browser_->profile()); | 841 browser_->profile()); |
| 837 if (model) | 842 if (model) |
| 838 model->RemoveObserver(this); | 843 model->RemoveObserver(this); |
| 839 } | 844 } |
| 840 FOR_EACH_OBSERVER(WrenchMenuObserver, observer_list_, WrenchMenuDestroyed()); | 845 FOR_EACH_OBSERVER(WrenchMenuObserver, observer_list_, WrenchMenuDestroyed()); |
| 841 } | 846 } |
| 842 | 847 |
| 843 void WrenchMenu::Init(ui::MenuModel* model) { | 848 void WrenchMenu::Init(ui::MenuModel* model) { |
| 844 DCHECK(!root_); | 849 DCHECK(!root_); |
| 845 root_ = new MenuItemView(this); | 850 root_ = new MenuItemView(this); |
| 846 root_->set_has_icons(true); // We have checks, radios and icons, set this | 851 root_->set_has_icons(true); // We have checks, radios and icons, set this |
| 847 // so we get the taller menu style. | 852 // so we get the taller menu style. |
| 848 int next_id = 1; | 853 PopulateMenu(root_, model); |
| 849 PopulateMenu(root_, model, &next_id); | 854 |
| 850 first_bookmark_command_id_ = next_id + 1; | 855 #if defined(DEBUG) |
| 856 // Verify that the reserved command ID's for bookmarks menu are not used. | |
| 857 for (int i = WrenchMenuModel:kMinBookmarkCommandId; | |
| 858 i <= WrenchMenuModel::kMaxBookmarkCommandId; ++i) | |
| 859 DCHECK(command_id_to_entry_.find(i) == command_id_to_entry_.end()); | |
| 860 #endif // defined(DEBUG) | |
| 861 | |
| 851 menu_runner_.reset(new views::MenuRunner(root_)); | 862 menu_runner_.reset(new views::MenuRunner(root_)); |
| 852 } | 863 } |
| 853 | 864 |
| 854 void WrenchMenu::RunMenu(views::MenuButton* host) { | 865 void WrenchMenu::RunMenu(views::MenuButton* host) { |
| 855 gfx::Point screen_loc; | 866 gfx::Point screen_loc; |
| 856 views::View::ConvertPointToScreen(host, &screen_loc); | 867 views::View::ConvertPointToScreen(host, &screen_loc); |
| 857 gfx::Rect bounds(screen_loc, host->size()); | 868 gfx::Rect bounds(screen_loc, host->size()); |
| 858 content::RecordAction(UserMetricsAction("ShowAppMenu")); | 869 content::RecordAction(UserMetricsAction("ShowAppMenu")); |
| 859 if (menu_runner_->RunMenuAt(host->GetWidget(), host, bounds, | 870 if (menu_runner_->RunMenuAt(host->GetWidget(), host, bounds, |
| 860 MenuItemView::TOPRIGHT, ui::MENU_SOURCE_NONE, | 871 MenuItemView::TOPRIGHT, ui::MENU_SOURCE_NONE, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 887 } | 898 } |
| 888 | 899 |
| 889 void WrenchMenu::AddObserver(WrenchMenuObserver* observer) { | 900 void WrenchMenu::AddObserver(WrenchMenuObserver* observer) { |
| 890 observer_list_.AddObserver(observer); | 901 observer_list_.AddObserver(observer); |
| 891 } | 902 } |
| 892 | 903 |
| 893 void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) { | 904 void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) { |
| 894 observer_list_.RemoveObserver(observer); | 905 observer_list_.RemoveObserver(observer); |
| 895 } | 906 } |
| 896 | 907 |
| 897 const gfx::Font* WrenchMenu::GetLabelFont(int index) const { | 908 const gfx::Font* WrenchMenu::GetLabelFont(int command_id) const { |
| 898 if (is_recent_tabs_command(index)) { | 909 if (IsRecentTabsCommand(command_id)) { |
| 899 return recent_tabs_menu_model_delegate_->GetLabelFontAt( | 910 return recent_tabs_menu_model_delegate_->GetLabelFontAt( |
| 900 index - first_recent_tabs_command_id_); | 911 ModelIndexFromCommandId(command_id)); |
| 901 } | 912 } |
| 902 return NULL; | 913 return NULL; |
| 903 } | 914 } |
| 904 | 915 |
| 905 bool WrenchMenu::GetForegroundColor(int command_id, | 916 bool WrenchMenu::GetForegroundColor(int command_id, |
| 906 bool is_hovered, | 917 bool is_hovered, |
| 907 SkColor* override_color) const { | 918 SkColor* override_color) const { |
| 908 if (is_recent_tabs_command(command_id)) { | 919 if (IsRecentTabsCommand(command_id)) { |
| 909 return recent_tabs_menu_model_delegate_->GetForegroundColor( | 920 return recent_tabs_menu_model_delegate_->GetForegroundColorAt( |
| 910 command_id - first_recent_tabs_command_id_, | 921 ModelIndexFromCommandId(command_id), is_hovered, override_color); |
| 911 is_hovered, | |
| 912 override_color); | |
| 913 } | 922 } |
| 914 return false; | 923 return false; |
| 915 } | 924 } |
| 916 | 925 |
| 917 string16 WrenchMenu::GetTooltipText(int id, | 926 string16 WrenchMenu::GetTooltipText(int command_id, |
| 918 const gfx::Point& p) const { | 927 const gfx::Point& p) const { |
| 919 return is_bookmark_command(id) ? | 928 return IsBookmarkCommand(command_id) ? |
| 920 bookmark_menu_delegate_->GetTooltipText(id, p) : string16(); | 929 bookmark_menu_delegate_->GetTooltipText(command_id, p) : string16(); |
| 921 } | 930 } |
| 922 | 931 |
| 923 bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu, | 932 bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu, |
| 924 const ui::Event& e) { | 933 const ui::Event& e) { |
| 925 return is_bookmark_command(menu->GetCommand()) ? | 934 return IsBookmarkCommand(menu->GetCommand()) ? |
| 926 bookmark_menu_delegate_->IsTriggerableEvent(menu, e) : | 935 bookmark_menu_delegate_->IsTriggerableEvent(menu, e) : |
| 927 MenuDelegate::IsTriggerableEvent(menu, e); | 936 MenuDelegate::IsTriggerableEvent(menu, e); |
| 928 } | 937 } |
| 929 | 938 |
| 930 bool WrenchMenu::GetDropFormats( | 939 bool WrenchMenu::GetDropFormats( |
| 931 MenuItemView* menu, | 940 MenuItemView* menu, |
| 932 int* formats, | 941 int* formats, |
| 933 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { | 942 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { |
| 934 CreateBookmarkMenu(); | 943 CreateBookmarkMenu(); |
| 935 return bookmark_menu_delegate_.get() && | 944 return bookmark_menu_delegate_.get() && |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 946 const ui::OSExchangeData& data) { | 955 const ui::OSExchangeData& data) { |
| 947 CreateBookmarkMenu(); | 956 CreateBookmarkMenu(); |
| 948 return bookmark_menu_delegate_.get() && | 957 return bookmark_menu_delegate_.get() && |
| 949 bookmark_menu_delegate_->CanDrop(menu, data); | 958 bookmark_menu_delegate_->CanDrop(menu, data); |
| 950 } | 959 } |
| 951 | 960 |
| 952 int WrenchMenu::GetDropOperation( | 961 int WrenchMenu::GetDropOperation( |
| 953 MenuItemView* item, | 962 MenuItemView* item, |
| 954 const ui::DropTargetEvent& event, | 963 const ui::DropTargetEvent& event, |
| 955 DropPosition* position) { | 964 DropPosition* position) { |
| 956 return is_bookmark_command(item->GetCommand()) ? | 965 return IsBookmarkCommand(item->GetCommand()) ? |
| 957 bookmark_menu_delegate_->GetDropOperation(item, event, position) : | 966 bookmark_menu_delegate_->GetDropOperation(item, event, position) : |
| 958 ui::DragDropTypes::DRAG_NONE; | 967 ui::DragDropTypes::DRAG_NONE; |
| 959 } | 968 } |
| 960 | 969 |
| 961 int WrenchMenu::OnPerformDrop(MenuItemView* menu, | 970 int WrenchMenu::OnPerformDrop(MenuItemView* menu, |
| 962 DropPosition position, | 971 DropPosition position, |
| 963 const ui::DropTargetEvent& event) { | 972 const ui::DropTargetEvent& event) { |
| 964 if (!is_bookmark_command(menu->GetCommand())) | 973 if (!IsBookmarkCommand(menu->GetCommand())) |
| 965 return ui::DragDropTypes::DRAG_NONE; | 974 return ui::DragDropTypes::DRAG_NONE; |
| 966 | 975 |
| 967 int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event); | 976 int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event); |
| 968 return result; | 977 return result; |
| 969 } | 978 } |
| 970 | 979 |
| 971 bool WrenchMenu::ShowContextMenu(MenuItemView* source, | 980 bool WrenchMenu::ShowContextMenu(MenuItemView* source, |
| 972 int id, | 981 int command_id, |
| 973 const gfx::Point& p, | 982 const gfx::Point& p, |
| 974 ui::MenuSourceType source_type) { | 983 ui::MenuSourceType source_type) { |
| 975 return is_bookmark_command(id) ? | 984 return IsBookmarkCommand(command_id) ? |
| 976 bookmark_menu_delegate_->ShowContextMenu(source, id, p, | 985 bookmark_menu_delegate_->ShowContextMenu(source, command_id, p, |
| 977 source_type) : | 986 source_type) : |
| 978 false; | 987 false; |
| 979 } | 988 } |
| 980 | 989 |
| 981 bool WrenchMenu::CanDrag(MenuItemView* menu) { | 990 bool WrenchMenu::CanDrag(MenuItemView* menu) { |
| 982 return is_bookmark_command(menu->GetCommand()) ? | 991 return IsBookmarkCommand(menu->GetCommand()) ? |
| 983 bookmark_menu_delegate_->CanDrag(menu) : false; | 992 bookmark_menu_delegate_->CanDrag(menu) : false; |
| 984 } | 993 } |
| 985 | 994 |
| 986 void WrenchMenu::WriteDragData(MenuItemView* sender, | 995 void WrenchMenu::WriteDragData(MenuItemView* sender, |
| 987 ui::OSExchangeData* data) { | 996 ui::OSExchangeData* data) { |
| 988 DCHECK(is_bookmark_command(sender->GetCommand())); | 997 DCHECK(IsBookmarkCommand(sender->GetCommand())); |
| 989 return bookmark_menu_delegate_->WriteDragData(sender, data); | 998 return bookmark_menu_delegate_->WriteDragData(sender, data); |
| 990 } | 999 } |
| 991 | 1000 |
| 992 int WrenchMenu::GetDragOperations(MenuItemView* sender) { | 1001 int WrenchMenu::GetDragOperations(MenuItemView* sender) { |
| 993 return is_bookmark_command(sender->GetCommand()) ? | 1002 return IsBookmarkCommand(sender->GetCommand()) ? |
| 994 bookmark_menu_delegate_->GetDragOperations(sender) : | 1003 bookmark_menu_delegate_->GetDragOperations(sender) : |
| 995 MenuDelegate::GetDragOperations(sender); | 1004 MenuDelegate::GetDragOperations(sender); |
| 996 } | 1005 } |
| 997 | 1006 |
| 998 int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) { | 1007 int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) { |
| 999 if (is_bookmark_command(menu->GetCommand())) | 1008 if (IsBookmarkCommand(menu->GetCommand())) |
| 1000 return bookmark_menu_delegate_->GetMaxWidthForMenu(menu); | 1009 return bookmark_menu_delegate_->GetMaxWidthForMenu(menu); |
| 1001 int max_width = -1; | 1010 int max_width = -1; |
| 1002 // If recent tabs menu is available, it will decide if |menu| is one of recent | 1011 // If recent tabs menu is available, it will decide if |menu| is one of recent |
| 1003 // tabs; if yes, it would return the menu width for recent tabs. | 1012 // tabs; if yes, it would return the menu width for recent tabs. |
| 1004 // otherwise, it would return -1. | 1013 // otherwise, it would return -1. |
| 1005 if (recent_tabs_menu_model_delegate_.get()) | 1014 if (recent_tabs_menu_model_delegate_.get()) |
| 1006 max_width = recent_tabs_menu_model_delegate_->GetMaxWidthForMenu(menu); | 1015 max_width = recent_tabs_menu_model_delegate_->GetMaxWidthForMenu(menu); |
| 1007 if (max_width == -1) | 1016 if (max_width == -1) |
| 1008 max_width = MenuDelegate::GetMaxWidthForMenu(menu); | 1017 max_width = MenuDelegate::GetMaxWidthForMenu(menu); |
| 1009 return max_width; | 1018 return max_width; |
| 1010 } | 1019 } |
| 1011 | 1020 |
| 1012 bool WrenchMenu::IsItemChecked(int id) const { | 1021 bool WrenchMenu::IsItemChecked(int command_id) const { |
| 1013 if (is_bookmark_command(id)) | 1022 if (IsBookmarkCommand(command_id)) |
| 1014 return false; | 1023 return false; |
| 1015 | 1024 |
| 1016 const Entry& entry = id_to_entry_.find(id)->second; | 1025 const Entry& entry = command_id_to_entry_.find(command_id)->second; |
| 1017 return entry.first->IsItemCheckedAt(entry.second); | 1026 return entry.first->IsItemCheckedAt(entry.second); |
| 1018 } | 1027 } |
| 1019 | 1028 |
| 1020 bool WrenchMenu::IsCommandEnabled(int id) const { | 1029 bool WrenchMenu::IsCommandEnabled(int command_id) const { |
| 1021 if (is_bookmark_command(id)) | 1030 if (IsBookmarkCommand(command_id)) |
| 1022 return true; | 1031 return true; |
| 1023 | 1032 |
| 1024 if (id == 0) | 1033 if (command_id == 0) |
| 1025 return false; // The root item. | 1034 return false; // The root item. |
| 1026 | 1035 |
| 1027 const Entry& entry = id_to_entry_.find(id)->second; | |
| 1028 int command_id = entry.first->GetCommandIdAt(entry.second); | |
| 1029 // The items representing the cut menu (cut/copy/paste) and zoom menu | 1036 // The items representing the cut menu (cut/copy/paste) and zoom menu |
| 1030 // (increment/decrement/reset) are always enabled. The child views of these | 1037 // (increment/decrement/reset) are always enabled. The child views of these |
| 1031 // items enabled state updates appropriately. | 1038 // items enabled state updates appropriately. |
| 1032 return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS || | 1039 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) |
| 1033 entry.first->IsEnabledAt(entry.second); | 1040 return true; |
| 1041 | |
| 1042 const Entry& entry = command_id_to_entry_.find(command_id)->second; | |
| 1043 return entry.first->IsEnabledAt(entry.second); | |
| 1034 } | 1044 } |
| 1035 | 1045 |
| 1036 void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) { | 1046 void WrenchMenu::ExecuteCommand(int command_id, int mouse_event_flags) { |
| 1037 if (is_bookmark_command(id)) { | 1047 if (IsBookmarkCommand(command_id)) { |
| 1038 bookmark_menu_delegate_->ExecuteCommand(id, mouse_event_flags); | 1048 bookmark_menu_delegate_->ExecuteCommand(command_id, mouse_event_flags); |
| 1039 return; | 1049 return; |
| 1040 } | 1050 } |
| 1041 | 1051 |
| 1042 // Not a bookmark | |
| 1043 const Entry& entry = id_to_entry_.find(id)->second; | |
| 1044 int command_id = entry.first->GetCommandIdAt(entry.second); | |
| 1045 | |
| 1046 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { | 1052 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { |
| 1047 // These items are represented by child views. If ExecuteCommand is invoked | 1053 // These items are represented by child views. If ExecuteCommand is invoked |
| 1048 // it means the user clicked on the area around the buttons and we should | 1054 // it means the user clicked on the area around the buttons and we should |
| 1049 // not do anyting. | 1055 // not do anyting. |
| 1050 return; | 1056 return; |
| 1051 } | 1057 } |
| 1052 | 1058 |
| 1059 const Entry& entry = command_id_to_entry_.find(command_id)->second; | |
| 1053 return entry.first->ActivatedAt(entry.second, mouse_event_flags); | 1060 return entry.first->ActivatedAt(entry.second, mouse_event_flags); |
| 1054 } | 1061 } |
| 1055 | 1062 |
| 1056 bool WrenchMenu::GetAccelerator(int id, ui::Accelerator* accelerator) { | 1063 bool WrenchMenu::GetAccelerator(int command_id, ui::Accelerator* accelerator) { |
| 1057 if (is_bookmark_command(id)) | 1064 if (IsBookmarkCommand(command_id)) |
| 1058 return false; | 1065 return false; |
| 1059 IDToEntry::iterator ix = id_to_entry_.find(id); | |
| 1060 if (ix == id_to_entry_.end()) { | |
| 1061 // There is no entry for this id. | |
| 1062 return false; | |
| 1063 } | |
| 1064 | 1066 |
| 1065 const Entry& entry = ix->second; | |
| 1066 int command_id = entry.first->GetCommandIdAt(entry.second); | |
| 1067 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { | 1067 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { |
| 1068 // These have special child views; don't show the accelerator for them. | 1068 // These have special child views; don't show the accelerator for them. |
| 1069 return false; | 1069 return false; |
| 1070 } | 1070 } |
| 1071 | 1071 |
| 1072 CommandIDToEntry::iterator ix = command_id_to_entry_.find(command_id); | |
| 1073 const Entry& entry = ix->second; | |
| 1072 ui::Accelerator menu_accelerator; | 1074 ui::Accelerator menu_accelerator; |
| 1073 if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator)) | 1075 if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator)) |
| 1074 return false; | 1076 return false; |
| 1075 | 1077 |
| 1076 *accelerator = ui::Accelerator(menu_accelerator.key_code(), | 1078 *accelerator = ui::Accelerator(menu_accelerator.key_code(), |
| 1077 menu_accelerator.modifiers()); | 1079 menu_accelerator.modifiers()); |
| 1078 return true; | 1080 return true; |
| 1079 } | 1081 } |
| 1080 | 1082 |
| 1081 void WrenchMenu::WillShowMenu(MenuItemView* menu) { | 1083 void WrenchMenu::WillShowMenu(MenuItemView* menu) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1111 // A change in the global errors list can add or remove items from the | 1113 // A change in the global errors list can add or remove items from the |
| 1112 // menu. Close the menu to avoid have a stale menu on-screen. | 1114 // menu. Close the menu to avoid have a stale menu on-screen. |
| 1113 root_->Cancel(); | 1115 root_->Cancel(); |
| 1114 break; | 1116 break; |
| 1115 default: | 1117 default: |
| 1116 NOTREACHED(); | 1118 NOTREACHED(); |
| 1117 } | 1119 } |
| 1118 } | 1120 } |
| 1119 | 1121 |
| 1120 void WrenchMenu::PopulateMenu(MenuItemView* parent, | 1122 void WrenchMenu::PopulateMenu(MenuItemView* parent, |
| 1121 MenuModel* model, | 1123 MenuModel* model) { |
| 1122 int* next_id) { | |
| 1123 for (int i = 0, max = model->GetItemCount(); i < max; ++i) { | 1124 for (int i = 0, max = model->GetItemCount(); i < max; ++i) { |
| 1124 // The button container menu items have a special height which we have to | 1125 // The button container menu items have a special height which we have to |
| 1125 // use instead of the normal height. | 1126 // use instead of the normal height. |
| 1126 int height = 0; | 1127 int height = 0; |
| 1127 if (use_new_menu_ && | 1128 if (use_new_menu_ && |
| 1128 (model->GetCommandIdAt(i) == IDC_CUT || | 1129 (model->GetCommandIdAt(i) == IDC_CUT || |
| 1129 model->GetCommandIdAt(i) == IDC_ZOOM_MINUS)) | 1130 model->GetCommandIdAt(i) == IDC_ZOOM_MINUS)) |
| 1130 height = kMenuItemContainingButtonsHeight; | 1131 height = kMenuItemContainingButtonsHeight; |
| 1131 | 1132 |
| 1132 MenuItemView* item = AppendMenuItem( | 1133 MenuItemView* item = AppendMenuItem( |
| 1133 parent, model, i, model->GetTypeAt(i), next_id, height); | 1134 parent, model, i, model->GetTypeAt(i), height); |
| 1134 | 1135 |
| 1135 if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) { | 1136 if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) |
| 1136 bool is_recent_tabs_menu = | 1137 PopulateMenu(item, model->GetSubmenuModelAt(i)); |
| 1137 model->GetCommandIdAt(i) == IDC_RECENT_TABS_MENU; | |
| 1138 if (is_recent_tabs_menu) | |
| 1139 first_recent_tabs_command_id_ = *next_id; | |
| 1140 PopulateMenu(item, model->GetSubmenuModelAt(i), next_id); | |
| 1141 if (is_recent_tabs_menu) | |
| 1142 last_recent_tabs_command_id_ = *next_id - 1; | |
| 1143 } | |
| 1144 | 1138 |
| 1145 const ui::NativeTheme* native_theme = GetNativeTheme(); | 1139 const ui::NativeTheme* native_theme = GetNativeTheme(); |
| 1146 | 1140 |
| 1147 switch (model->GetCommandIdAt(i)) { | 1141 switch (model->GetCommandIdAt(i)) { |
| 1148 case IDC_CUT: | 1142 case IDC_CUT: |
| 1149 DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i)); | 1143 DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i)); |
| 1150 DCHECK_LT(i + 2, max); | 1144 DCHECK_LT(i + 2, max); |
| 1151 DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(i + 1)); | 1145 DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(i + 1)); |
| 1152 DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(i + 2)); | 1146 DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(i + 2)); |
| 1153 item->SetTitle(l10n_util::GetStringUTF16(IDS_EDIT2)); | 1147 item->SetTitle(l10n_util::GetStringUTF16(IDS_EDIT2)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1188 default: | 1182 default: |
| 1189 break; | 1183 break; |
| 1190 } | 1184 } |
| 1191 } | 1185 } |
| 1192 } | 1186 } |
| 1193 | 1187 |
| 1194 MenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent, | 1188 MenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent, |
| 1195 MenuModel* model, | 1189 MenuModel* model, |
| 1196 int index, | 1190 int index, |
| 1197 MenuModel::ItemType menu_type, | 1191 MenuModel::ItemType menu_type, |
| 1198 int* next_id, | |
| 1199 int height) { | 1192 int height) { |
| 1200 int id = (*next_id)++; | 1193 int command_id = model->GetCommandIdAt(index); |
| 1194 DCHECK(command_id > -1 || | |
| 1195 (command_id == -1 && | |
| 1196 model->GetTypeAt(index) == MenuModel::TYPE_SEPARATOR)); | |
| 1201 | 1197 |
| 1202 id_to_entry_[id].first = model; | 1198 if (command_id > -1) { // Don't add separators to |command_id_to_entry_|. |
| 1203 id_to_entry_[id].second = index; | 1199 // All command ID's should be unique except for IDC_SHOW_HISTORY which is |
| 1200 // in both wrench menu and RecentTabs submenu, | |
| 1201 if (command_id != IDC_SHOW_HISTORY) { | |
| 1202 DCHECK(command_id_to_entry_.find(command_id) == | |
| 1203 command_id_to_entry_.end()) | |
| 1204 << "command ID " << command_id << " already exists!"; | |
| 1205 } | |
| 1206 command_id_to_entry_[command_id].first = model; | |
| 1207 command_id_to_entry_[command_id].second = index; | |
| 1208 } | |
| 1204 | 1209 |
| 1205 MenuItemView* menu_item = NULL; | 1210 MenuItemView* menu_item = NULL; |
| 1206 if (height > 0) { | 1211 if (height > 0) { |
| 1207 // For menu items with a special menu height we use our special class to be | 1212 // For menu items with a special menu height we use our special class to be |
| 1208 // able to modify the item height. | 1213 // able to modify the item height. |
| 1209 menu_item = new ButtonContainerMenuItemView(parent, id, height); | 1214 menu_item = new ButtonContainerMenuItemView(parent, command_id, height); |
| 1210 parent->GetSubmenu()->AddChildView(menu_item); | 1215 parent->GetSubmenu()->AddChildView(menu_item); |
| 1211 } else { | 1216 } else { |
| 1212 // For all other cases we use the more generic way to add menu items. | 1217 // For all other cases we use the more generic way to add menu items. |
| 1213 menu_item = views::MenuModelAdapter::AppendMenuItemFromModel( | 1218 menu_item = views::MenuModelAdapter::AppendMenuItemFromModel( |
| 1214 model, index, parent, id); | 1219 model, index, parent, command_id); |
| 1215 } | 1220 } |
| 1216 | 1221 |
| 1217 if (menu_item) { | 1222 if (menu_item) { |
| 1218 // Flush all buttons to the right side of the menu for the new menu type. | 1223 // Flush all buttons to the right side of the menu for the new menu type. |
| 1219 menu_item->set_use_right_margin(!use_new_menu_); | 1224 menu_item->set_use_right_margin(!use_new_menu_); |
| 1220 menu_item->SetVisible(model->IsVisibleAt(index)); | 1225 menu_item->SetVisible(model->IsVisibleAt(index)); |
| 1221 | 1226 |
| 1222 if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) { | 1227 if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) { |
| 1223 gfx::Image icon; | 1228 gfx::Image icon; |
| 1224 if (model->GetIconAt(index, &icon)) | 1229 if (model->GetIconAt(index, &icon)) |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1246 | 1251 |
| 1247 model->AddObserver(this); | 1252 model->AddObserver(this); |
| 1248 | 1253 |
| 1249 // TODO(oshima): Replace with views only API. | 1254 // TODO(oshima): Replace with views only API. |
| 1250 views::Widget* parent = views::Widget::GetWidgetForNativeWindow( | 1255 views::Widget* parent = views::Widget::GetWidgetForNativeWindow( |
| 1251 browser_->window()->GetNativeWindow()); | 1256 browser_->window()->GetNativeWindow()); |
| 1252 bookmark_menu_delegate_.reset( | 1257 bookmark_menu_delegate_.reset( |
| 1253 new BookmarkMenuDelegate(browser_, | 1258 new BookmarkMenuDelegate(browser_, |
| 1254 browser_, | 1259 browser_, |
| 1255 parent, | 1260 parent, |
| 1256 first_bookmark_command_id_)); | 1261 WrenchMenuModel::kMinBookmarkCommandId, |
| 1262 WrenchMenuModel::kMaxBookmarkCommandId)); | |
|
kuan
2013/10/08 09:53:31
pass in max menu id.
| |
| 1257 bookmark_menu_delegate_->Init(this, | 1263 bookmark_menu_delegate_->Init(this, |
| 1258 bookmark_menu_, | 1264 bookmark_menu_, |
| 1259 model->bookmark_bar_node(), | 1265 model->bookmark_bar_node(), |
| 1260 0, | 1266 0, |
| 1261 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS, | 1267 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS, |
| 1262 BOOKMARK_LAUNCH_LOCATION_WRENCH_MENU); | 1268 BOOKMARK_LAUNCH_LOCATION_WRENCH_MENU); |
| 1263 } | 1269 } |
| 1270 | |
| 1271 int WrenchMenu::ModelIndexFromCommandId(int command_id) const { | |
| 1272 CommandIDToEntry::const_iterator ix = command_id_to_entry_.find(command_id); | |
| 1273 DCHECK(ix != command_id_to_entry_.end()); | |
| 1274 return ix->second.second; | |
| 1275 } | |
| OLD | NEW |