Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ios / chrome / browser / autofill / form_suggestion_label.mm
blob099a8e778c67569f4d0cab76c4433fb8798eb7bd
1 // Copyright 2013 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 "ios/chrome/browser/autofill/form_suggestion_label.h"
7 #include <cmath>
9 #import <QuartzCore/QuartzCore.h>
11 #include "base/strings/sys_string_conversions.h"
12 #include "components/autofill/core/browser/credit_card.h"
13 #import "components/autofill/ios/browser/form_suggestion.h"
14 #import "ios/chrome/browser/autofill/form_suggestion_view_client.h"
15 #import "ios/chrome/browser/ui/uikit_ui_util.h"
16 #include "ios/chrome/browser/ui/ui_util.h"
18 namespace {
20 // The button corner radius.
21 const CGFloat kCornerRadius = 2.0f;
23 // Font size of button titles.
24 const CGFloat kIpadFontSize = 15.0f;
25 const CGFloat kIphoneFontSize = 14.0f;
27 // The alpha values of the suggestion's main and description labels.
28 const CGFloat kMainLabelAlpha = 0.87f;
29 const CGFloat kDescriptionLabelAlpha = 0.55f;
31 // The horizontal space between the edge of the background and the text.
32 const CGFloat kBorderWidth = 8.0f;
33 // The space between items in the label.
34 const CGFloat kSpacing = 4.0f;
36 // RGB button color when the button is not pressed.
37 const int kBackgroundNormalColor = 0xeceff1;
38 // RGB button color when the button is pressed.
39 const int kBackgroundPressedColor = 0xc4cbcf;
41 // Structure that record the image for each icon.
42 struct IconImageMap {
43   const char* const icon_name;
44   NSString* image_name;
47 const IconImageMap kCreditCardIconImageMap[] = {
48     {autofill::kAmericanExpressCard, @"autofill_card_american_express"},
49     {autofill::kDiscoverCard, @"autofill_card_discover"},
50     {autofill::kMasterCard, @"autofill_card_mastercard"},
51     {autofill::kVisaCard, @"autofill_card_visa"},
52     {autofill::kDinersCard, @"autofill_card_diners"},
53     {autofill::kGenericCard, @"autofill_card_generic"},
54     {autofill::kJCBCard, @"autofill_card_jcb"},
55     {autofill::kUnionPay, @"autofill_card_unionpay"},
58 // Creates a label with the given |text| and |alpha| suitable for use in a
59 // suggestion button in the keyboard accessory view.
60 UILabel* TextLabel(NSString* text, CGFloat alpha, BOOL bold) {
61   base::scoped_nsobject<UILabel> label([[UILabel alloc] init]);
62   [label setText:text];
63   CGFloat fontSize = IsIPadIdiom() ? kIpadFontSize : kIphoneFontSize;
64   UIFont* font = bold ? [UIFont boldSystemFontOfSize:fontSize]
65                       : [UIFont systemFontOfSize:fontSize];
66   [label setFont:font];
67   [label setTextColor:[UIColor colorWithWhite:0.0f alpha:alpha]];
68   [label setBackgroundColor:[UIColor clearColor]];
69   [label sizeToFit];
70   return label.autorelease();
73 }  // namespace
75 @interface FormSuggestionLabel ()
77 // Returns the name of the image for credit card icon.
78 + (NSString*)imageNameForCreditCardIcon:(NSString*)icon;
79 @end
81 @implementation FormSuggestionLabel {
82   // Client of this view.
83   base::WeakNSProtocol<id<FormSuggestionViewClient>> client_;
84   base::scoped_nsobject<FormSuggestion> suggestion_;
87 - (id)initWithSuggestion:(FormSuggestion*)suggestion
88            proposedFrame:(CGRect)proposedFrame
89                   client:(id<FormSuggestionViewClient>)client {
90   // TODO(jimblackler): implement sizeThatFits: and layoutSubviews, and perform
91   // layout in those methods instead of in the designated initializer.
92   self = [super initWithFrame:CGRectZero];
93   if (self) {
94     suggestion_.reset([suggestion retain]);
95     client_.reset(client);
97     const CGFloat frameHeight = CGRectGetHeight(proposedFrame);
98     CGFloat currentX = kBorderWidth;
100     // [UIImage imageNamed:] writes error message if nil is passed. Prevent
101     // console spam by checking the name first.
102     NSString* iconImageName =
103         [FormSuggestionLabel imageNameForCreditCardIcon:suggestion.icon];
104     UIImage* iconImage = nil;
105     if (iconImageName)
106       iconImage = [UIImage imageNamed:iconImageName];
107     if (iconImage) {
108       UIImageView* iconView =
109           [[[UIImageView alloc] initWithImage:iconImage] autorelease];
110       const CGFloat iconY =
111           std::floor((frameHeight - iconImage.size.height) / 2.0f);
112       iconView.frame = CGRectMake(currentX, iconY, iconImage.size.width,
113                                   iconImage.size.height);
114       [self addSubview:iconView];
115       currentX += CGRectGetWidth(iconView.frame) + kSpacing;
116     }
118     UILabel* label = TextLabel(suggestion.value, kMainLabelAlpha, YES);
119     const CGFloat labelY =
120         std::floor(frameHeight / 2.0f - CGRectGetMidY(label.frame));
121     label.frame = CGRectMake(currentX, labelY, CGRectGetWidth(label.frame),
122                              CGRectGetHeight(label.frame));
123     [self addSubview:label];
124     currentX += CGRectGetWidth(label.frame);
126     if ([suggestion.displayDescription length] > 0) {
127       currentX += kSpacing;
128       UILabel* description =
129           TextLabel(suggestion.displayDescription, kDescriptionLabelAlpha, NO);
130       const CGFloat descriptionY =
131           std::floor(frameHeight / 2.0f - CGRectGetMidY(description.frame));
132       description.frame =
133           CGRectMake(currentX, descriptionY, CGRectGetWidth(description.frame),
134                      CGRectGetHeight(description.frame));
135       [self addSubview:description];
136       currentX += CGRectGetWidth(description.frame);
137     }
139     currentX += kBorderWidth;
141     self.frame = CGRectMake(proposedFrame.origin.x, proposedFrame.origin.y,
142                             currentX, proposedFrame.size.height);
143     [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
144     [[self layer] setCornerRadius:kCornerRadius];
146     [self setClipsToBounds:YES];
147     [self setIsAccessibilityElement:YES];
148     [self setAccessibilityLabel:suggestion.value];
149     [self setUserInteractionEnabled:YES];
150   }
152   return self;
155 - (id)initWithFrame:(CGRect)frame {
156   NOTREACHED();
157   return nil;
160 #pragma mark -
161 #pragma mark UIResponder
163 - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
164   [self setBackgroundColor:UIColorFromRGB(kBackgroundPressedColor)];
167 - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
168   [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
171 - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
172   [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
173   [client_ didSelectSuggestion:suggestion_];
176 #pragma mark -
177 #pragma mark Private
179 + (NSString*)imageNameForCreditCardIcon:(NSString*)icon {
180   if (!icon || [icon length] == 0) {
181     return nil;
182   }
183   std::string iconName(base::SysNSStringToUTF8(icon));
184   for (size_t i = 0; i < arraysize(kCreditCardIconImageMap); ++i) {
185     if (iconName.compare(kCreditCardIconImageMap[i].icon_name) == 0) {
186       return kCreditCardIconImageMap[i].image_name;
187     }
188   }
189   return nil;
192 @end