MacViews: Use Mac's "Constrained Window Button" style for Button::STYLE_BUTTON LabelB...
[chromium-blink-merge.git] / chrome / browser / ui / views / passwords / credentials_item_view.cc
blob75c2581882c4f036269e7d2fc19a13bc8d9581f1
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/passwords/credentials_item_view.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "components/autofill/core/common/password_form.h"
11 #include "grit/theme_resources.h"
12 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/image/image.h"
16 #include "ui/gfx/path.h"
17 #include "ui/views/border.h"
18 #include "ui/views/controls/image_view.h"
19 #include "ui/views/controls/label.h"
21 namespace {
22 // The default spacing between the icon and text.
23 const int kSpacing = 5;
25 gfx::Size GetTextLabelsSize(const views::Label* upper_label,
26 const views::Label* lower_label) {
27 gfx::Size upper_label_size = upper_label->GetPreferredSize();
28 gfx::Size lower_label_size = lower_label ? lower_label->GetPreferredSize() :
29 gfx::Size();
30 return gfx::Size(std::max(upper_label_size.width(), lower_label_size.width()),
31 upper_label_size.height() + lower_label_size.height());
34 // Returns the bold upper text for the button.
35 base::string16 GetUpperLabelText(const autofill::PasswordForm& form,
36 CredentialsItemView::Style style) {
37 const base::string16& name = form.display_name.empty() ? form.username_value
38 : form.display_name;
39 switch (style) {
40 case CredentialsItemView::ACCOUNT_CHOOSER:
41 return name;
42 case CredentialsItemView::AUTO_SIGNIN:
43 return l10n_util::GetStringFUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE,
44 name);
46 NOTREACHED();
47 return base::string16();
50 // Returns the lower text for the button.
51 base::string16 GetLowerLabelText(const autofill::PasswordForm& form,
52 CredentialsItemView::Style style) {
53 if (!form.federation_url.is_empty()) {
54 return l10n_util::GetStringFUTF16(
55 IDS_MANAGE_PASSWORDS_IDENTITY_PROVIDER,
56 base::UTF8ToUTF16(form.federation_url.host()));
58 return form.display_name.empty() ? base::string16() : form.username_value;
61 class CircularImageView : public views::ImageView {
62 public:
63 CircularImageView() = default;
65 private:
66 // views::ImageView:
67 void OnPaint(gfx::Canvas* canvas) override;
69 DISALLOW_COPY_AND_ASSIGN(CircularImageView);
72 void CircularImageView::OnPaint(gfx::Canvas* canvas) {
73 // Display the avatar picture as a circle.
74 gfx::Rect bounds(GetImageBounds());
75 gfx::Path circular_mask;
76 circular_mask.addCircle(
77 SkIntToScalar(bounds.x() + bounds.right()) / 2,
78 SkIntToScalar(bounds.y() + bounds.bottom()) / 2,
79 SkIntToScalar(std::min(bounds.height(), bounds.width())) / 2);
80 canvas->ClipPath(circular_mask, true);
81 ImageView::OnPaint(canvas);
84 } // namespace
86 CredentialsItemView::CredentialsItemView(
87 views::ButtonListener* button_listener,
88 const autofill::PasswordForm* form,
89 password_manager::CredentialType credential_type,
90 Style style,
91 net::URLRequestContextGetter* request_context)
92 : LabelButton(button_listener, base::string16()),
93 form_(form),
94 credential_type_(credential_type),
95 upper_label_(nullptr),
96 lower_label_(nullptr),
97 weak_ptr_factory_(this) {
98 set_notify_enter_exit_on_child(true);
99 // Create an image-view for the avatar. Make sure it ignores events so that
100 // the parent can receive the events instead.
101 image_view_ = new CircularImageView;
102 image_view_->set_interactive(false);
103 gfx::Image image = ResourceBundle::GetSharedInstance().GetImageNamed(
104 IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE);
105 DCHECK(image.Width() >= kAvatarImageSize &&
106 image.Height() >= kAvatarImageSize);
107 UpdateAvatar(image.AsImageSkia());
108 if (form_->icon_url.is_valid()) {
109 // Fetch the actual avatar.
110 AccountAvatarFetcher* fetcher = new AccountAvatarFetcher(
111 form_->icon_url, weak_ptr_factory_.GetWeakPtr());
112 fetcher->Start(request_context);
114 AddChildView(image_view_);
116 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
117 upper_label_ = new views::Label(
118 GetUpperLabelText(*form_, style),
119 rb->GetFontList(ui::ResourceBundle::BoldFont));
120 upper_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
121 AddChildView(upper_label_);
123 base::string16 lower_text = GetLowerLabelText(*form_, style);
124 if (!lower_text.empty()) {
125 lower_label_ = new views::Label(
126 lower_text, rb->GetFontList(ui::ResourceBundle::SmallFont));
127 lower_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
128 lower_label_->SetEnabled(false);
129 AddChildView(lower_label_);
132 SetFocusable(true);
135 CredentialsItemView::~CredentialsItemView() = default;
137 gfx::Size CredentialsItemView::GetPreferredSize() const {
138 gfx::Size labels_size = GetTextLabelsSize(upper_label_, lower_label_);
139 gfx::Size size = gfx::Size(kAvatarImageSize + labels_size.width(),
140 std::max(kAvatarImageSize, labels_size.height()));
141 const gfx::Insets insets(GetInsets());
142 size.Enlarge(insets.width(), insets.height());
143 size.Enlarge(kSpacing, 0);
145 // Make the size at least as large as the minimum size needed by the border.
146 size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size());
147 return size;
150 int CredentialsItemView::GetHeightForWidth(int w) const {
151 return View::GetHeightForWidth(w);
154 void CredentialsItemView::Layout() {
155 gfx::Rect child_area(GetChildAreaBounds());
156 child_area.Inset(GetInsets());
158 gfx::Size image_size(image_view_->GetPreferredSize());
159 image_size.SetToMin(child_area.size());
160 gfx::Point image_origin(child_area.origin());
161 image_origin.Offset(0, (child_area.height() - image_size.height()) / 2);
162 image_view_->SetBoundsRect(gfx::Rect(image_origin, image_size));
164 gfx::Size full_name_size = upper_label_->GetPreferredSize();
165 gfx::Size username_size =
166 lower_label_ ? lower_label_->GetPreferredSize() : gfx::Size();
167 int y_offset = (child_area.height() -
168 (full_name_size.height() + username_size.height())) / 2;
169 gfx::Point label_origin(image_origin.x() + image_size.width() + kSpacing,
170 child_area.origin().y() + y_offset);
171 upper_label_->SetBoundsRect(gfx::Rect(label_origin, full_name_size));
172 if (lower_label_) {
173 label_origin.Offset(0, full_name_size.height());
174 lower_label_->SetBoundsRect(gfx::Rect(label_origin, username_size));
178 void CredentialsItemView::UpdateAvatar(const gfx::ImageSkia& image) {
179 image_view_->SetImage(ScaleImageForAccountAvatar(image));