blob: 490becb39d2a0c9d35d9d6aa68aafead5387fe56 [file] [log] [blame]
// Copyright 2013 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 "ios/chrome/browser/autofill/form_suggestion_label.h"
#import <QuartzCore/QuartzCore.h>
#include <stddef.h>
#include <cmath>
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "components/autofill/core/browser/credit_card.h"
#import "components/autofill/ios/browser/form_suggestion.h"
#import "ios/chrome/browser/autofill/form_suggestion_view_client.h"
#include "ios/chrome/browser/ui/ui_util.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The button corner radius.
const CGFloat kCornerRadius = 2.0f;
// Font size of button titles.
const CGFloat kIpadFontSize = 15.0f;
const CGFloat kIphoneFontSize = 14.0f;
// The alpha values of the suggestion's main and description labels.
const CGFloat kMainLabelAlpha = 0.87f;
const CGFloat kDescriptionLabelAlpha = 0.55f;
// The horizontal space between the edge of the background and the text.
const CGFloat kBorderWidth = 8.0f;
// The space between items in the label.
const CGFloat kSpacing = 4.0f;
// RGB button color when the button is not pressed.
const int kBackgroundNormalColor = 0xeceff1;
// RGB button color when the button is pressed.
const int kBackgroundPressedColor = 0xc4cbcf;
// Structure that record the image for each icon.
struct IconImageMap {
const char* const icon_name;
NSString* image_name;
};
const IconImageMap kCreditCardIconImageMap[] = {
{autofill::kAmericanExpressCard, @"autofill_card_american_express"},
{autofill::kDiscoverCard, @"autofill_card_discover"},
{autofill::kMasterCard, @"autofill_card_mastercard"},
{autofill::kMirCard, @"autofill_card_mir"},
{autofill::kVisaCard, @"autofill_card_visa"},
{autofill::kDinersCard, @"autofill_card_diners"},
{autofill::kGenericCard, @"autofill_card_generic"},
{autofill::kJCBCard, @"autofill_card_jcb"},
{autofill::kUnionPay, @"autofill_card_unionpay"},
};
// Creates a label with the given |text| and |alpha| suitable for use in a
// suggestion button in the keyboard accessory view.
UILabel* TextLabel(NSString* text, CGFloat alpha, BOOL bold) {
UILabel* label = [[UILabel alloc] init];
[label setText:text];
CGFloat fontSize = IsIPadIdiom() ? kIpadFontSize : kIphoneFontSize;
UIFont* font = bold ? [UIFont boldSystemFontOfSize:fontSize]
: [UIFont systemFontOfSize:fontSize];
[label setFont:font];
[label setTextColor:[UIColor colorWithWhite:0.0f alpha:alpha]];
[label setBackgroundColor:[UIColor clearColor]];
[label sizeToFit];
return label;
}
} // namespace
@interface FormSuggestionLabel ()
// Returns the name of the image for credit card icon.
+ (NSString*)imageNameForCreditCardIcon:(NSString*)icon;
@end
@implementation FormSuggestionLabel {
// Client of this view.
__weak id<FormSuggestionViewClient> client_;
FormSuggestion* suggestion_;
}
- (id)initWithSuggestion:(FormSuggestion*)suggestion
proposedFrame:(CGRect)proposedFrame
index:(NSUInteger)index
numSuggestions:(NSUInteger)numSuggestions
client:(id<FormSuggestionViewClient>)client {
// TODO(jimblackler): implement sizeThatFits: and layoutSubviews, and perform
// layout in those methods instead of in the designated initializer.
self = [super initWithFrame:CGRectZero];
if (self) {
suggestion_ = suggestion;
client_ = client;
const CGFloat frameHeight = CGRectGetHeight(proposedFrame);
CGFloat currentX = kBorderWidth;
// [UIImage imageNamed:] writes error message if nil is passed. Prevent
// console spam by checking the name first.
NSString* iconImageName =
[FormSuggestionLabel imageNameForCreditCardIcon:suggestion.icon];
UIImage* iconImage = nil;
if (iconImageName)
iconImage = [UIImage imageNamed:iconImageName];
if (iconImage) {
UIImageView* iconView = [[UIImageView alloc] initWithImage:iconImage];
const CGFloat iconY =
std::floor((frameHeight - iconImage.size.height) / 2.0f);
iconView.frame = CGRectMake(currentX, iconY, iconImage.size.width,
iconImage.size.height);
[self addSubview:iconView];
currentX += CGRectGetWidth(iconView.frame) + kSpacing;
}
UILabel* label = TextLabel(suggestion.value, kMainLabelAlpha, YES);
const CGFloat labelY =
std::floor(frameHeight / 2.0f - CGRectGetMidY(label.frame));
label.frame = CGRectMake(currentX, labelY, CGRectGetWidth(label.frame),
CGRectGetHeight(label.frame));
[self addSubview:label];
currentX += CGRectGetWidth(label.frame);
if ([suggestion.displayDescription length] > 0) {
currentX += kSpacing;
UILabel* description =
TextLabel(suggestion.displayDescription, kDescriptionLabelAlpha, NO);
const CGFloat descriptionY =
std::floor(frameHeight / 2.0f - CGRectGetMidY(description.frame));
description.frame =
CGRectMake(currentX, descriptionY, CGRectGetWidth(description.frame),
CGRectGetHeight(description.frame));
[self addSubview:description];
currentX += CGRectGetWidth(description.frame);
}
currentX += kBorderWidth;
self.frame = CGRectMake(proposedFrame.origin.x, proposedFrame.origin.y,
currentX, proposedFrame.size.height);
[self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
[[self layer] setCornerRadius:kCornerRadius];
[self setClipsToBounds:YES];
[self setUserInteractionEnabled:YES];
[self setIsAccessibilityElement:YES];
[self setAccessibilityLabel:l10n_util::GetNSStringF(
IDS_IOS_AUTOFILL_ACCNAME_SUGGESTION,
base::SysNSStringToUTF16(suggestion.value),
base::SysNSStringToUTF16(
suggestion.displayDescription),
base::IntToString16(index + 1),
base::IntToString16(numSuggestions))];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
NOTREACHED();
return nil;
}
#pragma mark -
#pragma mark UIResponder
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[self setBackgroundColor:UIColorFromRGB(kBackgroundPressedColor)];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
[self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
[client_ didSelectSuggestion:suggestion_];
}
#pragma mark -
#pragma mark Private
+ (NSString*)imageNameForCreditCardIcon:(NSString*)icon {
if (!icon || [icon length] == 0) {
return nil;
}
std::string iconName(base::SysNSStringToUTF8(icon));
for (size_t i = 0; i < arraysize(kCreditCardIconImageMap); ++i) {
if (iconName.compare(kCreditCardIconImageMap[i].icon_name) == 0) {
return kCreditCardIconImageMap[i].image_name;
}
}
return nil;
}
@end