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

Side by Side Diff: chrome/browser/ui/views/wrench_menu.cc

Issue 23530070: backup for dynamic recent tabs submenu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: new RecentTabsMenuModelDelegate w/ new intf Created 7 years, 2 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
« no previous file with comments | « chrome/browser/ui/views/wrench_menu.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/search/search.h" 18 #include "chrome/browser/search/search.h"
19 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_window.h" 20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
22 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h" 23 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
24 #include "chrome/browser/ui/views/recent_tabs_menu_model_delegate.h"
23 #include "chrome/browser/ui/views/wrench_menu_observer.h" 25 #include "chrome/browser/ui/views/wrench_menu_observer.h"
24 #include "content/public/browser/host_zoom_map.h" 26 #include "content/public/browser/host_zoom_map.h"
25 #include "content/public/browser/notification_observer.h" 27 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h" 28 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_source.h" 29 #include "content/public/browser/notification_source.h"
28 #include "content/public/browser/notification_types.h" 30 #include "content/public/browser/notification_types.h"
29 #include "content/public/browser/user_metrics.h" 31 #include "content/public/browser/user_metrics.h"
30 #include "content/public/browser/web_contents.h" 32 #include "content/public/browser/web_contents.h"
31 #include "grit/chromium_strings.h" 33 #include "grit/chromium_strings.h"
32 #include "grit/generated_resources.h" 34 #include "grit/generated_resources.h"
33 #include "grit/theme_resources.h" 35 #include "grit/theme_resources.h"
34 #include "third_party/skia/include/core/SkCanvas.h" 36 #include "third_party/skia/include/core/SkCanvas.h"
35 #include "third_party/skia/include/core/SkPaint.h" 37 #include "third_party/skia/include/core/SkPaint.h"
36 #include "ui/base/l10n/l10n_util.h" 38 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/layout.h" 39 #include "ui/base/layout.h"
38 #include "ui/base/resource/resource_bundle.h" 40 #include "ui/base/resource/resource_bundle.h"
39 #include "ui/gfx/canvas.h" 41 #include "ui/gfx/canvas.h"
40 #include "ui/gfx/image/canvas_image_source.h" 42 #include "ui/gfx/image/canvas_image_source.h"
41 #include "ui/gfx/image/image.h" 43 #include "ui/gfx/image/image.h"
42 #include "ui/gfx/skia_util.h" 44 #include "ui/gfx/skia_util.h"
43 #include "ui/gfx/text_utils.h" 45 #include "ui/gfx/text_utils.h"
44 #include "ui/views/background.h" 46 #include "ui/views/background.h"
45 #include "ui/views/controls/button/image_button.h" 47 #include "ui/views/controls/button/image_button.h"
46 #include "ui/views/controls/button/label_button.h" 48 #include "ui/views/controls/button/label_button.h"
47 #include "ui/views/controls/button/menu_button.h" 49 #include "ui/views/controls/button/menu_button.h"
48 #include "ui/views/controls/label.h" 50 #include "ui/views/controls/label.h"
49 #include "ui/views/controls/menu/menu_config.h" 51 #include "ui/views/controls/menu/menu_config.h"
50 #include "ui/views/controls/menu/menu_item_view.h" 52 #include "ui/views/controls/menu/menu_item_view.h"
53 #include "ui/views/controls/menu/menu_model_adapter.h"
51 #include "ui/views/controls/menu/menu_runner.h" 54 #include "ui/views/controls/menu/menu_runner.h"
52 #include "ui/views/controls/menu/menu_scroll_view_container.h" 55 #include "ui/views/controls/menu/menu_scroll_view_container.h"
53 #include "ui/views/controls/menu/submenu_view.h" 56 #include "ui/views/controls/menu/submenu_view.h"
54 #include "ui/views/widget/widget.h" 57 #include "ui/views/widget/widget.h"
55 58
56 #if defined(USE_AURA) 59 #if defined(USE_AURA)
57 #include "ui/native_theme/native_theme_aura.h" 60 #include "ui/native_theme/native_theme_aura.h"
58 #endif 61 #endif
59 62
60 using content::HostZoomMap; 63 using content::HostZoomMap;
(...skipping 18 matching lines...) Expand all
79 const SkColor kTouchButtonText = 0xff5a5a5a; 82 const SkColor kTouchButtonText = 0xff5a5a5a;
80 83
81 // Horizontal padding on the edges of the buttons. 84 // Horizontal padding on the edges of the buttons.
82 const int kHorizontalPadding = 6; 85 const int kHorizontalPadding = 6;
83 // Horizontal padding for a touch enabled menu. 86 // Horizontal padding for a touch enabled menu.
84 const int kHorizontalTouchPadding = 15; 87 const int kHorizontalTouchPadding = 15;
85 88
86 // 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.
87 const int kMenuItemContainingButtonsHeight = 43; 90 const int kMenuItemContainingButtonsHeight = 43;
88 91
92 // First ID to use for the items in the recent tabs submenu, must be more than
93 // maximum possible number of items in wrench menu and all its submenus except
94 // recent babs submenu.
95 const int kFirstRecentTabsCommandId = 200;
96
97 // First ID to use for the items representing bookmarks in the bookmark menu,
98 // must be more than kFirstRecentTabsCommandId + maximum possible number of
99 // items in recent tabs submenu.
100 const int kFirstBookmarkCommandId = 400;
101
89 // Subclass of ImageButton whose preferred size includes the size of the border. 102 // Subclass of ImageButton whose preferred size includes the size of the border.
90 class FullscreenButton : public ImageButton { 103 class FullscreenButton : public ImageButton {
91 public: 104 public:
92 explicit FullscreenButton(views::ButtonListener* listener) 105 explicit FullscreenButton(views::ButtonListener* listener)
93 : ImageButton(listener) { } 106 : ImageButton(listener) { }
94 107
95 // Overridden from ImageButton. 108 // Overridden from ImageButton.
96 virtual gfx::Size GetPreferredSize() OVERRIDE { 109 virtual gfx::Size GetPreferredSize() OVERRIDE {
97 gfx::Size pref = ImageButton::GetPreferredSize(); 110 gfx::Size pref = ImageButton::GetPreferredSize();
98 if (border()) { 111 if (border()) {
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 LabelButton* decrement_button_; 762 LabelButton* decrement_button_;
750 763
751 ImageButton* fullscreen_button_; 764 ImageButton* fullscreen_button_;
752 765
753 // Width given to |zoom_label_|. This is the width at 100%. 766 // Width given to |zoom_label_|. This is the width at 100%.
754 int zoom_label_width_; 767 int zoom_label_width_;
755 768
756 DISALLOW_COPY_AND_ASSIGN(ZoomView); 769 DISALLOW_COPY_AND_ASSIGN(ZoomView);
757 }; 770 };
758 771
759 // RecentTabsMenuModelDelegate -------------------------------------------------
760
761 // Provides the ui::MenuModelDelegate implementation for RecentTabsSubMenuModel
762 // items.
763 class WrenchMenu::RecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
764 public:
765 RecentTabsMenuModelDelegate(ui::MenuModel* model,
766 views::MenuItemView* menu_item)
767 : model_(model),
768 menu_item_(menu_item) {
769 model_->SetMenuModelDelegate(this);
770 }
771
772 virtual ~RecentTabsMenuModelDelegate() {
773 model_->SetMenuModelDelegate(NULL);
774 }
775
776 // ui::MenuModelDelegate implementation:
777 virtual void OnIconChanged(int index) OVERRIDE {
778 // |index| specifies position in children items of |menu_item_| starting at
779 // 0, its corresponding command id as used in the children menu item views
780 // follows that of the parent menu item view |menu_item_|.
781 int command_id = menu_item_->GetCommand() + 1 + index;
782 views::MenuItemView* item = menu_item_->GetMenuItemByID(command_id);
783 DCHECK(item);
784 gfx::Image icon;
785 if (model_->GetIconAt(index, &icon))
786 item->SetIcon(*icon.ToImageSkia());
787 }
788
789 // Return the specific menu width of recent tab menu item if |command_id|
790 // refers to one of recent tabs menu items, else return -1.
791 int GetMaxWidthForMenu(MenuItemView* menu) {
792 views::SubmenuView* submenu = menu_item_->GetSubmenu();
793 if (!submenu)
794 return -1;
795 const int kMaxMenuItemWidth = 320;
796 return menu->GetCommand() >= menu_item_->GetCommand() &&
797 menu->GetCommand() <=
798 menu_item_->GetCommand() + submenu->GetMenuItemCount() ?
799 kMaxMenuItemWidth : -1;
800 }
801
802 const gfx::Font* GetLabelFontAt(int index) const {
803 return model_->GetLabelFontAt(index);
804 }
805
806 bool GetForegroundColor(int command_id,
807 bool is_hovered,
808 SkColor* override_color) const {
809 // The items for which we get a font, should be shown in black.
810 if (GetLabelFontAt(command_id)) {
811 *override_color = SK_ColorBLACK;
812 return true;
813 }
814 return false;
815 }
816
817 private:
818 ui::MenuModel* model_;
819 views::MenuItemView* menu_item_;
820
821 DISALLOW_COPY_AND_ASSIGN(RecentTabsMenuModelDelegate);
822 };
823
824 // WrenchMenu ------------------------------------------------------------------ 772 // WrenchMenu ------------------------------------------------------------------
825 773
826 WrenchMenu::WrenchMenu(Browser* browser, 774 WrenchMenu::WrenchMenu(Browser* browser,
827 bool use_new_menu, 775 bool use_new_menu,
828 bool supports_new_separators) 776 bool supports_new_separators)
829 : root_(NULL), 777 : root_(NULL),
830 browser_(browser), 778 browser_(browser),
831 selected_menu_model_(NULL), 779 selected_menu_model_(NULL),
832 selected_index_(0), 780 selected_index_(0),
833 bookmark_menu_(NULL), 781 bookmark_menu_(NULL),
834 feedback_menu_item_(NULL), 782 feedback_menu_item_(NULL),
835 first_bookmark_command_id_(0),
836 first_recent_tabs_command_id_(-1),
837 last_recent_tabs_command_id_(-1),
838 use_new_menu_(use_new_menu), 783 use_new_menu_(use_new_menu),
839 supports_new_separators_(supports_new_separators) { 784 supports_new_separators_(supports_new_separators) {
840 registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, 785 registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
841 content::Source<Profile>(browser_->profile())); 786 content::Source<Profile>(browser_->profile()));
842 } 787 }
843 788
844 WrenchMenu::~WrenchMenu() { 789 WrenchMenu::~WrenchMenu() {
845 if (bookmark_menu_delegate_.get()) { 790 if (bookmark_menu_delegate_.get()) {
846 BookmarkModel* model = BookmarkModelFactory::GetForProfile( 791 BookmarkModel* model = BookmarkModelFactory::GetForProfile(
847 browser_->profile()); 792 browser_->profile());
848 if (model) 793 if (model)
849 model->RemoveObserver(this); 794 model->RemoveObserver(this);
850 } 795 }
851 FOR_EACH_OBSERVER(WrenchMenuObserver, observer_list_, WrenchMenuDestroyed()); 796 FOR_EACH_OBSERVER(WrenchMenuObserver, observer_list_, WrenchMenuDestroyed());
852 } 797 }
853 798
854 void WrenchMenu::Init(ui::MenuModel* model) { 799 void WrenchMenu::Init(ui::MenuModel* model) {
855 DCHECK(!root_); 800 DCHECK(!root_);
856 root_ = new MenuItemView(this); 801 root_ = new MenuItemView(this);
857 root_->set_has_icons(true); // We have checks, radios and icons, set this 802 root_->set_has_icons(true); // We have checks, radios and icons, set this
858 // so we get the taller menu style. 803 // so we get the taller menu style.
859 int next_id = 1; 804 int next_id = 1;
860 PopulateMenu(root_, model, &next_id); 805 PopulateMenu(root_, model, &next_id);
861 first_bookmark_command_id_ = next_id + 1; 806 DCHECK_LT(next_id, kFirstRecentTabsCommandId);
862 menu_runner_.reset(new views::MenuRunner(root_)); 807 menu_runner_.reset(new views::MenuRunner(root_));
863 } 808 }
864 809
865 void WrenchMenu::RunMenu(views::MenuButton* host) { 810 void WrenchMenu::RunMenu(views::MenuButton* host) {
866 gfx::Point screen_loc; 811 gfx::Point screen_loc;
867 views::View::ConvertPointToScreen(host, &screen_loc); 812 views::View::ConvertPointToScreen(host, &screen_loc);
868 gfx::Rect bounds(screen_loc, host->size()); 813 gfx::Rect bounds(screen_loc, host->size());
869 content::RecordAction(UserMetricsAction("ShowAppMenu")); 814 content::RecordAction(UserMetricsAction("ShowAppMenu"));
870 if (menu_runner_->RunMenuAt(host->GetWidget(), host, bounds, 815 if (menu_runner_->RunMenuAt(host->GetWidget(), host, bounds,
871 MenuItemView::TOPRIGHT, ui::MENU_SOURCE_NONE, 816 MenuItemView::TOPRIGHT, ui::MENU_SOURCE_NONE,
(...skipping 26 matching lines...) Expand all
898 } 843 }
899 844
900 void WrenchMenu::AddObserver(WrenchMenuObserver* observer) { 845 void WrenchMenu::AddObserver(WrenchMenuObserver* observer) {
901 observer_list_.AddObserver(observer); 846 observer_list_.AddObserver(observer);
902 } 847 }
903 848
904 void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) { 849 void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) {
905 observer_list_.RemoveObserver(observer); 850 observer_list_.RemoveObserver(observer);
906 } 851 }
907 852
908 const gfx::Font* WrenchMenu::GetLabelFont(int index) const { 853 const gfx::Font* WrenchMenu::GetLabelFont(int id) const {
909 if (is_recent_tabs_command(index)) { 854 return IsRecentTabsCommand(id) ?
910 return recent_tabs_menu_model_delegate_->GetLabelFontAt( 855 recent_tabs_menu_model_delegate_->GetLabelFontAt(id) : NULL;
911 index - first_recent_tabs_command_id_);
912 }
913 return NULL;
914 } 856 }
915 857
916 bool WrenchMenu::GetForegroundColor(int command_id, 858 bool WrenchMenu::GetForegroundColor(int command_id,
917 bool is_hovered, 859 bool is_hovered,
918 SkColor* override_color) const { 860 SkColor* override_color) const {
919 if (is_recent_tabs_command(command_id)) { 861 if (IsRecentTabsCommand(command_id)) {
920 return recent_tabs_menu_model_delegate_->GetForegroundColor( 862 return recent_tabs_menu_model_delegate_->GetForegroundColor(
921 command_id - first_recent_tabs_command_id_, 863 command_id,
922 is_hovered, 864 is_hovered,
923 override_color); 865 override_color);
924 } 866 }
925 return false; 867 return false;
926 } 868 }
927 869
928 string16 WrenchMenu::GetTooltipText(int id, 870 string16 WrenchMenu::GetTooltipText(int id,
929 const gfx::Point& p) const { 871 const gfx::Point& p) const {
930 return is_bookmark_command(id) ? 872 return IsBookmarkCommand(id) ?
931 bookmark_menu_delegate_->GetTooltipText(id, p) : string16(); 873 bookmark_menu_delegate_->GetTooltipText(id, p) : string16();
932 } 874 }
933 875
934 bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu, 876 bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu,
935 const ui::Event& e) { 877 const ui::Event& e) {
936 return is_bookmark_command(menu->GetCommand()) ? 878 return IsBookmarkCommand(menu->GetCommand()) ?
937 bookmark_menu_delegate_->IsTriggerableEvent(menu, e) : 879 bookmark_menu_delegate_->IsTriggerableEvent(menu, e) :
938 MenuDelegate::IsTriggerableEvent(menu, e); 880 MenuDelegate::IsTriggerableEvent(menu, e);
939 } 881 }
940 882
941 bool WrenchMenu::GetDropFormats( 883 bool WrenchMenu::GetDropFormats(
942 MenuItemView* menu, 884 MenuItemView* menu,
943 int* formats, 885 int* formats,
944 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { 886 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) {
945 CreateBookmarkMenu(); 887 CreateBookmarkMenu();
946 return bookmark_menu_delegate_.get() && 888 return bookmark_menu_delegate_.get() &&
(...skipping 10 matching lines...) Expand all
957 const ui::OSExchangeData& data) { 899 const ui::OSExchangeData& data) {
958 CreateBookmarkMenu(); 900 CreateBookmarkMenu();
959 return bookmark_menu_delegate_.get() && 901 return bookmark_menu_delegate_.get() &&
960 bookmark_menu_delegate_->CanDrop(menu, data); 902 bookmark_menu_delegate_->CanDrop(menu, data);
961 } 903 }
962 904
963 int WrenchMenu::GetDropOperation( 905 int WrenchMenu::GetDropOperation(
964 MenuItemView* item, 906 MenuItemView* item,
965 const ui::DropTargetEvent& event, 907 const ui::DropTargetEvent& event,
966 DropPosition* position) { 908 DropPosition* position) {
967 return is_bookmark_command(item->GetCommand()) ? 909 return IsBookmarkCommand(item->GetCommand()) ?
968 bookmark_menu_delegate_->GetDropOperation(item, event, position) : 910 bookmark_menu_delegate_->GetDropOperation(item, event, position) :
969 ui::DragDropTypes::DRAG_NONE; 911 ui::DragDropTypes::DRAG_NONE;
970 } 912 }
971 913
972 int WrenchMenu::OnPerformDrop(MenuItemView* menu, 914 int WrenchMenu::OnPerformDrop(MenuItemView* menu,
973 DropPosition position, 915 DropPosition position,
974 const ui::DropTargetEvent& event) { 916 const ui::DropTargetEvent& event) {
975 if (!is_bookmark_command(menu->GetCommand())) 917 if (!IsBookmarkCommand(menu->GetCommand()))
976 return ui::DragDropTypes::DRAG_NONE; 918 return ui::DragDropTypes::DRAG_NONE;
977 919
978 int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event); 920 int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event);
979 return result; 921 return result;
980 } 922 }
981 923
982 bool WrenchMenu::ShowContextMenu(MenuItemView* source, 924 bool WrenchMenu::ShowContextMenu(MenuItemView* source,
983 int id, 925 int id,
984 const gfx::Point& p, 926 const gfx::Point& p,
985 ui::MenuSourceType source_type) { 927 ui::MenuSourceType source_type) {
986 return is_bookmark_command(id) ? 928 return IsBookmarkCommand(id) ?
987 bookmark_menu_delegate_->ShowContextMenu(source, id, p, 929 bookmark_menu_delegate_->ShowContextMenu(source, id, p,
988 source_type) : 930 source_type) :
989 false; 931 false;
990 } 932 }
991 933
992 bool WrenchMenu::CanDrag(MenuItemView* menu) { 934 bool WrenchMenu::CanDrag(MenuItemView* menu) {
993 return is_bookmark_command(menu->GetCommand()) ? 935 return IsBookmarkCommand(menu->GetCommand()) ?
994 bookmark_menu_delegate_->CanDrag(menu) : false; 936 bookmark_menu_delegate_->CanDrag(menu) : false;
995 } 937 }
996 938
997 void WrenchMenu::WriteDragData(MenuItemView* sender, 939 void WrenchMenu::WriteDragData(MenuItemView* sender,
998 ui::OSExchangeData* data) { 940 ui::OSExchangeData* data) {
999 DCHECK(is_bookmark_command(sender->GetCommand())); 941 DCHECK(IsBookmarkCommand(sender->GetCommand()));
1000 return bookmark_menu_delegate_->WriteDragData(sender, data); 942 return bookmark_menu_delegate_->WriteDragData(sender, data);
1001 } 943 }
1002 944
1003 int WrenchMenu::GetDragOperations(MenuItemView* sender) { 945 int WrenchMenu::GetDragOperations(MenuItemView* sender) {
1004 return is_bookmark_command(sender->GetCommand()) ? 946 return IsBookmarkCommand(sender->GetCommand()) ?
1005 bookmark_menu_delegate_->GetDragOperations(sender) : 947 bookmark_menu_delegate_->GetDragOperations(sender) :
1006 MenuDelegate::GetDragOperations(sender); 948 MenuDelegate::GetDragOperations(sender);
1007 } 949 }
1008 950
1009 int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) { 951 int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) {
1010 if (is_bookmark_command(menu->GetCommand())) 952 if (IsBookmarkCommand(menu->GetCommand()))
1011 return bookmark_menu_delegate_->GetMaxWidthForMenu(menu); 953 return bookmark_menu_delegate_->GetMaxWidthForMenu(menu);
1012 int max_width = -1; 954 int max_width = -1;
1013 // If recent tabs menu is available, it will decide if |menu| is one of recent 955 // If recent tabs menu is available, it will decide if |menu| is one of recent
1014 // tabs; if yes, it would return the menu width for recent tabs. 956 // tabs; if yes, it would return the menu width for recent tabs.
1015 // otherwise, it would return -1. 957 // otherwise, it would return -1.
1016 if (recent_tabs_menu_model_delegate_.get()) 958 if (recent_tabs_menu_model_delegate_.get())
1017 max_width = recent_tabs_menu_model_delegate_->GetMaxWidthForMenu(menu); 959 max_width = recent_tabs_menu_model_delegate_->GetMaxWidthForMenu(menu);
1018 if (max_width == -1) 960 if (max_width == -1)
1019 max_width = MenuDelegate::GetMaxWidthForMenu(menu); 961 max_width = MenuDelegate::GetMaxWidthForMenu(menu);
1020 return max_width; 962 return max_width;
1021 } 963 }
1022 964
1023 bool WrenchMenu::IsItemChecked(int id) const { 965 bool WrenchMenu::IsItemChecked(int id) const {
1024 if (is_bookmark_command(id)) 966 if (IsBookmarkCommand(id))
1025 return false; 967 return false;
1026 968
1027 const Entry& entry = id_to_entry_.find(id)->second; 969 const Entry& entry = id_to_entry_.find(id)->second;
1028 return entry.first->IsItemCheckedAt(entry.second); 970 return entry.first->IsItemCheckedAt(entry.second);
1029 } 971 }
1030 972
1031 bool WrenchMenu::IsCommandEnabled(int id) const { 973 bool WrenchMenu::IsCommandEnabled(int id) const {
1032 if (is_bookmark_command(id)) 974 if (IsBookmarkCommand(id))
1033 return true; 975 return true;
1034 976
1035 if (id == 0) 977 if (id == 0)
1036 return false; // The root item. 978 return false; // The root item.
1037 979
1038 const Entry& entry = id_to_entry_.find(id)->second; 980 const Entry& entry = id_to_entry_.find(id)->second;
1039 int command_id = entry.first->GetCommandIdAt(entry.second); 981 int command_id = entry.first->GetCommandIdAt(entry.second);
1040 // The items representing the cut menu (cut/copy/paste) and zoom menu 982 // The items representing the cut menu (cut/copy/paste) and zoom menu
1041 // (increment/decrement/reset) are always enabled. The child views of these 983 // (increment/decrement/reset) are always enabled. The child views of these
1042 // items enabled state updates appropriately. 984 // items enabled state updates appropriately.
1043 return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS || 985 return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
1044 entry.first->IsEnabledAt(entry.second); 986 entry.first->IsEnabledAt(entry.second);
1045 } 987 }
1046 988
1047 void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) { 989 void WrenchMenu::ExecuteCommand(int id, int mouse_event_flags) {
1048 if (is_bookmark_command(id)) { 990 if (IsBookmarkCommand(id)) {
1049 bookmark_menu_delegate_->ExecuteCommand(id, mouse_event_flags); 991 bookmark_menu_delegate_->ExecuteCommand(id, mouse_event_flags);
1050 return; 992 return;
1051 } 993 }
1052 994
1053 // Not a bookmark 995 // Not a bookmark
1054 const Entry& entry = id_to_entry_.find(id)->second; 996 const Entry& entry = id_to_entry_.find(id)->second;
1055 int command_id = entry.first->GetCommandIdAt(entry.second); 997 int command_id = entry.first->GetCommandIdAt(entry.second);
1056 998
1057 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { 999 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
1058 // These items are represented by child views. If ExecuteCommand is invoked 1000 // These items are represented by child views. If ExecuteCommand is invoked
1059 // it means the user clicked on the area around the buttons and we should 1001 // it means the user clicked on the area around the buttons and we should
1060 // not do anyting. 1002 // not do anyting.
1061 return; 1003 return;
1062 } 1004 }
1063 1005
1064 return entry.first->ActivatedAt(entry.second, mouse_event_flags); 1006 return entry.first->ActivatedAt(entry.second, mouse_event_flags);
1065 } 1007 }
1066 1008
1067 bool WrenchMenu::GetAccelerator(int id, ui::Accelerator* accelerator) { 1009 bool WrenchMenu::GetAccelerator(int id, ui::Accelerator* accelerator) {
1068 if (is_bookmark_command(id)) 1010 if (IsBookmarkCommand(id))
1069 return false; 1011 return false;
1070 IDToEntry::iterator ix = id_to_entry_.find(id); 1012 IDToEntry::iterator ix = id_to_entry_.find(id);
1071 if (ix == id_to_entry_.end()) { 1013 if (ix == id_to_entry_.end()) {
1072 // There is no entry for this id. 1014 // There is no entry for this id.
1073 return false; 1015 return false;
1074 } 1016 }
1075 1017
1076 const Entry& entry = ix->second; 1018 const Entry& entry = ix->second;
1077 int command_id = entry.first->GetCommandIdAt(entry.second); 1019 int command_id = entry.first->GetCommandIdAt(entry.second);
1078 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) { 1020 if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
(...skipping 22 matching lines...) Expand all
1101 if (menu->HasSubmenu() && feedback_menu_item_ && 1043 if (menu->HasSubmenu() && feedback_menu_item_ &&
1102 feedback_menu_item_->IsSelected()) { 1044 feedback_menu_item_->IsSelected()) {
1103 // It's okay to just turn off the animation and no to take care the 1045 // It's okay to just turn off the animation and no to take care the
1104 // animation back because the menu widget will be recreated next time 1046 // animation back because the menu widget will be recreated next time
1105 // it's opened. See ToolbarView::RunMenu() and Init() of this class. 1047 // it's opened. See ToolbarView::RunMenu() and Init() of this class.
1106 menu->GetSubmenu()->GetWidget()-> 1048 menu->GetSubmenu()->GetWidget()->
1107 SetVisibilityChangedAnimationsEnabled(false); 1049 SetVisibilityChangedAnimationsEnabled(false);
1108 } 1050 }
1109 } 1051 }
1110 1052
1053 void WrenchMenu::OnItemAdded(MenuItemView* parent,
1054 int menu_index,
1055 ui::MenuModel* model,
1056 int model_index,
1057 int item_id) {
1058 int id = item_id;
1059 AddMenuItem(parent, menu_index, model,
1060 model_index, model->GetTypeAt(model_index),
1061 &id, 0);
1062 }
1063
1064 void WrenchMenu::OnItemRemoved(MenuItemView* parent, int menu_index,
1065 int item_id) {
1066 parent->RemoveMenuItemAt(menu_index);
1067 id_to_entry_.erase(item_id);
1068 }
1069
1070 void WrenchMenu::UpdateMapOfMenuItemIdAndModel(ui::MenuModel* model,
1071 std::vector<int>& item_ids) {
1072 for (int i = 0; i < static_cast<int>(item_ids.size()); ++i) {
1073 int id = item_ids[i];
1074 CHECK(id_to_entry_[id].first == model); // kk
1075 if (id_to_entry_[id].second != i)
1076 {
1077 LOG(ERROR) << "kk chnged: map[" << id << "] = {" << id_to_entry_[id].first << ", " << id_to_entry_[id].second << "}, idx=" << i;
1078 id_to_entry_[id].second = i;
1079 }
1080 }
1081
1082 //#if defined(DEBUG) // kk
1083 // Verify that all mappings between id and index is unique i.e. 1-1.
1084 std::vector<bool> id_exists;
1085 id_exists.resize(model->GetItemCount(), false);
1086 for (IDToEntry::const_iterator iter = id_to_entry_.begin();
1087 iter != id_to_entry_.end(); ++iter) {
1088 const Entry& entry = iter->second;
1089 if (entry.first != model)
1090 continue;
1091 CHECK(!id_exists[entry.second]) // kk
1092 << "id_to_map[" << iter->first << "].index = " << entry.second
1093 << " already exists!";
1094 LOG(ERROR) << "id_to_map[" << iter->first << "].index = " << entry.second;
1095 id_exists[entry.second] = true;
1096 }
1097 // #endif // defined(DEBUG) // kk
1098 }
1099
1111 void WrenchMenu::BookmarkModelChanged() { 1100 void WrenchMenu::BookmarkModelChanged() {
1112 DCHECK(bookmark_menu_delegate_.get()); 1101 DCHECK(bookmark_menu_delegate_.get());
1113 if (!bookmark_menu_delegate_->is_mutating_model()) 1102 if (!bookmark_menu_delegate_->is_mutating_model())
1114 root_->Cancel(); 1103 root_->Cancel();
1115 } 1104 }
1116 1105
1117 void WrenchMenu::Observe(int type, 1106 void WrenchMenu::Observe(int type,
1118 const content::NotificationSource& source, 1107 const content::NotificationSource& source,
1119 const content::NotificationDetails& details) { 1108 const content::NotificationDetails& details) {
1120 switch (type) { 1109 switch (type) {
(...skipping 12 matching lines...) Expand all
1133 int* next_id) { 1122 int* next_id) {
1134 for (int i = 0, max = model->GetItemCount(); i < max; ++i) { 1123 for (int i = 0, max = model->GetItemCount(); i < max; ++i) {
1135 // The button container menu items have a special height which we have to 1124 // The button container menu items have a special height which we have to
1136 // use instead of the normal height. 1125 // use instead of the normal height.
1137 int height = 0; 1126 int height = 0;
1138 if (use_new_menu_ && 1127 if (use_new_menu_ &&
1139 (model->GetCommandIdAt(i) == IDC_CUT || 1128 (model->GetCommandIdAt(i) == IDC_CUT ||
1140 model->GetCommandIdAt(i) == IDC_ZOOM_MINUS)) 1129 model->GetCommandIdAt(i) == IDC_ZOOM_MINUS))
1141 height = kMenuItemContainingButtonsHeight; 1130 height = kMenuItemContainingButtonsHeight;
1142 1131
1143 MenuItemView* item = AppendMenuItem( 1132 // Add the menu item at the end.
1144 parent, model, i, model->GetTypeAt(i), next_id, height); 1133 int menu_index = parent->HasSubmenu() ?
1134 parent->GetSubmenu()->child_count() : 0;
1135 MenuItemView* item = AddMenuItem(
1136 parent, menu_index, model, i, model->GetTypeAt(i), next_id, height);
1145 1137
1146 if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) { 1138 if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU) {
1147 bool is_recent_tabs_menu = 1139 // Only populate submenus if it's not Recent Tabs submenu.
1148 model->GetCommandIdAt(i) == IDC_RECENT_TABS_MENU; 1140 // RecentTabsMenuModelDelegate will populate the Recent Tabs submenu
1149 if (is_recent_tabs_menu) 1141 // below; the submenu consists of both dynamic and constant items, which
1150 first_recent_tabs_command_id_ = *next_id; 1142 // require special handling of their Id's.
1151 PopulateMenu(item, model->GetSubmenuModelAt(i), next_id); 1143 if (model->GetCommandIdAt(i) != IDC_RECENT_TABS_MENU)
1152 if (is_recent_tabs_menu) 1144 PopulateMenu(item, model->GetSubmenuModelAt(i), next_id);
1153 last_recent_tabs_command_id_ = *next_id - 1;
1154 } 1145 }
1155 1146
1156 const ui::NativeTheme* native_theme = GetNativeTheme(); 1147 const ui::NativeTheme* native_theme = GetNativeTheme();
1157 1148
1158 switch (model->GetCommandIdAt(i)) { 1149 switch (model->GetCommandIdAt(i)) {
1159 case IDC_CUT: 1150 case IDC_CUT:
1160 DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i)); 1151 DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i));
1161 DCHECK_LT(i + 2, max); 1152 DCHECK_LT(i + 2, max);
1162 DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(i + 1)); 1153 DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(i + 1));
1163 DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(i + 2)); 1154 DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(i + 2));
(...skipping 21 matching lines...) Expand all
1185 #if defined(GOOGLE_CHROME_BUILD) 1176 #if defined(GOOGLE_CHROME_BUILD)
1186 case IDC_FEEDBACK: 1177 case IDC_FEEDBACK:
1187 DCHECK(!feedback_menu_item_); 1178 DCHECK(!feedback_menu_item_);
1188 feedback_menu_item_ = item; 1179 feedback_menu_item_ = item;
1189 break; 1180 break;
1190 #endif 1181 #endif
1191 1182
1192 case IDC_RECENT_TABS_MENU: 1183 case IDC_RECENT_TABS_MENU:
1193 DCHECK(!recent_tabs_menu_model_delegate_.get()); 1184 DCHECK(!recent_tabs_menu_model_delegate_.get());
1194 recent_tabs_menu_model_delegate_.reset( 1185 recent_tabs_menu_model_delegate_.reset(
1195 new RecentTabsMenuModelDelegate(model->GetSubmenuModelAt(i), 1186 new RecentTabsMenuModelDelegate(
1196 item)); 1187 this,
1188 static_cast<RecentTabsSubMenuModel*>(
1189 model->GetSubmenuModelAt(i)),
1190 item,
1191 kFirstRecentTabsCommandId,
1192 kFirstBookmarkCommandId - 1));
1193 recent_tabs_menu_model_delegate_->PopulateMenu();
1197 break; 1194 break;
1198 1195
1199 default: 1196 default:
1200 break; 1197 break;
1201 } 1198 }
1202 } 1199 }
1203 } 1200 }
1204 1201
1205 MenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent, 1202 MenuItemView* WrenchMenu::AddMenuItem(MenuItemView* parent,
1206 MenuModel* model, 1203 int menu_index,
1207 int index, 1204 MenuModel* model,
1208 MenuModel::ItemType menu_type, 1205 int model_index,
1209 int* next_id, 1206 MenuModel::ItemType menu_type,
1210 int height) { 1207 int* next_id,
1208 int height) {
1211 int id = (*next_id)++; 1209 int id = (*next_id)++;
1212 1210
1211 DCHECK(id_to_entry_.find(id) == id_to_entry_.end());
1212
1213 id_to_entry_[id].first = model; 1213 id_to_entry_[id].first = model;
1214 id_to_entry_[id].second = index; 1214 id_to_entry_[id].second = model_index;
1215 1215
1216 MenuItemView* menu_item = NULL; 1216 MenuItemView* menu_item = NULL;
1217 if (height > 0) { 1217 if (height > 0) {
1218 // For menu items with a special menu height we use our special class to be 1218 // For menu items with a special menu height we use our special class to be
1219 // able to modify the item height. 1219 // able to modify the item height.
1220 menu_item = new ButtonContainerMenuItemView(parent, id, height); 1220 menu_item = new ButtonContainerMenuItemView(parent, id, height);
1221 parent->GetSubmenu()->AddChildView(menu_item); 1221 parent->GetSubmenu()->AddChildViewAt(menu_item, menu_index);
1222 } else { 1222 } else {
1223 // For all other cases we use the more generic way to add menu items. 1223 // For all other cases we use the more generic way to add menu items.
1224 menu_item = parent->AppendMenuItemFromModel(model, index, id); 1224 menu_item = views::MenuModelAdapter::AddMenuItemFromModelAt(
1225 model, model_index, parent, menu_index, id);
1225 } 1226 }
1226 1227
1227 if (menu_item) { 1228 if (menu_item) {
1228 // Flush all buttons to the right side of the menu for the new menu type. 1229 // Flush all buttons to the right side of the menu for the new menu type.
1229 menu_item->set_use_right_margin(!use_new_menu_); 1230 menu_item->set_use_right_margin(!use_new_menu_);
1230 menu_item->SetVisible(model->IsVisibleAt(index)); 1231 menu_item->SetVisible(model->IsVisibleAt(model_index));
1231 1232
1232 if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) { 1233 if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) {
1233 gfx::Image icon; 1234 gfx::Image icon;
1234 if (model->GetIconAt(index, &icon)) 1235 if (model->GetIconAt(model_index, &icon))
1235 menu_item->SetIcon(*icon.ToImageSkia()); 1236 menu_item->SetIcon(*icon.ToImageSkia());
1236 } 1237 }
1237 } 1238 }
1238 1239
1239 return menu_item; 1240 return menu_item;
1240 } 1241 }
1241 1242
1242 void WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) { 1243 void WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) {
1243 selected_menu_model_ = model; 1244 selected_menu_model_ = model;
1244 selected_index_ = index; 1245 selected_index_ = index;
(...skipping 11 matching lines...) Expand all
1256 1257
1257 model->AddObserver(this); 1258 model->AddObserver(this);
1258 1259
1259 // TODO(oshima): Replace with views only API. 1260 // TODO(oshima): Replace with views only API.
1260 views::Widget* parent = views::Widget::GetWidgetForNativeWindow( 1261 views::Widget* parent = views::Widget::GetWidgetForNativeWindow(
1261 browser_->window()->GetNativeWindow()); 1262 browser_->window()->GetNativeWindow());
1262 bookmark_menu_delegate_.reset( 1263 bookmark_menu_delegate_.reset(
1263 new BookmarkMenuDelegate(browser_, 1264 new BookmarkMenuDelegate(browser_,
1264 browser_, 1265 browser_,
1265 parent, 1266 parent,
1266 first_bookmark_command_id_)); 1267 kFirstBookmarkCommandId));
1267 bookmark_menu_delegate_->Init( 1268 bookmark_menu_delegate_->Init(
1268 this, bookmark_menu_, model->bookmark_bar_node(), 0, 1269 this, bookmark_menu_, model->bookmark_bar_node(), 0,
1269 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS, 1270 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
1270 bookmark_utils::LAUNCH_WRENCH_MENU); 1271 bookmark_utils::LAUNCH_WRENCH_MENU);
1271 } 1272 }
1273
1274 bool WrenchMenu::IsBookmarkCommand(int id) const {
1275 return bookmark_menu_delegate_.get() && id >= kFirstBookmarkCommandId;
1276 }
1277
1278 bool WrenchMenu::IsRecentTabsCommand(int id) const {
1279 return (recent_tabs_menu_model_delegate_.get() &&
1280 id >= kFirstRecentTabsCommandId &&
1281 id < kFirstBookmarkCommandId);
1282 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/wrench_menu.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698