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

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

Issue 8070021: Update look of profile menu (Views) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review comments Created 9 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/avatar_menu_bubble_view.h ('k') | no next file » | 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/avatar_menu_bubble_view.h" 5 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
6 6
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/ui/browser.h" 9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/profiles/avatar_menu_model.h" 10 #include "chrome/browser/profiles/avatar_menu_model.h"
11 #include "chrome/browser/profiles/profile_info_cache.h" 11 #include "chrome/browser/profiles/profile_info_cache.h"
12 #include "chrome/browser/profiles/profile_manager.h" 12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "grit/generated_resources.h" 13 #include "grit/generated_resources.h"
14 #include "grit/theme_resources.h" 14 #include "grit/theme_resources.h"
15 #include "ui/base/l10n/l10n_util.h" 15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/resource/resource_bundle.h" 16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/gfx/canvas.h" 17 #include "ui/gfx/canvas.h"
18 #include "ui/gfx/canvas_skia.h"
18 #include "ui/gfx/font.h" 19 #include "ui/gfx/font.h"
19 #include "ui/gfx/image/image.h" 20 #include "ui/gfx/image/image.h"
20 #include "views/controls/button/image_button.h" 21 #include "views/controls/button/image_button.h"
22 #include "views/controls/image_view.h"
23 #include "views/controls/label.h"
21 24
22 namespace { 25 namespace {
23 26
24 const int kBubbleViewMinWidth = 175; 27 const int kItemHeight = 44;
25 const int kBubbleViewMaxWidth = 800; 28 const int kItemMarginY = 4;
26 const int kItemHeight = 32;
27 const int kItemMarginY = 8;
28 const int kIconWidth = 38; 29 const int kIconWidth = 38;
29 const int kIconMarginX = 6; 30 const int kIconMarginX = 6;
30 const int kEditProfileButtonMarginX = 8; 31 const int kSeparatorPaddingY = 5;
31 32
32 inline int Round(double x) { 33 inline int Round(double x) {
33 return static_cast<int>(x + 0.5); 34 return static_cast<int>(x + 0.5);
34 } 35 }
35 36
36 gfx::Rect GetCenteredAndScaledRect(int src_width, int src_height, 37 gfx::Rect GetCenteredAndScaledRect(int src_width, int src_height,
37 int dst_x, int dst_y, 38 int dst_x, int dst_y,
38 int dst_width, int dst_height) { 39 int dst_width, int dst_height) {
39 int scaled_width; 40 int scaled_width;
40 int scaled_height; 41 int scaled_height;
41 if (src_width > src_height) { 42 if (src_width > src_height) {
42 scaled_width = std::min(src_width, dst_width); 43 scaled_width = std::min(src_width, dst_width);
43 float scale = static_cast<float>(scaled_width) / 44 float scale = static_cast<float>(scaled_width) /
44 static_cast<float>(src_width); 45 static_cast<float>(src_width);
45 scaled_height = Round(src_height * scale); 46 scaled_height = Round(src_height * scale);
46 } else { 47 } else {
47 scaled_height = std::min(src_height, dst_height); 48 scaled_height = std::min(src_height, dst_height);
48 float scale = static_cast<float>(scaled_height) / 49 float scale = static_cast<float>(scaled_height) /
49 static_cast<float>(src_height); 50 static_cast<float>(src_height);
50 scaled_width = Round(src_width * scale); 51 scaled_width = Round(src_width * scale);
51 } 52 }
52 int x = dst_x + (dst_width - scaled_width) / 2; 53 int x = dst_x + (dst_width - scaled_width) / 2;
53 int y = dst_y + (dst_height - scaled_height) / 2; 54 int y = dst_y + (dst_height - scaled_height) / 2;
54 return gfx::Rect(x, y, scaled_width, scaled_height); 55 return gfx::Rect(x, y, scaled_width, scaled_height);
55 } 56 }
56 57
57 class ProfileItemView : public views::CustomButton { 58 // Delegate to callback when the highlight state of a control changes.
59 class HighlightDelegate {
60 public:
61 virtual void OnHighlightStateChanged() = 0;
62 };
63
64 // A custom Link control that forwards highlight state changes. We need to do
65 // this to make sure that the ProfileItemView looks highlighted even when
66 // the mouse is over this link.
67 class EditProfileLink : public views::Link {
68 public:
69 explicit EditProfileLink(const string16& title,
70 HighlightDelegate* delegate)
71 : views::Link(UTF16ToWideHack(title)),
72 delegate_(delegate),
73 state_(views::CustomButton::BS_NORMAL) {
74 }
75
76 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE {
77 views::Link::OnMouseEntered(event);
78 state_ = views::CustomButton::BS_HOT;
79 delegate_->OnHighlightStateChanged();
80 }
81
82 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE {
83 views::Link::OnMouseExited(event);
84 state_ = views::CustomButton::BS_NORMAL;
85 delegate_->OnHighlightStateChanged();
86 }
87
88 views::CustomButton::ButtonState state() { return state_; }
89
90 private:
91 HighlightDelegate* delegate_;
92 views::CustomButton::ButtonState state_;
93 };
94
95 // A custom image view that ignores mouse events so that the parent can receive
96 // them them instead.
97 class ProfileImageView : public views::ImageView {
98 public:
99 virtual bool HitTest(const gfx::Point& l) const OVERRIDE {
100 return false;
101 }
102 };
103
104 // Control that shows information about a single profile.
105 class ProfileItemView : public views::CustomButton,
106 public HighlightDelegate {
58 public: 107 public:
59 ProfileItemView(const AvatarMenuModel::Item& item, 108 ProfileItemView(const AvatarMenuModel::Item& item,
60 views::ButtonListener* listener) 109 views::ButtonListener* switch_profile_listener,
61 : views::CustomButton(listener), 110 views::LinkListener* edit_profile_listener)
111 : views::CustomButton(switch_profile_listener),
62 item_(item) { 112 item_(item) {
113 image_view_ = new ProfileImageView();
114 SkBitmap profile_icon = item_.icon;
115 if (item_.active) {
116 SkBitmap badged_icon = GetBadgedIcon(profile_icon);
117 image_view_->SetImage(&badged_icon);
118 } else {
119 image_view_->SetImage(&profile_icon);
120 }
121 AddChildView(image_view_);
122
123 // Add a label to show the profile name.
124 name_label_ = new views::Label(UTF16ToWideHack(item_.name));
125 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
126 gfx::Font base_font = rb.GetFont(ResourceBundle::BaseFont);
127 int style = item_.active ? gfx::Font::BOLD : 0;
128 const int kNameFontDelta = 1;
129 name_label_->SetFont(base_font.DeriveFont(kNameFontDelta, style));
130 name_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
131 AddChildView(name_label_);
132
133 // Add a label to show the sync state.
134 sync_state_label_ = new views::Label(UTF16ToWideHack(item_.sync_state));
135 const int kStateFontDelta = -1;
136 sync_state_label_->SetFont(base_font.DeriveFont(kStateFontDelta));
137 sync_state_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
138 sync_state_label_->SetEnabled(false);
139 AddChildView(sync_state_label_);
140
141 // Add an edit profile link.
142 edit_link_ = new EditProfileLink(
143 l10n_util::GetStringUTF16(IDS_PROFILES_EDIT_PROFILE_LINK), this);
144 edit_link_->set_listener(edit_profile_listener);
145 edit_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
146 edit_link_->SetNormalColor(SkColorSetRGB(0, 0x79, 0xda));
147 AddChildView(edit_link_);
148
149 OnHighlightStateChanged();
63 } 150 }
64 151
65 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 152 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
153 if (IsHighlighted()) {
154 canvas->FillRectInt(SkColorSetRGB(0xe3, 0xed, 0xf6), 0, 0,
155 width(), height());
156 }
157 }
158
159 virtual gfx::Size GetPreferredSize() OVERRIDE {
160 int width = std::max(name_label_->GetPreferredSize().width(),
161 sync_state_label_->GetPreferredSize().width());
162 width = std::max(edit_link_->GetPreferredSize().width(),
163 width);
164 return gfx::Size(kIconWidth + kIconMarginX + width, kItemHeight);
165 }
166
167 virtual void Layout() OVERRIDE {
168 // Profile icon.
169 const SkBitmap& icon = image_view_->GetImage();
170 gfx::Rect icon_rect = GetCenteredAndScaledRect(
171 icon.width(), icon.height(), 0, 0, kIconWidth, height());
172 image_view_->SetBoundsRect(icon_rect);
173
174 int label_x = icon_rect.right() + kIconMarginX;
175 int max_label_width = width() - label_x;
176 gfx::Size name_size = name_label_->GetPreferredSize();
177 name_size.set_width(std::min(name_size.width(), max_label_width));
178 gfx::Size state_size = sync_state_label_->GetPreferredSize();
179 state_size.set_width(std::min(state_size.width(), max_label_width));
180 gfx::Size edit_size = edit_link_->GetPreferredSize();
181 edit_size.set_width(std::min(edit_size.width(), max_label_width));
182
183 const int kNameStatePaddingY = 2;
184 int labels_height = name_size.height() + kNameStatePaddingY +
185 std::max(state_size.height(), edit_size.height());
186 int y = (height() - labels_height) / 2;
187 name_label_->SetBounds(label_x, y, name_size.width(), name_size.height());
188
189 int bottom = y + labels_height;
190 sync_state_label_->SetBounds(label_x, bottom - state_size.height(),
191 state_size.width(), state_size.height());
192 // The edit link overlaps the sync state label.
193 edit_link_->SetBounds(label_x, bottom - edit_size.height(),
194 edit_size.width(), edit_size.height());
195 }
196
197 virtual void OnHighlightStateChanged() OVERRIDE {
198 bool show_edit = IsHighlighted() && item_.active;
199 sync_state_label_->SetVisible(!show_edit);
200 edit_link_->SetVisible(show_edit);
201 SchedulePaint();
202 }
203
204 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE {
205 views::CustomButton::OnMouseEntered(event);
206 OnHighlightStateChanged();
207 }
208
209 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE {
210 views::CustomButton::OnMouseExited(event);
211 OnHighlightStateChanged();
212 }
213
214 EditProfileLink* edit_link() { return edit_link_; }
215 const AvatarMenuModel::Item& item() { return item_; }
216
217 private:
218 bool IsHighlighted() {
219 return state() == views::CustomButton::BS_PUSHED ||
220 state() == views::CustomButton::BS_HOT ||
221 edit_link_->state() == views::CustomButton::BS_PUSHED ||
222 edit_link_->state() == views::CustomButton::BS_HOT;
223 }
224
225 SkBitmap GetBadgedIcon(const SkBitmap& icon) {
226 gfx::Rect icon_rect = GetCenteredAndScaledRect(
227 icon.width(), icon.height(), 0, 0, kIconWidth, kItemHeight);
228
66 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 229 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
67 230 SkBitmap badge = rb.GetImageNamed(IDR_PROFILE_SELECTED);
68 // Draw the profile icon on the left. 231 const float kBadgeOverlapRatioX = 1.0f / 5.0f;
69 SkBitmap profile_icon = item_.icon; 232 int width = icon_rect.width() + badge.width() * kBadgeOverlapRatioX;
70 gfx::Rect profile_icon_rect = GetCenteredAndScaledRect( 233 const float kBadgeOverlapRatioY = 1.0f / 3.0f;
71 profile_icon.width(), profile_icon.height(), 234 int height = icon_rect.height() + badge.height() * kBadgeOverlapRatioY;
72 0, 0, kIconWidth, height()); 235
73 canvas->DrawBitmapInt(profile_icon, 0, 0, profile_icon.width(), 236 gfx::CanvasSkia canvas(width, height, false);
74 profile_icon.height(), profile_icon_rect.x(), 237 canvas.DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), 0, 0,
75 profile_icon_rect.y(), profile_icon_rect.width(), 238 icon_rect.width(), icon_rect.height(), true);
76 profile_icon_rect.height(), false); 239 canvas.DrawBitmapInt(badge, width - badge.width(), height - badge.height());
77 240 return canvas.ExtractBitmap();
78 // If this profile is selected then draw a check mark on the bottom right 241 }
79 // of the profile icon. 242
80 if (item_.active) { 243 EditProfileLink* edit_link_;
81 SkBitmap check_icon = rb.GetImageNamed(IDR_PROFILE_SELECTED); 244 views::ImageView* image_view_;
82 int y = profile_icon_rect.bottom() - check_icon.height();
83 int x = profile_icon_rect.right() - check_icon.width() + 2;
84 canvas->DrawBitmapInt(check_icon, 0, 0, check_icon.width(),
85 check_icon.height(), x, y, check_icon.width(),
86 check_icon.height(), false);
87 }
88
89 // Draw the profile name to the right of the profile icon.
90 int name_x = profile_icon_rect.right() + kIconMarginX;
91 canvas->DrawStringInt(item_.name, rb.GetFont(ResourceBundle::BaseFont),
92 GetNameColor(), name_x, 0, width() - name_x,
93 height());
94 }
95
96 virtual gfx::Size GetPreferredSize() OVERRIDE {
97 gfx::Font font = ResourceBundle::GetSharedInstance().GetFont(
98 ResourceBundle::BaseFont);
99 int title_width = font.GetStringWidth(item_.name);
100 return gfx::Size(kIconWidth + kIconMarginX + title_width, kItemHeight);
101 }
102
103 private:
104 SkColor GetNameColor() {
105 bool normal = state() != views::CustomButton::BS_PUSHED &&
106 state() != views::CustomButton::BS_HOT;
107 if (item_.active)
108 return normal ? SkColorSetRGB(30, 30, 30) : SkColorSetRGB(0, 0, 0);
109 return normal ? SkColorSetRGB(128, 128, 128) : SkColorSetRGB(64, 64, 64);
110 }
111
112 AvatarMenuModel::Item item_; 245 AvatarMenuModel::Item item_;
246 views::Label* name_label_;
247 views::Label* sync_state_label_;
113 }; 248 };
114 249
115 } // namespace 250 } // namespace
116 251
117 class EditProfileButton : public views::ImageButton {
118 public:
119 EditProfileButton(size_t profile_index, views::ButtonListener* listener)
120 : views::ImageButton(listener),
121 profile_index_(profile_index) {
122 }
123
124 size_t profile_index() {
125 return profile_index_;
126 }
127
128 private:
129 size_t profile_index_;
130 };
131
132 AvatarMenuBubbleView::AvatarMenuBubbleView(Browser* browser) 252 AvatarMenuBubbleView::AvatarMenuBubbleView(Browser* browser)
133 : add_profile_link_(NULL), 253 : add_profile_link_(NULL),
134 browser_(browser), 254 browser_(browser) {
135 edit_profile_button_(NULL) {
136 avatar_menu_model_.reset(new AvatarMenuModel( 255 avatar_menu_model_.reset(new AvatarMenuModel(
137 &g_browser_process->profile_manager()->GetProfileInfoCache(), 256 &g_browser_process->profile_manager()->GetProfileInfoCache(),
138 this, browser_)); 257 this, browser_));
139 // Build the menu for the first time. 258 // Build the menu for the first time.
140 OnAvatarMenuModelChanged(avatar_menu_model_.get()); 259 OnAvatarMenuModelChanged(avatar_menu_model_.get());
141 } 260 }
142 261
143 AvatarMenuBubbleView::~AvatarMenuBubbleView() { 262 AvatarMenuBubbleView::~AvatarMenuBubbleView() {
144 } 263 }
145 264
146 gfx::Size AvatarMenuBubbleView::GetPreferredSize() { 265 gfx::Size AvatarMenuBubbleView::GetPreferredSize() {
147 int max_width = 0; 266 int max_width = 0;
148 int total_height = 0; 267 int total_height = 0;
149 for (size_t i = 0; i < item_views_.size(); ++i) { 268 for (size_t i = 0; i < item_views_.size(); ++i) {
150 gfx::Size size = item_views_[i]->GetPreferredSize(); 269 gfx::Size size = item_views_[i]->GetPreferredSize();
151 if (i == edit_profile_button_->profile_index()) {
152 size.set_width(size.width() +
153 edit_profile_button_->GetPreferredSize().width() +
154 kEditProfileButtonMarginX);
155 }
156
157 max_width = std::max(max_width, size.width()); 270 max_width = std::max(max_width, size.width());
158 total_height += size.height() + kItemMarginY; 271 total_height += size.height() + kItemMarginY;
159 } 272 }
160 273
274 total_height += kSeparatorPaddingY * 2 +
275 separator_->GetPreferredSize().height();
276
161 gfx::Size add_profile_size = add_profile_link_->GetPreferredSize(); 277 gfx::Size add_profile_size = add_profile_link_->GetPreferredSize();
162 max_width = std::max(max_width, 278 max_width = std::max(max_width,
163 add_profile_size.width() + kIconWidth + kIconMarginX); 279 add_profile_size.width() + kIconWidth + kIconMarginX);
164 total_height += add_profile_link_->GetPreferredSize().height(); 280 total_height += add_profile_link_->GetPreferredSize().height();
165 281
282 const int kBubbleViewMaxWidth = 800;
283 const int kBubbleViewMinWidth = 175;
166 int total_width = std::min(std::max(max_width, kBubbleViewMinWidth), 284 int total_width = std::min(std::max(max_width, kBubbleViewMinWidth),
167 kBubbleViewMaxWidth); 285 kBubbleViewMaxWidth);
168 return gfx::Size(total_width, total_height); 286 return gfx::Size(total_width, total_height);
169 } 287 }
170 288
171 void AvatarMenuBubbleView::Layout() { 289 void AvatarMenuBubbleView::Layout() {
172 int y = 0; 290 int y = 0;
173 for (size_t i = 0; i < item_views_.size(); ++i) { 291 for (size_t i = 0; i < item_views_.size(); ++i) {
174 views::CustomButton* item_view = item_views_[i]; 292 views::CustomButton* item_view = item_views_[i];
175 int item_height = item_view->GetPreferredSize().height(); 293 int item_height = item_view->GetPreferredSize().height();
176 int item_width = width(); 294 int item_width = width();
177
178 if (i == edit_profile_button_->profile_index()) {
179 gfx::Size edit_size = edit_profile_button_->GetPreferredSize();
180 edit_profile_button_->SetBounds(width() - edit_size.width(), y,
181 edit_size.width(), item_height);
182 item_width -= edit_size.width() + kEditProfileButtonMarginX;
183 }
184
185 item_view->SetBounds(0, y, item_width, item_height); 295 item_view->SetBounds(0, y, item_width, item_height);
186 y += item_height + kItemMarginY; 296 y += item_height + kItemMarginY;
187 } 297 }
188 298
299 y += kSeparatorPaddingY;
300 int separator_height = separator_->GetPreferredSize().height();
301 separator_->SetBounds(0, y, width(), separator_height);
302 y += kSeparatorPaddingY + separator_height;
303
189 add_profile_link_->SetBounds(kIconWidth + kIconMarginX, y, width(), 304 add_profile_link_->SetBounds(kIconWidth + kIconMarginX, y, width(),
190 add_profile_link_->GetPreferredSize().height()); 305 add_profile_link_->GetPreferredSize().height());
191 } 306 }
192 307
193 void AvatarMenuBubbleView::ButtonPressed(views::Button* sender, 308 void AvatarMenuBubbleView::ButtonPressed(views::Button* sender,
194 const views::Event& event) { 309 const views::Event& event) {
195 if (sender == edit_profile_button_) { 310 for (size_t i = 0; i < item_views_.size(); ++i) {
196 avatar_menu_model_->EditProfile(edit_profile_button_->profile_index()); 311 ProfileItemView* item_view = static_cast<ProfileItemView*>(item_views_[i]);
197 } else { 312 if (sender == item_view) {
198 for (size_t i = 0; i < item_views_.size(); ++i) { 313 // Clicking on the active profile shouldn't do anything.
199 if (sender == item_views_[i]) { 314 if (!item_view->item().active)
200 avatar_menu_model_->SwitchToProfile(i); 315 avatar_menu_model_->SwitchToProfile(i);
201 break; 316 break;
202 }
203 } 317 }
204 } 318 }
205 } 319 }
206 320
207 void AvatarMenuBubbleView::LinkClicked(views::Link* source, int event_flags) { 321 void AvatarMenuBubbleView::LinkClicked(views::Link* source, int event_flags) {
208 DCHECK_EQ(source, add_profile_link_); 322 if (source == add_profile_link_) {
209 avatar_menu_model_->AddNewProfile(); 323 avatar_menu_model_->AddNewProfile();
324 return;
325 }
326
327 for (size_t i = 0; i < item_views_.size(); ++i) {
328 ProfileItemView* item_view = static_cast<ProfileItemView*>(item_views_[i]);
329 if (source == item_view->edit_link()) {
330 avatar_menu_model_->EditProfile(i);
331 return;
332 }
333 }
210 } 334 }
211 335
212 void AvatarMenuBubbleView::BubbleClosing(Bubble* bubble, 336 void AvatarMenuBubbleView::BubbleClosing(Bubble* bubble,
213 bool closed_by_escape) { 337 bool closed_by_escape) {
214 } 338 }
215 339
216 bool AvatarMenuBubbleView::CloseOnEscape() { 340 bool AvatarMenuBubbleView::CloseOnEscape() {
217 return true; 341 return true;
218 } 342 }
219 343
220 bool AvatarMenuBubbleView::FadeInOnShow() { 344 bool AvatarMenuBubbleView::FadeInOnShow() {
221 return false; 345 return false;
222 } 346 }
223 347
224 void AvatarMenuBubbleView::OnAvatarMenuModelChanged( 348 void AvatarMenuBubbleView::OnAvatarMenuModelChanged(
225 AvatarMenuModel* avatar_menu_model) { 349 AvatarMenuModel* avatar_menu_model) {
226 // Unset all our child view references and call RemoveAllChildViews() which 350 // Unset all our child view references and call RemoveAllChildViews() which
227 // will actually delete them. 351 // will actually delete them.
228 add_profile_link_ = NULL; 352 add_profile_link_ = NULL;
229 edit_profile_button_ = NULL;
230 item_views_.clear(); 353 item_views_.clear();
231 RemoveAllChildViews(true); 354 RemoveAllChildViews(true);
232 355
233 for (size_t i = 0; i < avatar_menu_model->GetNumberOfItems(); ++i) { 356 for (size_t i = 0; i < avatar_menu_model->GetNumberOfItems(); ++i) {
234 const AvatarMenuModel::Item& item = avatar_menu_model->GetItemAt(i); 357 const AvatarMenuModel::Item& item = avatar_menu_model->GetItemAt(i);
235 ProfileItemView* item_view = new ProfileItemView(item, this); 358 ProfileItemView* item_view = new ProfileItemView(item, this, this);
236 item_view->SetAccessibleName(l10n_util::GetStringFUTF16( 359 item_view->SetAccessibleName(l10n_util::GetStringFUTF16(
237 IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name)); 360 IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name));
238 AddChildView(item_view); 361 AddChildView(item_view);
239 item_views_.push_back(item_view); 362 item_views_.push_back(item_view);
363 }
240 364
241 if (item.active) { 365 separator_ = new views::Separator();
242 DCHECK(!edit_profile_button_); 366 AddChildView(separator_);
243 edit_profile_button_ = new EditProfileButton(i, this);
244 edit_profile_button_->SetAccessibleName(l10n_util::GetStringFUTF16(
245 IDS_PROFILES_CUSTOMIZE_PROFILE_ACCESSIBLE_NAME, item.name));
246 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
247 edit_profile_button_->SetImage(views::CustomButton::BS_NORMAL,
248 rb.GetImageNamed(IDR_PROFILE_EDIT));
249 edit_profile_button_->SetImage(views::CustomButton::BS_HOT,
250 rb.GetImageNamed(IDR_PROFILE_EDIT_HOVER));
251 edit_profile_button_->SetImage(views::CustomButton::BS_PUSHED,
252 rb.GetImageNamed(IDR_PROFILE_EDIT_PRESSED));
253 edit_profile_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
254 views::ImageButton::ALIGN_MIDDLE);
255 AddChildView(edit_profile_button_);
256 }
257 }
258 367
259 add_profile_link_ = new views::Link(UTF16ToWide( 368 add_profile_link_ = new views::Link(UTF16ToWide(
260 l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK))); 369 l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK)));
261 add_profile_link_->set_listener(this); 370 add_profile_link_->set_listener(this);
262 add_profile_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 371 add_profile_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
263 add_profile_link_->SetNormalColor(SkColorSetRGB(0, 0x79, 0xda)); 372 add_profile_link_->SetNormalColor(SkColorSetRGB(0, 0x79, 0xda));
264 AddChildView(add_profile_link_); 373 AddChildView(add_profile_link_);
265 374
266 PreferredSizeChanged(); 375 PreferredSizeChanged();
267 } 376 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/avatar_menu_bubble_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698