1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/app_list/views/app_list_menu_views.h" 6 7 #include "grit/ui_resources.h" 8 #include "ui/app_list/app_list_view_delegate.h" 9 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/views/controls/button/menu_button.h" 11 #include "ui/views/controls/image_view.h" 12 #include "ui/views/controls/label.h" 13 #include "ui/views/controls/menu/menu_config.h" 14 #include "ui/views/controls/menu/menu_item_view.h" 15 #include "ui/views/controls/menu/submenu_view.h" 16 #include "ui/views/layout/grid_layout.h" 17 18 using views::MenuItemView; 19 20 namespace app_list { 21 22 namespace { 23 24 class CurrentUserView : public views::View { 25 public: 26 CurrentUserView(const base::string16& user_name, 27 const base::string16& user_email, 28 const gfx::ImageSkia& icon) { 29 const views::MenuConfig& menu_config = views::MenuConfig::instance(NULL); 30 views::GridLayout* layout = new views::GridLayout(this); 31 int item_right_padding = menu_config.label_to_arrow_padding + 32 menu_config.arrow_width + 33 menu_config.arrow_to_edge_padding; 34 35 layout->SetInsets(0, 0, 0, item_right_padding); 36 SetLayoutManager(layout); 37 38 views::ColumnSet* columns = layout->AddColumnSet(0); 39 columns->AddColumn(views::GridLayout::FILL, 40 views::GridLayout::FILL, 41 0, 42 views::GridLayout::USE_PREF, 43 0, 44 menu_config.check_width + menu_config.item_left_margin); 45 columns->AddColumn(views::GridLayout::FILL, 46 views::GridLayout::FILL, 47 1, 48 views::GridLayout::USE_PREF, 49 0, 50 0); 51 52 layout->StartRow(0, 0); 53 views::ImageView* image_view = new views::ImageView(); 54 image_view->SetImage(icon); 55 layout->AddView(image_view); 56 57 views::Label* user_name_view = new views::Label(user_name); 58 user_name_view->SetHorizontalAlignment(gfx::ALIGN_LEFT); 59 layout->AddView(user_name_view); 60 61 layout->StartRow(0, 0); 62 views::Label* user_email_view = new views::Label(user_email); 63 user_email_view->SetHorizontalAlignment(gfx::ALIGN_LEFT); 64 user_email_view->SetEnabled(false); 65 layout->SkipColumns(1); 66 layout->AddView(user_email_view); 67 } 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(CurrentUserView); 71 }; 72 73 class CurrentUserMenuItem : public MenuItemView { 74 public: 75 CurrentUserMenuItem(MenuItemView* parent, 76 int id, 77 const base::string16& user_name, 78 const base::string16& user_email, 79 const gfx::ImageSkia& icon) 80 : MenuItemView(parent, id, MenuItemView::NORMAL) { 81 AddChildView(new CurrentUserView(user_name, user_email, icon)); 82 } 83 84 private: 85 DISALLOW_COPY_AND_ASSIGN(CurrentUserMenuItem); 86 }; 87 88 class AppListMenuModelAdapter : public views::MenuModelAdapter { 89 public: 90 AppListMenuModelAdapter(ui::MenuModel* menu_model, 91 AppListViewDelegate* delegate) 92 : views::MenuModelAdapter(menu_model), 93 delegate_(delegate) {} 94 virtual ~AppListMenuModelAdapter() {} 95 96 // Overridden from views::MenuModelAdapter: 97 virtual MenuItemView* AppendMenuItem(MenuItemView* menu, 98 ui::MenuModel* model, 99 int index) OVERRIDE { 100 if (!delegate_) 101 return NULL; 102 103 int id = model->GetCommandIdAt(index); 104 if (id != AppListMenu::CURRENT_USER) 105 return MenuModelAdapter::AppendMenuItem(menu, model, index); 106 107 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 108 MenuItemView* item = new CurrentUserMenuItem( 109 menu, 110 id, 111 delegate_->GetCurrentUserName(), 112 delegate_->GetCurrentUserEmail(), 113 *rb.GetImageSkiaNamed(IDR_APP_LIST_USER_INDICATOR)); 114 menu->CreateSubmenu(); 115 menu->GetSubmenu()->AddChildViewAt(item, index); 116 return item; 117 } 118 119 private: 120 AppListViewDelegate* delegate_; 121 122 DISALLOW_COPY_AND_ASSIGN(AppListMenuModelAdapter); 123 }; 124 125 } // namespace 126 127 AppListMenuViews::AppListMenuViews(AppListViewDelegate* delegate) 128 : AppListMenu(delegate) { 129 menu_delegate_.reset(new AppListMenuModelAdapter(menu_model(), delegate)); 130 menu_ = new MenuItemView(menu_delegate_.get()); 131 menu_runner_.reset(new views::MenuRunner(menu_)); 132 menu_delegate_->BuildMenu(menu_); 133 } 134 135 AppListMenuViews::~AppListMenuViews() {} 136 137 void AppListMenuViews::RunMenuAt(views::MenuButton* button, 138 const gfx::Point& point) { 139 ignore_result(menu_runner_->RunMenuAt(button->GetWidget(), button, 140 gfx::Rect(point, gfx::Size()), 141 MenuItemView::TOPRIGHT, 142 ui::MENU_SOURCE_NONE, 0)); 143 } 144 145 void AppListMenuViews::Cancel() { 146 menu_runner_->Cancel(); 147 } 148 149 } // namespace app_list 150