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

Side by Side Diff: chrome/browser/ui/views/passwords/credentials_item_view.cc

Issue 854173003: Credential Management API: the account chooser dialog supports custom avatars. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added a test Created 5 years, 11 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/passwords/credentials_item_view.h" 5 #include "chrome/browser/ui/views/passwords/credentials_item_view.h"
6 6
7 #include "chrome/browser/browser_process.h" 7 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
8 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
9 #include "chrome/browser/profiles/profile_info_cache.h"
10 #include "chrome/browser/profiles/profile_manager.h"
11 #include "grit/theme_resources.h" 8 #include "grit/theme_resources.h"
9 #include "net/base/load_flags.h"
12 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/base/resource/resource_bundle.h"
13 #include "ui/gfx/canvas.h" 11 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/image/image.h" 12 #include "ui/gfx/image/image.h"
13 #include "ui/gfx/image/image_skia_operations.h"
15 #include "ui/gfx/path.h" 14 #include "ui/gfx/path.h"
16 #include "ui/views/border.h" 15 #include "ui/views/border.h"
17 #include "ui/views/controls/image_view.h" 16 #include "ui/views/controls/image_view.h"
18 #include "ui/views/controls/label.h" 17 #include "ui/views/controls/label.h"
19 18
20 namespace { 19 namespace {
21 const int kIconSize = 50; 20 const int kIconSize = 50;
22 // The default spacing between the icon and text. 21 // The default spacing between the icon and text.
23 const int kSpacing = 5; 22 const int kSpacing = 5;
24 23
25 gfx::Size GetTextLabelsSize(const views::Label* full_name_label, 24 gfx::Size GetTextLabelsSize(const views::Label* full_name_label,
26 const views::Label* username_label) { 25 const views::Label* username_label) {
27 gfx::Size full_name = full_name_label->GetPreferredSize(); 26 gfx::Size full_name = full_name_label->GetPreferredSize();
28 gfx::Size username = username_label ? username_label->GetPreferredSize() : 27 gfx::Size username = username_label ? username_label->GetPreferredSize() :
29 gfx::Size(); 28 gfx::Size();
30 return gfx::Size(std::max(full_name.width(), username.width()), 29 return gfx::Size(std::max(full_name.width(), username.width()),
31 full_name.height() + username.height()); 30 full_name.height() + username.height());
32 } 31 }
33 32
33 // Crops and scales |image| to kIconSize
34 gfx::ImageSkia ScaleImage(gfx::ImageSkia skia_image) {
35 gfx::Size size = skia_image.size();
36 if (size.height() != size.width()) {
37 gfx::Rect target(size);
38 int side = std::min(size.height(), size.width());
39 target.ClampToCenteredSize(gfx::Size(side, side));
40 skia_image = gfx::ImageSkiaOperations::ExtractSubset(skia_image, target);
41 }
42 return gfx::ImageSkiaOperations::CreateResizedImage(
43 skia_image,
44 skia::ImageOperations::RESIZE_BEST,
45 gfx::Size(kIconSize, kIconSize));
46 }
47
34 class CircularImageView : public views::ImageView { 48 class CircularImageView : public views::ImageView {
35 public: 49 public:
36 CircularImageView() = default; 50 CircularImageView() = default;
37 51
38 private: 52 private:
39 // views::ImageView: 53 // views::ImageView:
40 void OnPaint(gfx::Canvas* canvas) override; 54 void OnPaint(gfx::Canvas* canvas) override;
41 55
42 DISALLOW_COPY_AND_ASSIGN(CircularImageView); 56 DISALLOW_COPY_AND_ASSIGN(CircularImageView);
43 }; 57 };
44 58
45 void CircularImageView::OnPaint(gfx::Canvas* canvas) { 59 void CircularImageView::OnPaint(gfx::Canvas* canvas) {
46 // Display the avatar picture as a circle. 60 // Display the avatar picture as a circle.
47 gfx::Rect bounds(GetImageBounds()); 61 gfx::Rect bounds(GetImageBounds());
48 gfx::Path circular_mask; 62 gfx::Path circular_mask;
49 circular_mask.addCircle( 63 circular_mask.addCircle(
50 SkIntToScalar(bounds.x() + bounds.right()) / 2, 64 SkIntToScalar(bounds.x() + bounds.right()) / 2,
51 SkIntToScalar(bounds.y() + bounds.bottom()) / 2, 65 SkIntToScalar(bounds.y() + bounds.bottom()) / 2,
52 SkIntToScalar(std::min(bounds.height(), bounds.width())) / 2); 66 SkIntToScalar(std::min(bounds.height(), bounds.width())) / 2);
53 canvas->ClipPath(circular_mask, true); 67 canvas->ClipPath(circular_mask, true);
54 ImageView::OnPaint(canvas); 68 ImageView::OnPaint(canvas);
55 } 69 }
56 70
57 } // namespace 71 } // namespace
58 72
59 CredentialsItemView::CredentialsItemView(views::ButtonListener* button_listener, 73 // Helper class to download the avatar. It deletes itself once the request is
60 const autofill::PasswordForm& form) 74 // done.
75 class CredentialsItemView::AvatarFetcher
76 : public chrome::BitmapFetcherDelegate {
77 public:
78 AvatarFetcher(const GURL& url,
79 const base::WeakPtr<CredentialsItemView>& delegate);
80
81 void Start(net::URLRequestContextGetter* request_context);
82
83 private:
84 ~AvatarFetcher() override;
85
86 // chrome::BitmapFetcherDelegate:
87 void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override;
88
89 chrome::BitmapFetcher fetcher_;
90 base::WeakPtr<CredentialsItemView> delegate_;
91
92 DISALLOW_COPY_AND_ASSIGN(AvatarFetcher);
93 };
94
95 CredentialsItemView::AvatarFetcher::AvatarFetcher(
96 const GURL& url,
97 const base::WeakPtr<CredentialsItemView>& delegate)
98 : fetcher_(url, this),
99 delegate_(delegate) {
100 }
101
102 CredentialsItemView::AvatarFetcher::~AvatarFetcher() = default;
103
104 void CredentialsItemView::AvatarFetcher::Start(
105 net::URLRequestContextGetter* request_context) {
106 fetcher_.Start(request_context, std::string(),
107 net::URLRequest::NEVER_CLEAR_REFERRER,
108 net::LOAD_DO_NOT_SEND_COOKIES |
109 net::LOAD_DO_NOT_SAVE_COOKIES |
110 net::LOAD_MAYBE_USER_GESTURE);
111 }
112
113 void CredentialsItemView::AvatarFetcher::OnFetchComplete(
114 const GURL /*url*/, const SkBitmap* bitmap) {
115 if (bitmap && delegate_)
116 delegate_->UpdateAvatar(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
117
118 delete this;
119 }
120
121 CredentialsItemView::CredentialsItemView(
122 views::ButtonListener* button_listener,
123 const autofill::PasswordForm& form,
124 net::URLRequestContextGetter* request_context)
61 : LabelButton(button_listener, base::string16()), 125 : LabelButton(button_listener, base::string16()),
62 form_(form) { 126 form_(form),
127 weak_ptr_factory_(this) {
63 set_notify_enter_exit_on_child(true); 128 set_notify_enter_exit_on_child(true);
64 // Create an image-view for the avatar. Make sure it ignores events so that 129 // Create an image-view for the avatar. Make sure it ignores events so that
65 // the parent can receive the events instead. 130 // the parent can receive the events instead.
66 image_view_ = new CircularImageView; 131 image_view_ = new CircularImageView;
67 image_view_->set_interactive(false); 132 image_view_->set_interactive(false);
68 133 gfx::Image image =
69 // TODO(vasilii): temporary code below shows the built-in profile icon instead 134 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_PROFILE_AVATAR_26);
70 // of avatar. 135 image_view_->SetImageSize(gfx::Size(kIconSize, kIconSize));
71 const ProfileInfoCache& cache = 136 image_view_->SetImage(image.ToImageSkia());
72 g_browser_process->profile_manager()->GetProfileInfoCache(); 137 if (form_.avatar_url.is_valid()) {
73 const gfx::Image& image = cache.GetAvatarIconOfProfileAtIndex(0); 138 // Fetch the actual avatar.
74 image_view_->SetImage(profiles::GetSizedAvatarIcon( 139 AvatarFetcher* fetcher = new AvatarFetcher(form_.avatar_url,
75 image, true, kIconSize, kIconSize).ToImageSkia()); 140 weak_ptr_factory_.GetWeakPtr());
141 fetcher->Start(request_context);
142 }
76 AddChildView(image_view_); 143 AddChildView(image_view_);
77 144
78 // Add a label to show the full name. 145 // Add a label to show the full name.
79 // TODO(vasilii): temporarily the label shows username. 146 // TODO(vasilii): temporarily the label shows username.
80 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 147 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
81 full_name_label_ = new views::Label( 148 full_name_label_ = new views::Label(
82 form_.username_value, rb->GetFontList(ui::ResourceBundle::BoldFont)); 149 form_.username_value, rb->GetFontList(ui::ResourceBundle::BoldFont));
83 full_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 150 full_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
84 AddChildView(full_name_label_); 151 AddChildView(full_name_label_);
85 152
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 int y_offset = (child_area.height() - 195 int y_offset = (child_area.height() -
129 (full_name_size.height() + username_size.height())) / 2; 196 (full_name_size.height() + username_size.height())) / 2;
130 gfx::Point label_origin(image_origin.x() + image_size.width() + kSpacing, 197 gfx::Point label_origin(image_origin.x() + image_size.width() + kSpacing,
131 child_area.origin().y() + y_offset); 198 child_area.origin().y() + y_offset);
132 full_name_label_->SetBoundsRect(gfx::Rect(label_origin, full_name_size)); 199 full_name_label_->SetBoundsRect(gfx::Rect(label_origin, full_name_size));
133 if (username_label_) { 200 if (username_label_) {
134 label_origin.Offset(0, full_name_size.height()); 201 label_origin.Offset(0, full_name_size.height());
135 username_label_->SetBoundsRect(gfx::Rect(label_origin, username_size)); 202 username_label_->SetBoundsRect(gfx::Rect(label_origin, username_size));
136 } 203 }
137 } 204 }
205
206 void CredentialsItemView::UpdateAvatar(const gfx::ImageSkia& image) {
207 image_view_->SetImage(ScaleImage(image));
208 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698