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

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

Issue 7622001: Revert 96306 - Multi-Profiles: Change avatar menu to bubble view (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 4 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/profiles/avatar_menu_model.h"
11 #include "chrome/browser/profiles/profile_info_cache.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "grit/generated_resources.h"
14 #include "grit/theme_resources.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/gfx/canvas.h"
18 #include "ui/gfx/font.h"
19 #include "ui/gfx/image/image.h"
20 #include "views/controls/button/image_button.h"
21
22 namespace {
23
24 const int kBubbleViewMinWidth = 175;
25 const int kBubbleViewMaxWidth = 800;
26 const int kItemHeight = 32;
27 const int kItemMarginY = 8;
28 const int kIconWidth = 38;
29 const int kIconMarginX = 6;
30 const int kEditProfileButtonMarginX = 8;
31
32 inline int Round(double x) {
33 return static_cast<int>(x + 0.5);
34 }
35
36 gfx::Rect GetCenteredAndScaledRect(int src_width, int src_height,
37 int dst_x, int dst_y,
38 int dst_width, int dst_height) {
39 int scaled_width;
40 int scaled_height;
41 if (src_width > src_height) {
42 scaled_width = std::min(src_width, dst_width);
43 float scale = static_cast<float>(scaled_width) /
44 static_cast<float>(src_width);
45 scaled_height = Round(src_height * scale);
46 } else {
47 scaled_height = std::min(src_height, dst_height);
48 float scale = static_cast<float>(scaled_height) /
49 static_cast<float>(src_height);
50 scaled_width = Round(src_width * scale);
51 }
52 int x = dst_x + (dst_width - scaled_width) / 2;
53 int y = dst_y + (dst_height - scaled_height) / 2;
54 return gfx::Rect(x, y, scaled_width, scaled_height);
55 }
56
57 class ProfileItemView : public views::CustomButton {
58 public:
59 ProfileItemView(const AvatarMenuModel::Item& item,
60 views::ButtonListener* listener)
61 : views::CustomButton(listener),
62 item_(item) {
63 }
64
65 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
66 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
67
68 // Draw the profile icon on the left.
69 SkBitmap profile_icon = item_.icon;
70 gfx::Rect profile_icon_rect = GetCenteredAndScaledRect(
71 profile_icon.width(), profile_icon.height(),
72 0, 0, kIconWidth, height());
73 canvas->DrawBitmapInt(profile_icon, 0, 0, profile_icon.width(),
74 profile_icon.height(), profile_icon_rect.x(),
75 profile_icon_rect.y(), profile_icon_rect.width(),
76 profile_icon_rect.height(), false);
77
78 // If this profile is selected then draw a check mark on the bottom right
79 // of the profile icon.
80 if (item_.active) {
81 SkBitmap check_icon = rb.GetImageNamed(IDR_PROFILE_SELECTED);
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_;
113 };
114
115 } // namespace
116
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)
133 : add_profile_link_(NULL),
134 browser_(browser),
135 edit_profile_button_(NULL) {
136 avatar_menu_model_.reset(new AvatarMenuModel(
137 &g_browser_process->profile_manager()->GetProfileInfoCache(),
138 this, browser_));
139 }
140
141 AvatarMenuBubbleView::~AvatarMenuBubbleView() {
142 }
143
144 gfx::Size AvatarMenuBubbleView::GetPreferredSize() {
145 int max_width = 0;
146 int total_height = 0;
147 for (size_t i = 0; i < item_views_.size(); ++i) {
148 gfx::Size size = item_views_[i]->GetPreferredSize();
149 if (i == edit_profile_button_->profile_index()) {
150 size.set_width(size.width() +
151 edit_profile_button_->GetPreferredSize().width() +
152 kEditProfileButtonMarginX);
153 }
154
155 max_width = std::max(max_width, size.width());
156 total_height += size.height() + kItemMarginY;
157 }
158
159 gfx::Size add_profile_size = add_profile_link_->GetPreferredSize();
160 max_width = std::max(max_width,
161 add_profile_size.width() + kIconWidth + kIconMarginX);
162 total_height += add_profile_link_->GetPreferredSize().height();
163
164 int total_width = std::min(std::max(max_width, kBubbleViewMinWidth),
165 kBubbleViewMaxWidth);
166 return gfx::Size(total_width, total_height);
167 }
168
169 void AvatarMenuBubbleView::Layout() {
170 int y = 0;
171 for (size_t i = 0; i < item_views_.size(); ++i) {
172 views::CustomButton* item_view = item_views_[i];
173 int item_height = item_view->GetPreferredSize().height();
174 int item_width = width();
175
176 if (i == edit_profile_button_->profile_index()) {
177 gfx::Size edit_size = edit_profile_button_->GetPreferredSize();
178 edit_profile_button_->SetBounds(width() - edit_size.width(), y,
179 edit_size.width(), item_height);
180 item_width -= edit_size.width() + kEditProfileButtonMarginX;
181 }
182
183 item_view->SetBounds(0, y, item_width, item_height);
184 y += item_height + kItemMarginY;
185 }
186
187 add_profile_link_->SetBounds(kIconWidth + kIconMarginX, y, width(),
188 add_profile_link_->GetPreferredSize().height());
189 }
190
191 void AvatarMenuBubbleView::ButtonPressed(views::Button* sender,
192 const views::Event& event) {
193 if (sender == edit_profile_button_) {
194 avatar_menu_model_->EditProfile(edit_profile_button_->profile_index());
195 } else {
196 for (size_t i = 0; i < item_views_.size(); ++i) {
197 if (sender == item_views_[i]) {
198 avatar_menu_model_->SwitchToProfile(i);
199 break;
200 }
201 }
202 }
203 }
204
205 void AvatarMenuBubbleView::LinkClicked(views::Link* source, int event_flags) {
206 DCHECK_EQ(source, add_profile_link_);
207 avatar_menu_model_->AddNewProfile();
208 }
209
210 void AvatarMenuBubbleView::BubbleClosing(Bubble* bubble,
211 bool closed_by_escape) {
212 }
213
214 bool AvatarMenuBubbleView::CloseOnEscape() {
215 return true;
216 }
217
218 bool AvatarMenuBubbleView::FadeInOnShow() {
219 return false;
220 }
221
222 void AvatarMenuBubbleView::OnAvatarMenuModelChanged(
223 AvatarMenuModel* avatar_menu_model) {
224 // Unset all our child view references and call RemoveAllChildViews() which
225 // will actually delete them.
226 add_profile_link_ = NULL;
227 edit_profile_button_ = NULL;
228 item_views_.clear();
229 RemoveAllChildViews(true);
230
231 for (size_t i = 0; i < avatar_menu_model->GetNumberOfItems(); ++i) {
232 const AvatarMenuModel::Item& item = avatar_menu_model->GetItemAt(i);
233 ProfileItemView* item_view = new ProfileItemView(item, this);
234 item_view->SetAccessibleName(l10n_util::GetStringFUTF16(
235 IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name));
236 AddChildView(item_view);
237 item_views_.push_back(item_view);
238
239 if (item.active) {
240 DCHECK(!edit_profile_button_);
241 edit_profile_button_ = new EditProfileButton(i, this);
242 edit_profile_button_->SetAccessibleName(l10n_util::GetStringFUTF16(
243 IDS_PROFILES_CUSTOMIZE_PROFILE_ACCESSIBLE_NAME, item.name));
244 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
245 edit_profile_button_->SetImage(views::CustomButton::BS_NORMAL,
246 rb.GetImageNamed(IDR_PROFILE_EDIT));
247 edit_profile_button_->SetImage(views::CustomButton::BS_HOT,
248 rb.GetImageNamed(IDR_PROFILE_EDIT_HOVER));
249 edit_profile_button_->SetImage(views::CustomButton::BS_PUSHED,
250 rb.GetImageNamed(IDR_PROFILE_EDIT_PRESSED));
251 edit_profile_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
252 views::ImageButton::ALIGN_MIDDLE);
253 AddChildView(edit_profile_button_);
254 }
255 }
256
257 add_profile_link_ = new views::Link(UTF16ToWide(
258 l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK)));
259 add_profile_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
260 add_profile_link_->SetNormalColor(SkColorSetRGB(0, 0x79, 0xda));
261 AddChildView(add_profile_link_);
262
263 PreferredSizeChanged();
264 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/avatar_menu_bubble_view.h ('k') | chrome/browser/ui/views/avatar_menu_button.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698