// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #import "chrome/browser/ui/cocoa/passwords/credential_item_view.h" #include #include "base/i18n/rtl.h" #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/grit/generated_resources.h" #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_util_mac.h" namespace { const CGFloat kHorizontalPaddingBetweenAvatarAndLabels = 10.0f; const CGFloat kVerticalPaddingBetweenLabels = 2.0f; } // namespace @interface CredentialItemView() + (NSString*)upperLabelTextForForm:(const autofill::PasswordForm&)passwordForm style:(password_manager_mac::CredentialItemStyle) style; + (NSString*)lowerLabelTextForForm: (const autofill::PasswordForm&)passwordForm; + (NSTextField*)labelWithText:(NSString*)title; @property(nonatomic, readonly) NSTextField* upperLabel; @property(nonatomic, readonly) NSTextField* lowerLabel; @property(nonatomic, readonly) NSImageView* avatarView; @end @implementation CredentialItemView @synthesize upperLabel = upperLabel_; @synthesize lowerLabel = lowerLabel_; @synthesize avatarView = avatarView_; @synthesize passwordForm = passwordForm_; @synthesize credentialType = credentialType_; - (id)initWithPasswordForm:(const autofill::PasswordForm&)passwordForm credentialType:(password_manager::CredentialType)credentialType style:(password_manager_mac::CredentialItemStyle)style delegate:(id)delegate { if ((self = [super init])) { passwordForm_ = passwordForm; credentialType_ = credentialType; delegate_ = delegate; // ----------------------------------------------- // | | John Q. Facebooker | // | icon | john@somewhere.com | // ----------------------------------------------- // Create the views. avatarView_ = [[[NSImageView alloc] initWithFrame:NSZeroRect] autorelease]; [avatarView_ setWantsLayer:YES]; [[avatarView_ layer] setCornerRadius:kAvatarImageSize / 2.0f]; [[avatarView_ layer] setMasksToBounds:YES]; [self addSubview:avatarView_]; NSString* upperLabelText = [[self class] upperLabelTextForForm:passwordForm_ style:style]; upperLabel_ = [[self class] labelWithText:upperLabelText]; [self addSubview:upperLabel_]; NSString* lowerLabelText = [[self class] lowerLabelTextForForm:passwordForm_]; if (lowerLabelText) { lowerLabel_ = [[self class] labelWithText:lowerLabelText]; [self addSubview:lowerLabel_]; } // Compute the heights and widths of everything, as the layout depends on // these measurements. const CGFloat labelsHeight = NSHeight([upperLabel_ frame]) + NSHeight([lowerLabel_ frame]) + kVerticalPaddingBetweenLabels; const CGFloat height = std::max(labelsHeight, CGFloat(kAvatarImageSize)); const CGFloat width = kAvatarImageSize + kHorizontalPaddingBetweenAvatarAndLabels + std::max(NSWidth([upperLabel_ frame]), NSWidth([lowerLabel_ frame])); self.frame = NSMakeRect(0, 0, width, height); // Lay out the views (RTL reverses the order horizontally). const CGFloat avatarX = base::i18n::IsRTL() ? width - kAvatarImageSize : 0; const CGFloat avatarY = (kAvatarImageSize > height) ? 0 : (height - kAvatarImageSize) / 2.0f; [avatarView_ setFrame:NSMakeRect(avatarX, avatarY, kAvatarImageSize, kAvatarImageSize)]; const CGFloat lowerX = base::i18n::IsRTL() ? NSMinX([avatarView_ frame]) - kHorizontalPaddingBetweenAvatarAndLabels - NSWidth([lowerLabel_ frame]) : NSMaxX([avatarView_ frame]) + kHorizontalPaddingBetweenAvatarAndLabels; const CGFloat lowerLabelY = (labelsHeight > height) ? 0 : (height - labelsHeight) / 2.0f; NSRect lowerFrame = [lowerLabel_ frame]; lowerFrame.origin = NSMakePoint(lowerX, lowerLabelY); [lowerLabel_ setFrame:lowerFrame]; const CGFloat upperX = base::i18n::IsRTL() ? NSMinX([avatarView_ frame]) - kHorizontalPaddingBetweenAvatarAndLabels - NSWidth([upperLabel_ frame]) : NSMaxX([avatarView_ frame]) + kHorizontalPaddingBetweenAvatarAndLabels; const CGFloat upperLabelY = NSMaxY(lowerFrame) + kVerticalPaddingBetweenLabels; NSRect upperFrame = [upperLabel_ frame]; upperFrame.origin = NSMakePoint(upperX, upperLabelY); [upperLabel_ setFrame:upperFrame]; // Use a default avatar and fetch the custom one, if it exists. [self updateAvatar:[[self class] defaultAvatar]]; if (passwordForm_.icon_url.is_valid()) [delegate_ fetchAvatar:passwordForm_.icon_url forView:self]; // When resizing, stick to the left (resp. right for RTL) edge. const NSUInteger autoresizingMask = (base::i18n::IsRTL() ? NSViewMinXMargin : NSViewMaxXMargin); [avatarView_ setAutoresizingMask:autoresizingMask]; [lowerLabel_ setAutoresizingMask:autoresizingMask]; [upperLabel_ setAutoresizingMask:autoresizingMask]; [self setAutoresizingMask:NSViewWidthSizable]; } return self; } - (void)updateAvatar:(NSImage*)avatar { [avatarView_ setImage:avatar]; } + (NSImage*)defaultAvatar { return gfx::NSImageFromImageSkia(ScaleImageForAccountAvatar( *ResourceBundle::GetSharedInstance() .GetImageNamed(IDR_PROFILE_AVATAR_PLACEHOLDER_LARGE) .ToImageSkia())); } + (NSString*)upperLabelTextForForm:(const autofill::PasswordForm&)passwordForm style:(password_manager_mac::CredentialItemStyle) style { base::string16 name = passwordForm.display_name.empty() ? passwordForm.username_value : passwordForm.display_name; switch (style) { case password_manager_mac::CredentialItemStyle::ACCOUNT_CHOOSER: return base::SysUTF16ToNSString(name); case password_manager_mac::CredentialItemStyle::AUTO_SIGNIN: return l10n_util::GetNSStringF(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE, name); } NOTREACHED(); return nil; } + (NSString*)lowerLabelTextForForm: (const autofill::PasswordForm&)passwordForm { return passwordForm.display_name.empty() ? nil : base::SysUTF16ToNSString(passwordForm.username_value); } + (NSTextField*)labelWithText:(NSString*)title { NSTextField* label = [[[NSTextField alloc] initWithFrame:NSZeroRect] autorelease]; [label setBezeled:NO]; [label setDrawsBackground:NO]; [label setEditable:NO]; [label setSelectable:NO]; [label setStringValue:title]; [label setAlignment:base::i18n::IsRTL() ? NSRightTextAlignment : NSLeftTextAlignment]; [label sizeToFit]; return label; } @end