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

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

Issue 7566050: Multi-Profiles: Change avatar menu to bubble view (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments 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 "chrome/browser/browser_process.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/profiles/avatar_menu_model.h"
10 #include "chrome/browser/profiles/profile_info_cache.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "grit/generated_resources.h"
13 #include "grit/theme_resources.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/gfx/canvas.h"
17 #include "ui/gfx/font.h"
18 #include "ui/gfx/image/image.h"
19
20 namespace {
21
22 const int kItemWidth = 210;
23 const int kItemHeight = 32;
24 const int kItemMarginY = 8;
25 const int kIconWidth = 38;
26 const int kIconMarginX = 6;
27 const int kAddUserButtonHeight = 20;
28 const int kEditUserButtonWidth = 19;
29 const int kEditUserButtonMarginX = 3;
30
31 inline int Round(double x) {
32 return static_cast<int>(x + 0.5);
33 }
34
35 gfx::Rect GetCenteredAndScaledRect(int src_width, int src_height,
36 int dst_x, int dst_y,
37 int dst_width, int dst_height) {
38 int scaled_width;
Robert Sesek 2011/08/05 01:34:21 Two-space indents
sail 2011/08/05 01:50:24 Done.
39 int scaled_height;
40 if (src_width > src_height) {
41 scaled_width = std::min(src_width, dst_width);
42 float scale = static_cast<float>(scaled_width) /
43 static_cast<float>(src_width);
44 scaled_height = Round(src_height * scale);
45 } else {
46 scaled_height = std::min(src_height, dst_height);
47 float scale = static_cast<float>(scaled_height) /
48 static_cast<float>(src_height);
49 scaled_width = Round(src_width * scale);
50 }
51 int x = dst_x + (dst_width - scaled_width) / 2;
52 int y = dst_y + (dst_height - scaled_height) / 2;
53 return gfx::Rect(x, y, scaled_width, scaled_height);
54 }
55
56 class AddUserButton : public views::ImageButton {
57 public:
58 explicit AddUserButton(views::ButtonListener* listener)
59 : views::ImageButton(listener) {
60 }
61
62 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
63 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
64 int x = kIconWidth + kIconMarginX;
65 int w = width() - x;
66
67 gfx::Font font(rb.GetFont(ResourceBundle::BaseFont));
68 font = font.DeriveFont(0, gfx::Font::UNDERLINED);
69
70 canvas->DrawStringInt(
71 l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK), font,
72 SkColorSetRGB(0, 0x79, 0xda), x, 0, w, height());
73 }
74 };
75
76 class ProfileItemView : public views::ImageButton {
77 public:
78 ProfileItemView(const AvatarMenuModel::Item& item,
79 views::ButtonListener* listener)
80 : views::ImageButton(listener),
81 item_(item) {
82 }
83
84 void OnPaint(gfx::Canvas* canvas) {
85 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
86
87 // Draw the profile icon on the left.
88 SkBitmap profile_icon = item_.icon;
89 gfx::Rect profile_icon_rect = GetCenteredAndScaledRect(
90 profile_icon.width(), profile_icon.height(),
91 0, 0, kIconWidth, height());
92 canvas->DrawBitmapInt(profile_icon, 0, 0, profile_icon.width(),
93 profile_icon.height(), profile_icon_rect.x(),
94 profile_icon_rect.y(), profile_icon_rect.width(),
95 profile_icon_rect.height(), false);
96
97 // If this profile is selected then draw a check mark on the bottom right
98 // of the profile icon.
99 if (item_.active) {
100 SkBitmap check_icon = rb.GetImageNamed(IDR_PROFILE_SELECTED);
101 int y = profile_icon_rect.bottom() - check_icon.height();
102 int x = profile_icon_rect.right() - check_icon.width() + 2;
103 canvas->DrawBitmapInt(check_icon, 0, 0, check_icon.width(),
104 check_icon.height(), x, y, check_icon.width(),
105 check_icon.height(), false);
106 }
107
108 // Draw the profile name to the right of the profile icon.
109 int name_x = profile_icon_rect.right() + kIconMarginX;
110 canvas->DrawStringInt(item_.name, rb.GetFont(ResourceBundle::BaseFont),
111 GetNameColor(), name_x, 0, width() - name_x,
112 height());
113 }
114
115 private:
116 SkColor GetNameColor() {
117 bool normal = state() != views::CustomButton::BS_PUSHED &&
118 state() != views::CustomButton::BS_HOT;
119 if (item_.active)
120 return normal ? SkColorSetRGB(30, 30, 30) : SkColorSetRGB(0, 0, 0);
121 else
122 return normal ? SkColorSetRGB(128, 128, 128) : SkColorSetRGB(64, 64, 64);
123 }
124
125 AvatarMenuModel::Item item_;
126 };
127
128 } // namespace
129
130 class EditUserButton : public views::ImageButton {
131 public:
132 EditUserButton(size_t profile_index, views::ButtonListener* listener)
133 : views::ImageButton(listener),
134 profile_index_(profile_index) {
135 }
136
137 size_t profile_index() {
138 return profile_index_;
139 }
140
141 private:
142 size_t profile_index_;
143 };
144
145 AvatarMenuBubbleView::AvatarMenuBubbleView(Browser* browser)
146 : add_user_button_(NULL),
147 browser_(browser),
148 edit_user_button_(NULL) {
149 avatar_menu_model_.reset(new AvatarMenuModel(
150 &g_browser_process->profile_manager()->GetProfileInfoCache(),
151 this, browser_));
152 OnAvatarMenuModelChanged();
Robert Sesek 2011/08/05 01:34:21 The MenuModel should call this for you.
sail 2011/08/05 01:50:24 Done.
153 }
154
155 AvatarMenuBubbleView::~AvatarMenuBubbleView() {
156 }
157
158 gfx::Size AvatarMenuBubbleView::GetPreferredSize() {
159 return gfx::Size(kItemWidth, (kItemHeight + kItemMarginY) *
160 item_views_.size() + kAddUserButtonHeight);
161 }
162
163 void AvatarMenuBubbleView::Layout() {
164 int kItemWidth = width() - kEditUserButtonWidth - kEditUserButtonMarginX;
165
166 for (size_t i = 0; i < item_views_.size(); ++i) {
167 views::ImageButton* item_view = item_views_[i];
168 int y = (kItemHeight + kItemMarginY) * i;
169 item_view->SetBounds(0, y, kItemWidth, kItemHeight);
170 }
171
172 int y = (kItemHeight + kItemMarginY) * item_views_.size();
173 add_user_button_->SetBounds(0, y, width(), kAddUserButtonHeight);
174
175 y = (kItemHeight + kItemMarginY) * edit_user_button_->profile_index();
176 edit_user_button_->SetBounds(width() - kEditUserButtonWidth, y,
177 kEditUserButtonWidth, kItemHeight);
178 }
179
180 void AvatarMenuBubbleView::ButtonPressed(views::Button* sender,
181 const views::Event& event) {
182 if (sender == add_user_button_) {
183 avatar_menu_model_->AddNewProfile();
184 } else if (sender == edit_user_button_) {
185 avatar_menu_model_->EditProfile(edit_user_button_->profile_index());
186 } else {
187 for (size_t i = 0; i < item_views_.size(); ++i) {
188 if (sender == item_views_[i]) {
189 avatar_menu_model_->SwitchToProfile(i);
190 break;
191 }
192 }
193 }
194 }
195
196 void AvatarMenuBubbleView::BubbleClosing(Bubble* bubble,
197 bool closed_by_escape) {
198 }
199
200 bool AvatarMenuBubbleView::CloseOnEscape() {
201 return true;
202 }
203
204 bool AvatarMenuBubbleView::FadeInOnShow() {
205 return false;
206 }
207
208 void AvatarMenuBubbleView::OnAvatarMenuModelChanged() {
209 // TODO(sail): This function can get called before our menu model reference
Robert Sesek 2011/08/05 01:34:21 Make the model pass itself as the arg to this func
Robert Sesek 2011/08/05 01:41:21 Alternatively, make the model not call this in the
sail 2011/08/05 01:50:24 Done.
210 // is set. As a work around we explicity check that the menu model exists.
211 if (!avatar_menu_model_.get())
212 return;
213
214 // Unset all our child view references and call RemoveAllChildViews() which
215 // will actually delete them.
216 add_user_button_ = NULL;
217 edit_user_button_ = NULL;
218 item_views_.clear();
219 RemoveAllChildViews(true);
220
221 size_t active_profile_index = 0;
222 for (size_t i = 0; i < avatar_menu_model_->GetNumberOfItems(); ++i) {
223 const AvatarMenuModel::Item& item = avatar_menu_model_->GetItemAt(i);
224 ProfileItemView* item_view = new ProfileItemView(item, this);
225 AddChildView(item_view);
226 item_views_.push_back(item_view);
227
228 if (item.active)
229 active_profile_index = i;
230 }
231
232 add_user_button_ = new AddUserButton(this);
233 AddChildView(add_user_button_);
234
235 edit_user_button_ = new EditUserButton(active_profile_index, this);
236 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
237 edit_user_button_->SetImage(views::CustomButton::BS_NORMAL,
238 rb.GetImageNamed(IDR_PROFILE_EDIT));
239 edit_user_button_->SetImage(views::CustomButton::BS_HOT,
240 rb.GetImageNamed(IDR_PROFILE_EDIT_HOVER));
241 edit_user_button_->SetImage(views::CustomButton::BS_PUSHED,
242 rb.GetImageNamed(IDR_PROFILE_EDIT_PRESSED));
243 edit_user_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
244 views::ImageButton::ALIGN_MIDDLE);
245 AddChildView(edit_user_button_);
246
247 PreferredSizeChanged();
248 }
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