Index: ios/chrome/browser/autofill/form_suggestion_label.mm |
diff --git a/ios/chrome/browser/autofill/form_suggestion_label.mm b/ios/chrome/browser/autofill/form_suggestion_label.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..60e90222d1cdd9099b32bb53c24f858e201e84fe |
--- /dev/null |
+++ b/ios/chrome/browser/autofill/form_suggestion_label.mm |
@@ -0,0 +1,238 @@ |
+// 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" |
+ |
+#include <cmath> |
+ |
+#import <QuartzCore/QuartzCore.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" |
+ |
+namespace { |
+ |
+// The button corner radius. |
+const CGFloat kCornerRadius = 3.0f; |
+ |
+// The width of the border in the button background image. |
+const CGFloat kBorderWidth = 1.0f; |
+ |
+// Font size of button titles. |
+const CGFloat kIpadFontSize = 15.0f; |
+const CGFloat kIphoneFontSize = 13.0f; |
+ |
+// The grayscale value of the color object. |
+const CGFloat kTitleColor = 51.0f / 255.0f; |
+ |
+// The alpha value of the suggestion's description label. |
+const CGFloat kDescriptionLabelAlpha = 0.54f; |
+ |
+// The edge inset for background image. |
+const CGFloat kBackgroundImageEdgeInsetSize = 8.0f; |
+// The space between items in the label. |
+const CGFloat kSpacing = 8.0f; |
+ |
+// 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::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) { |
+ base::scoped_nsobject<UILabel> label([[UILabel alloc] init]); |
+ [label setText:text]; |
+ UIFont* font = IsIPadIdiom() ? [UIFont systemFontOfSize:kIpadFontSize] |
+ : [UIFont systemFontOfSize:kIphoneFontSize]; |
+ [label setFont:font]; |
+ [label setTextColor:[UIColor colorWithWhite:kTitleColor alpha:alpha]]; |
+ [label setBackgroundColor:[UIColor clearColor]]; |
+ [label sizeToFit]; |
+ return label.autorelease(); |
+} |
+ |
+} // namespace |
+ |
+@interface FormSuggestionLabel () |
+ |
+@property(nonatomic, readonly) UIColor* normalBackgroundColor; |
+@property(nonatomic, readonly) UIColor* pressedBackgroundColor; |
+ |
+// Returns the color generated from the image named |imageName| resized to |
+// |rect|. |
+- (UIColor*)backgroundColorFromImageNamed:(NSString*)imageName |
+ inRect:(CGRect)rect; |
+// Returns the name of the image for credit card icon. |
++ (NSString*)imageNameForCreditCardIcon:(NSString*)icon; |
+@end |
+ |
+@implementation FormSuggestionLabel { |
+ // Client of this view. |
+ base::WeakNSProtocol<id<FormSuggestionViewClient>> client_; |
+ base::scoped_nsobject<FormSuggestion> suggestion_; |
+ |
+ // Background color when the label is not pressed. |
+ base::scoped_nsobject<UIColor> normalBackgroundColor_; |
+ // Background color when the label is pressed. |
+ base::scoped_nsobject<UIColor> pressedBackgroundColor_; |
+} |
+ |
+- (id)initWithSuggestion:(FormSuggestion*)suggestion |
+ proposedFrame:(CGRect)proposedFrame |
+ 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_.reset([suggestion retain]); |
+ client_.reset(client); |
+ |
+ const CGFloat frameHeight = CGRectGetHeight(proposedFrame); |
+ CGFloat currentX = kBorderWidth + kSpacing; |
+ |
+ UIImage* iconImage = [UIImage imageNamed: |
+ [FormSuggestionLabel imageNameForCreditCardIcon:suggestion.icon]]; |
+ if (iconImage) { |
+ UIImageView* iconView = |
+ [[[UIImageView alloc] initWithImage:iconImage] autorelease]; |
+ 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, 1.0f); |
+ 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) + kSpacing; |
+ |
+ if (suggestion.displayDescription) { |
+ UILabel* description = |
+ TextLabel(suggestion.displayDescription, kDescriptionLabelAlpha); |
+ 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) + kSpacing; |
+ } |
+ |
+ currentX += kBorderWidth; |
+ |
+ self.frame = CGRectMake(proposedFrame.origin.x, proposedFrame.origin.y, |
+ currentX, proposedFrame.size.height); |
+ [self setBackgroundColor:[self normalBackgroundColor]]; |
+ [[self layer] setCornerRadius:kCornerRadius]; |
+ |
+ [self setClipsToBounds:YES]; |
+ [self setIsAccessibilityElement:YES]; |
+ [self setAccessibilityLabel:suggestion.value]; |
+ [self setUserInteractionEnabled:YES]; |
+ } |
+ |
+ return self; |
+} |
+ |
+- (id)initWithFrame:(CGRect)frame { |
+ NOTREACHED(); |
+ return nil; |
+} |
+ |
+- (void)layoutSubviews { |
+ // Resets the colors so the size will be updated in their getters. |
+ normalBackgroundColor_.reset(); |
+ pressedBackgroundColor_.reset(); |
+ [super layoutSubviews]; |
+} |
+ |
+#pragma mark - |
+#pragma mark UIResponder |
+ |
+- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { |
+ [self setBackgroundColor:self.pressedBackgroundColor]; |
+} |
+ |
+- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { |
+ [self setBackgroundColor:self.normalBackgroundColor]; |
+} |
+ |
+- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { |
+ [self setBackgroundColor:self.normalBackgroundColor]; |
+ [client_ didSelectSuggestion:suggestion_]; |
+} |
+ |
+#pragma mark - |
+#pragma mark Private |
+ |
+- (UIColor*)normalBackgroundColor { |
+ if (!normalBackgroundColor_) { |
+ normalBackgroundColor_.reset( |
+ [[self backgroundColorFromImageNamed:@"autofill_button" |
+ inRect:self.bounds] retain]); |
+ } |
+ return normalBackgroundColor_; |
+} |
+ |
+- (UIColor*)pressedBackgroundColor { |
+ if (!pressedBackgroundColor_) { |
+ pressedBackgroundColor_.reset( |
+ [[self backgroundColorFromImageNamed:@"autofill_button_pressed" |
+ inRect:self.bounds] retain]); |
+ } |
+ return pressedBackgroundColor_; |
+} |
+ |
+- (UIColor*)backgroundColorFromImageNamed:(NSString*)imageName |
+ inRect:(CGRect)rect { |
+ UIEdgeInsets edgeInsets = UIEdgeInsetsMake( |
+ kBackgroundImageEdgeInsetSize, kBackgroundImageEdgeInsetSize, |
+ kBackgroundImageEdgeInsetSize, kBackgroundImageEdgeInsetSize); |
+ UIImage* image = |
+ [[UIImage imageNamed:imageName] resizableImageWithCapInsets:edgeInsets]; |
+ |
+ UIGraphicsBeginImageContextWithOptions(rect.size, NO, |
+ UIScreen.mainScreen.scale); |
+ [image drawInRect:rect]; |
+ UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext(); |
+ UIGraphicsEndImageContext(); |
+ |
+ return [UIColor colorWithPatternImage:resizedImage]; |
+} |
+ |
++ (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 |