blob: 2ab98a9cd75d193e4787e98931fb90d0f22af457 [file] [log] [blame]
// 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 <algorithm>
#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<CredentialItemDelegate>)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