Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / passwords / credential_item_view.mm
blob2ab98a9cd75d193e4787e98931fb90d0f22af457
1 // Copyright 2015 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 #import "chrome/browser/ui/cocoa/passwords/credential_item_view.h"
7 #include <algorithm>
9 #include "base/i18n/rtl.h"
10 #include "base/mac/foundation_util.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
13 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
14 #include "chrome/grit/generated_resources.h"
15 #include "grit/theme_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/image/image_skia.h"
19 #include "ui/gfx/image/image_skia_util_mac.h"
21 namespace {
22 const CGFloat kHorizontalPaddingBetweenAvatarAndLabels = 10.0f;
23 const CGFloat kVerticalPaddingBetweenLabels = 2.0f;
24 }  // namespace
26 @interface CredentialItemView()
27 + (NSString*)upperLabelTextForForm:(const autofill::PasswordForm&)passwordForm
28                              style:(password_manager_mac::CredentialItemStyle)
29                                        style;
30 + (NSString*)lowerLabelTextForForm:
31         (const autofill::PasswordForm&)passwordForm;
32 + (NSTextField*)labelWithText:(NSString*)title;
33 @property(nonatomic, readonly) NSTextField* upperLabel;
34 @property(nonatomic, readonly) NSTextField* lowerLabel;
35 @property(nonatomic, readonly) NSImageView* avatarView;
36 @end
38 @implementation CredentialItemView
40 @synthesize upperLabel = upperLabel_;
41 @synthesize lowerLabel = lowerLabel_;
42 @synthesize avatarView = avatarView_;
43 @synthesize passwordForm = passwordForm_;
44 @synthesize credentialType = credentialType_;
46 - (id)initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
47             credentialType:(password_manager::CredentialType)credentialType
48                      style:(password_manager_mac::CredentialItemStyle)style
49                   delegate:(id<CredentialItemDelegate>)delegate {
50   if ((self = [super init])) {
51     passwordForm_ = passwordForm;
52     credentialType_ = credentialType;
53     delegate_ = delegate;
55     // -----------------------------------------------
56     // |      | John Q. Facebooker                   |
57     // | icon | john@somewhere.com                   |
58     // -----------------------------------------------
60     // Create the views.
62     avatarView_ = [[[NSImageView alloc] initWithFrame:NSZeroRect] autorelease];
63     [avatarView_ setWantsLayer:YES];
64     [[avatarView_ layer] setCornerRadius:kAvatarImageSize / 2.0f];
65     [[avatarView_ layer] setMasksToBounds:YES];
66     [self addSubview:avatarView_];
68     NSString* upperLabelText =
69         [[self class] upperLabelTextForForm:passwordForm_ style:style];
70     upperLabel_ = [[self class] labelWithText:upperLabelText];
71     [self addSubview:upperLabel_];
73     NSString* lowerLabelText =
74         [[self class] lowerLabelTextForForm:passwordForm_];
75     if (lowerLabelText) {
76       lowerLabel_ = [[self class] labelWithText:lowerLabelText];
77       [self addSubview:lowerLabel_];
78     }
80     // Compute the heights and widths of everything, as the layout depends on
81     // these measurements.
82     const CGFloat labelsHeight = NSHeight([upperLabel_ frame]) +
83                                  NSHeight([lowerLabel_ frame]) +
84                                  kVerticalPaddingBetweenLabels;
85     const CGFloat height = std::max(labelsHeight, CGFloat(kAvatarImageSize));
86     const CGFloat width =
87         kAvatarImageSize + kHorizontalPaddingBetweenAvatarAndLabels +
88         std::max(NSWidth([upperLabel_ frame]), NSWidth([lowerLabel_ frame]));
89     self.frame = NSMakeRect(0, 0, width, height);
91     // Lay out the views (RTL reverses the order horizontally).
93     const CGFloat avatarX = base::i18n::IsRTL() ? width - kAvatarImageSize : 0;
94     const CGFloat avatarY =
95         (kAvatarImageSize > height) ? 0 : (height - kAvatarImageSize) / 2.0f;
96     [avatarView_ setFrame:NSMakeRect(avatarX, avatarY, kAvatarImageSize,
97                                      kAvatarImageSize)];
99     const CGFloat lowerX =
100         base::i18n::IsRTL()
101             ? NSMinX([avatarView_ frame]) -
102                   kHorizontalPaddingBetweenAvatarAndLabels -
103                   NSWidth([lowerLabel_ frame])
104             : NSMaxX([avatarView_ frame]) +
105                   kHorizontalPaddingBetweenAvatarAndLabels;
106     const CGFloat lowerLabelY =
107         (labelsHeight > height) ? 0 : (height - labelsHeight) / 2.0f;
108     NSRect lowerFrame = [lowerLabel_ frame];
109     lowerFrame.origin = NSMakePoint(lowerX, lowerLabelY);
110     [lowerLabel_ setFrame:lowerFrame];
112     const CGFloat upperX = base::i18n::IsRTL()
113                               ? NSMinX([avatarView_ frame]) -
114                                     kHorizontalPaddingBetweenAvatarAndLabels -
115                                     NSWidth([upperLabel_ frame])
116                               : NSMaxX([avatarView_ frame]) +
117                                     kHorizontalPaddingBetweenAvatarAndLabels;
118     const CGFloat upperLabelY =
119         NSMaxY(lowerFrame) + kVerticalPaddingBetweenLabels;
120     NSRect upperFrame = [upperLabel_ frame];
121     upperFrame.origin = NSMakePoint(upperX, upperLabelY);
122     [upperLabel_ setFrame:upperFrame];
124     // Use a default avatar and fetch the custom one, if it exists.
125     [self updateAvatar:[[self class] defaultAvatar]];
126     if (passwordForm_.icon_url.is_valid())
127       [delegate_ fetchAvatar:passwordForm_.icon_url forView:self];
129     // When resizing, stick to the left (resp. right for RTL) edge.
130     const NSUInteger autoresizingMask =
131         (base::i18n::IsRTL() ? NSViewMinXMargin : NSViewMaxXMargin);
132     [avatarView_ setAutoresizingMask:autoresizingMask];
133     [lowerLabel_ setAutoresizingMask:autoresizingMask];
134     [upperLabel_ setAutoresizingMask:autoresizingMask];
135     [self setAutoresizingMask:NSViewWidthSizable];
136   }
138   return self;
141 - (void)updateAvatar:(NSImage*)avatar {
142   [avatarView_ setImage:avatar];
145 + (NSImage*)defaultAvatar {
146   return gfx::NSImageFromImageSkia(ScaleImageForAccountAvatar(
147       *ResourceBundle::GetSharedInstance()
148            .GetImageNamed(IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE)
149            .ToImageSkia()));
152 + (NSString*)upperLabelTextForForm:(const autofill::PasswordForm&)passwordForm
153                              style:(password_manager_mac::CredentialItemStyle)
154                                        style {
155   base::string16 name = passwordForm.display_name.empty()
156                             ? passwordForm.username_value
157                             : passwordForm.display_name;
158   switch (style) {
159     case password_manager_mac::CredentialItemStyle::ACCOUNT_CHOOSER:
160       return base::SysUTF16ToNSString(name);
161     case password_manager_mac::CredentialItemStyle::AUTO_SIGNIN:
162       return l10n_util::GetNSStringF(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE,
163                                      name);
164   }
165   NOTREACHED();
166   return nil;
169 + (NSString*)lowerLabelTextForForm:
170         (const autofill::PasswordForm&)passwordForm {
171   return passwordForm.display_name.empty()
172              ? nil
173              : base::SysUTF16ToNSString(passwordForm.username_value);
176 + (NSTextField*)labelWithText:(NSString*)title {
177   NSTextField* label =
178       [[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease];
179   [label setBezeled:NO];
180   [label setDrawsBackground:NO];
181   [label setEditable:NO];
182   [label setSelectable:NO];
183   [label setStringValue:title];
184   [label setAlignment:base::i18n::IsRTL() ? NSRightTextAlignment
185                                           : NSLeftTextAlignment];
186   [label sizeToFit];
187   return label;
190 @end