OLD | NEW |
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 } |
OLD | NEW |