cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / ios / chrome / browser / autofill / form_suggestion_label.mm
bloba2cfc9875e903f86149d1c6fe32b5e316b624817
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 #include "ios/chrome/browser/ui/ui_util.h"
17 namespace {
19 // The button corner radius.
20 const CGFloat kCornerRadius = 3.0f;
22 // The width of the border in the button background image.
23 const CGFloat kBorderWidth = 1.0f;
25 // Font size of button titles.
26 const CGFloat kIpadFontSize = 15.0f;
27 const CGFloat kIphoneFontSize = 13.0f;
29 // The grayscale value of the color object.
30 const CGFloat kTitleColor = 51.0f / 255.0f;
32 // The alpha value of the suggestion's description label.
33 const CGFloat kDescriptionLabelAlpha = 0.54f;
35 // The edge inset for background image.
36 const CGFloat kBackgroundImageEdgeInsetSize = 8.0f;
37 // The space between items in the label.
38 const CGFloat kSpacing = 8.0f;
40 // Structure that record the image for each icon.
41 struct IconImageMap {
42   const char* const icon_name;
43   NSString* image_name;
46 const IconImageMap kCreditCardIconImageMap[] = {
47     {autofill::kAmericanExpressCard, @"autofill_card_american_express"},
48     {autofill::kDiscoverCard, @"autofill_card_discover"},
49     {autofill::kMasterCard, @"autofill_card_mastercard"},
50     {autofill::kVisaCard, @"autofill_card_visa"},
51     {autofill::kDinersCard, @"autofill_card_diners"},
52     {autofill::kGenericCard, @"autofill_card_generic"},
53     {autofill::kJCBCard, @"autofill_card_jcb"},
54     {autofill::kUnionPay, @"autofill_card_unionpay"},
57 // Creates a label with the given |text| and |alpha| suitable for use in a
58 // suggestion button in the keyboard accessory view.
59 UILabel* TextLabel(NSString* text, CGFloat alpha) {
60   base::scoped_nsobject<UILabel> label([[UILabel alloc] init]);
61   [label setText:text];
62   UIFont* font = IsIPadIdiom() ? [UIFont systemFontOfSize:kIpadFontSize]
63                                : [UIFont systemFontOfSize:kIphoneFontSize];
64   [label setFont:font];
65   [label setTextColor:[UIColor colorWithWhite:kTitleColor alpha:alpha]];
66   [label setBackgroundColor:[UIColor clearColor]];
67   [label sizeToFit];
68   return label.autorelease();
71 }  // namespace
73 @interface FormSuggestionLabel ()
75 @property(nonatomic, readonly) UIColor* normalBackgroundColor;
76 @property(nonatomic, readonly) UIColor* pressedBackgroundColor;
78 // Returns the color generated from the image named |imageName| resized to
79 // |rect|.
80 - (UIColor*)backgroundColorFromImageNamed:(NSString*)imageName
81                                    inRect:(CGRect)rect;
82 // Returns the name of the image for credit card icon.
83 + (NSString*)imageNameForCreditCardIcon:(NSString*)icon;
84 @end
86 @implementation FormSuggestionLabel {
87   // Client of this view.
88   base::WeakNSProtocol<id<FormSuggestionViewClient>> client_;
89   base::scoped_nsobject<FormSuggestion> suggestion_;
91   // Background color when the label is not pressed.
92   base::scoped_nsobject<UIColor> normalBackgroundColor_;
93   // Background color when the label is pressed.
94   base::scoped_nsobject<UIColor> pressedBackgroundColor_;
97 - (id)initWithSuggestion:(FormSuggestion*)suggestion
98            proposedFrame:(CGRect)proposedFrame
99                   client:(id<FormSuggestionViewClient>)client {
100   // TODO(jimblackler): implement sizeThatFits: and layoutSubviews, and perform
101   // layout in those methods instead of in the designated initializer.
102   self = [super initWithFrame:CGRectZero];
103   if (self) {
104     suggestion_.reset([suggestion retain]);
105     client_.reset(client);
107     const CGFloat frameHeight = CGRectGetHeight(proposedFrame);
108     CGFloat currentX = kBorderWidth + kSpacing;
110     // [UIImage imageNamed:] writes error message if nil is passed. Prevent
111     // console spam by checking the name first.
112     NSString* iconImageName =
113         [FormSuggestionLabel imageNameForCreditCardIcon:suggestion.icon];
114     UIImage* iconImage = nil;
115     if (iconImageName)
116       iconImage = [UIImage imageNamed:iconImageName];
117     if (iconImage) {
118       UIImageView* iconView =
119           [[[UIImageView alloc] initWithImage:iconImage] autorelease];
120       const CGFloat iconY =
121           std::floor((frameHeight - iconImage.size.height) / 2.0f);
122       iconView.frame = CGRectMake(currentX, iconY, iconImage.size.width,
123                                   iconImage.size.height);
124       [self addSubview:iconView];
125       currentX += CGRectGetWidth(iconView.frame) + kSpacing;
126     }
128     UILabel* label = TextLabel(suggestion.value, 1.0f);
129     const CGFloat labelY =
130         std::floor(frameHeight / 2.0f - CGRectGetMidY(label.frame));
131     label.frame = CGRectMake(currentX, labelY, CGRectGetWidth(label.frame),
132                              CGRectGetHeight(label.frame));
133     [self addSubview:label];
134     currentX += CGRectGetWidth(label.frame) + kSpacing;
136     if (suggestion.displayDescription) {
137       UILabel* description =
138           TextLabel(suggestion.displayDescription, kDescriptionLabelAlpha);
139       const CGFloat descriptionY =
140           std::floor(frameHeight / 2.0f - CGRectGetMidY(description.frame));
141       description.frame =
142           CGRectMake(currentX, descriptionY, CGRectGetWidth(description.frame),
143                      CGRectGetHeight(description.frame));
144       [self addSubview:description];
145       currentX += CGRectGetWidth(description.frame) + kSpacing;
146     }
148     currentX += kBorderWidth;
150     self.frame = CGRectMake(proposedFrame.origin.x, proposedFrame.origin.y,
151                             currentX, proposedFrame.size.height);
152     [self setBackgroundColor:[self normalBackgroundColor]];
153     [[self layer] setCornerRadius:kCornerRadius];
155     [self setClipsToBounds:YES];
156     [self setIsAccessibilityElement:YES];
157     [self setAccessibilityLabel:suggestion.value];
158     [self setUserInteractionEnabled:YES];
159   }
161   return self;
164 - (id)initWithFrame:(CGRect)frame {
165   NOTREACHED();
166   return nil;
169 - (void)layoutSubviews {
170   // Resets the colors so the size will be updated in their getters.
171   normalBackgroundColor_.reset();
172   pressedBackgroundColor_.reset();
173   [super layoutSubviews];
176 #pragma mark -
177 #pragma mark UIResponder
179 - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
180   [self setBackgroundColor:self.pressedBackgroundColor];
183 - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
184   [self setBackgroundColor:self.normalBackgroundColor];
187 - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
188   [self setBackgroundColor:self.normalBackgroundColor];
189   [client_ didSelectSuggestion:suggestion_];
192 #pragma mark -
193 #pragma mark Private
195 - (UIColor*)normalBackgroundColor {
196   if (!normalBackgroundColor_) {
197     normalBackgroundColor_.reset(
198         [[self backgroundColorFromImageNamed:@"autofill_button"
199                                       inRect:self.bounds] retain]);
200   }
201   return normalBackgroundColor_;
204 - (UIColor*)pressedBackgroundColor {
205   if (!pressedBackgroundColor_) {
206     pressedBackgroundColor_.reset(
207         [[self backgroundColorFromImageNamed:@"autofill_button_pressed"
208                                       inRect:self.bounds] retain]);
209   }
210   return pressedBackgroundColor_;
213 - (UIColor*)backgroundColorFromImageNamed:(NSString*)imageName
214                                    inRect:(CGRect)rect {
215   UIEdgeInsets edgeInsets = UIEdgeInsetsMake(
216       kBackgroundImageEdgeInsetSize, kBackgroundImageEdgeInsetSize,
217       kBackgroundImageEdgeInsetSize, kBackgroundImageEdgeInsetSize);
218   UIImage* image =
219       [[UIImage imageNamed:imageName] resizableImageWithCapInsets:edgeInsets];
221   UIGraphicsBeginImageContextWithOptions(rect.size, NO,
222                                          UIScreen.mainScreen.scale);
223   [image drawInRect:rect];
224   UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
225   UIGraphicsEndImageContext();
227   return [UIColor colorWithPatternImage:resizedImage];
230 + (NSString*)imageNameForCreditCardIcon:(NSString*)icon {
231   if (!icon || [icon length] == 0) {
232     return nil;
233   }
234   std::string iconName(base::SysNSStringToUTF8(icon));
235   for (size_t i = 0; i < arraysize(kCreditCardIconImageMap); ++i) {
236     if (iconName.compare(kCreditCardIconImageMap[i].icon_name) == 0) {
237       return kCreditCardIconImageMap[i].image_name;
238     }
239   }
240   return nil;
243 @end