| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_promo_view.h" | 5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_promo_view.h" |
| 6 | 6 |
| 7 #include "base/ios/weak_nsobject.h" | |
| 8 #import "base/mac/scoped_nsobject.h" | |
| 9 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" | 7 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" |
| 10 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h" | 8 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h" |
| 11 #include "ios/chrome/browser/ui/uikit_ui_util.h" | 9 #include "ios/chrome/browser/ui/uikit_ui_util.h" |
| 12 #import "ios/chrome/browser/ui/util/label_link_controller.h" | 10 #import "ios/chrome/browser/ui/util/label_link_controller.h" |
| 13 #import "ios/chrome/common/material_timing.h" | 11 #import "ios/chrome/common/material_timing.h" |
| 14 #include "ios/chrome/common/string_util.h" | 12 #include "ios/chrome/common/string_util.h" |
| 15 #include "ios/chrome/grit/ios_strings.h" | 13 #include "ios/chrome/grit/ios_strings.h" |
| 16 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" | 14 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" |
| 17 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF
ontLoader.h" | 15 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF
ontLoader.h" |
| 18 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
| 19 #include "url/gurl.h" | 17 #include "url/gurl.h" |
| 20 | 18 |
| 19 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 20 #error "This file requires ARC support." |
| 21 #endif |
| 22 |
| 21 namespace { | 23 namespace { |
| 22 const int kMargin = 16; | 24 const int kMargin = 16; |
| 23 const int kSpaceBelowText = 32; | 25 const int kSpaceBelowText = 32; |
| 24 const int kButtonSeparator = 8; | 26 const int kButtonSeparator = 8; |
| 25 const int kButtonHeight = 36; | 27 const int kButtonHeight = 36; |
| 26 const int kButtonMinWidth = 88; | 28 const int kButtonMinWidth = 88; |
| 27 const int kDividerHeight = 1; | 29 const int kDividerHeight = 1; |
| 28 | 30 |
| 29 const int kTextFontSize = 16; | 31 const int kTextFontSize = 16; |
| 30 const int kButtonFontSize = 14; | 32 const int kButtonFontSize = 14; |
| 31 const CGFloat kTextColorGrayShade = 0.494; | 33 const CGFloat kTextColorGrayShade = 0.494; |
| 32 const int kLinkColorRGB = 0x5D9AFF; | 34 const int kLinkColorRGB = 0x5D9AFF; |
| 33 | 35 |
| 34 const CGFloat kLineSpace = 1.15; | 36 const CGFloat kLineSpace = 1.15; |
| 35 | 37 |
| 36 // Animation timings. | 38 // Animation timings. |
| 37 const CGFloat kCloseDuration = ios::material::kDuration1; | 39 const CGFloat kCloseDuration = ios::material::kDuration1; |
| 38 } | 40 } |
| 39 | 41 |
| 40 @interface ContextualSearchPromoView () | 42 @interface ContextualSearchPromoView () |
| 41 @property(nonatomic, assign) id<ContextualSearchPromoViewDelegate> delegate; | 43 @property(nonatomic, weak) id<ContextualSearchPromoViewDelegate> delegate; |
| 42 @end | 44 @end |
| 43 | 45 |
| 44 @implementation ContextualSearchPromoView { | 46 @implementation ContextualSearchPromoView { |
| 45 base::scoped_nsobject<LabelLinkController> _linkController; | 47 LabelLinkController* _linkController; |
| 46 base::scoped_nsobject<NSMutableArray> _constraints; | 48 NSMutableArray* _constraints; |
| 47 } | 49 } |
| 48 | 50 |
| 49 @synthesize disabled = _disabled; | 51 @synthesize disabled = _disabled; |
| 50 @synthesize delegate = _delegate; | 52 @synthesize delegate = _delegate; |
| 51 | 53 |
| 52 + (BOOL)requiresConstraintBasedLayout { | 54 + (BOOL)requiresConstraintBasedLayout { |
| 53 return YES; | 55 return YES; |
| 54 } | 56 } |
| 55 | 57 |
| 56 - (instancetype)initWithFrame:(CGRect)frame | 58 - (instancetype)initWithFrame:(CGRect)frame |
| 57 delegate:(id<ContextualSearchPromoViewDelegate>)delegate { | 59 delegate:(id<ContextualSearchPromoViewDelegate>)delegate { |
| 58 if (!(self = [super initWithFrame:frame])) | 60 if (!(self = [super initWithFrame:frame])) |
| 59 return nil; | 61 return nil; |
| 60 | 62 |
| 61 self.delegate = delegate; | 63 self.delegate = delegate; |
| 62 self.backgroundColor = [UIColor colorWithWhite:0.93 alpha:1.0]; | 64 self.backgroundColor = [UIColor colorWithWhite:0.93 alpha:1.0]; |
| 63 | 65 |
| 64 // Temp array to accumulate constraints as views are created. | 66 // Temp array to accumulate constraints as views are created. |
| 65 NSMutableArray* constraints = [NSMutableArray array]; | 67 NSMutableArray* constraints = [NSMutableArray array]; |
| 66 | 68 |
| 67 // Initialize text label and its link controller. | 69 // Initialize text label and its link controller. |
| 68 UILabel* text = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; | 70 UILabel* text = [[UILabel alloc] initWithFrame:CGRectZero]; |
| 69 base::WeakNSObject<ContextualSearchPromoView> weakSelf(self); | 71 __weak ContextualSearchPromoView* weakSelf = self; |
| 70 _linkController.reset([[LabelLinkController alloc] | 72 _linkController = [[LabelLinkController alloc] |
| 71 initWithLabel:text | 73 initWithLabel:text |
| 72 action:^(const GURL& gurl) { | 74 action:^(const GURL& gurl) { |
| 73 [[weakSelf delegate] promoViewSettingsTapped]; | 75 [[weakSelf delegate] promoViewSettingsTapped]; |
| 74 }]); | 76 }]; |
| 75 [_linkController setLinkColor:UIColorFromRGB(kLinkColorRGB)]; | 77 [_linkController setLinkColor:UIColorFromRGB(kLinkColorRGB)]; |
| 76 | 78 |
| 77 // Label is as wide as the content area of the view. | 79 // Label is as wide as the content area of the view. |
| 78 [constraints addObject:[text.widthAnchor | 80 [constraints addObject:[text.widthAnchor |
| 79 constraintEqualToAnchor:self.layoutMarginsGuide | 81 constraintEqualToAnchor:self.layoutMarginsGuide |
| 80 .widthAnchor]]; | 82 .widthAnchor]]; |
| 81 | 83 |
| 82 // Parse out link location from the label text. | 84 // Parse out link location from the label text. |
| 83 NSString* textString = | 85 NSString* textString = |
| 84 l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_SHORT_DESCRIPTION); | 86 l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_SHORT_DESCRIPTION); |
| 85 NSRange linkRange; | 87 NSRange linkRange; |
| 86 textString = ParseStringWithLink(textString, &linkRange); | 88 textString = ParseStringWithLink(textString, &linkRange); |
| 87 | 89 |
| 88 // Build style attributes for the label. | 90 // Build style attributes for the label. |
| 89 NSMutableParagraphStyle* paragraphStyle = | 91 NSMutableParagraphStyle* paragraphStyle = |
| 90 [[[NSMutableParagraphStyle alloc] init] autorelease]; | 92 [[NSMutableParagraphStyle alloc] init]; |
| 91 [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; | 93 [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; |
| 92 [paragraphStyle setLineHeightMultiple:kLineSpace]; | 94 [paragraphStyle setLineHeightMultiple:kLineSpace]; |
| 93 NSDictionary* attributes = @{ | 95 NSDictionary* attributes = @{ |
| 94 NSParagraphStyleAttributeName : paragraphStyle, | 96 NSParagraphStyleAttributeName : paragraphStyle, |
| 95 NSFontAttributeName : | 97 NSFontAttributeName : |
| 96 [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:kTextFontSize], | 98 [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:kTextFontSize], |
| 97 NSForegroundColorAttributeName : | 99 NSForegroundColorAttributeName : |
| 98 [UIColor colorWithWhite:kTextColorGrayShade alpha:1] | 100 [UIColor colorWithWhite:kTextColorGrayShade alpha:1] |
| 99 }; | 101 }; |
| 100 | 102 |
| 101 // Create and assign attributed text to label. | 103 // Create and assign attributed text to label. |
| 102 base::scoped_nsobject<NSMutableAttributedString> attributedText( | 104 NSMutableAttributedString* attributedText = |
| 103 [[NSMutableAttributedString alloc] initWithString:textString]); | 105 [[NSMutableAttributedString alloc] initWithString:textString]; |
| 104 [attributedText setAttributes:attributes | 106 [attributedText setAttributes:attributes |
| 105 range:NSMakeRange(0, textString.length)]; | 107 range:NSMakeRange(0, textString.length)]; |
| 106 text.attributedText = attributedText; | 108 text.attributedText = attributedText; |
| 107 [_linkController addLinkWithRange:linkRange | 109 [_linkController addLinkWithRange:linkRange |
| 108 url:GURL("contextualSearch://settings")]; | 110 url:GURL("contextualSearch://settings")]; |
| 109 text.numberOfLines = 0; | 111 text.numberOfLines = 0; |
| 110 | 112 |
| 111 UIFont* buttonFont = | 113 UIFont* buttonFont = |
| 112 [[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:kButtonFontSize]; | 114 [[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:kButtonFontSize]; |
| 113 | 115 |
| 114 // Create accept and decline buttons with dimensions defined by the | 116 // Create accept and decline buttons with dimensions defined by the |
| 115 // minimum height and width constants. | 117 // minimum height and width constants. |
| 116 MDCFlatButton* acceptButton = [[[MDCFlatButton alloc] init] autorelease]; | 118 MDCFlatButton* acceptButton = [[MDCFlatButton alloc] init]; |
| 117 acceptButton.hasOpaqueBackground = YES; | 119 acceptButton.hasOpaqueBackground = YES; |
| 118 acceptButton.inkColor = | 120 acceptButton.inkColor = |
| 119 [[[MDCPalette cr_bluePalette] tint300] colorWithAlphaComponent:0.5f]; | 121 [[[MDCPalette cr_bluePalette] tint300] colorWithAlphaComponent:0.5f]; |
| 120 [acceptButton setBackgroundColor:[[MDCPalette cr_bluePalette] tint500] | 122 [acceptButton setBackgroundColor:[[MDCPalette cr_bluePalette] tint500] |
| 121 forState:UIControlStateNormal]; | 123 forState:UIControlStateNormal]; |
| 122 [acceptButton setBackgroundColor:[UIColor colorWithWhite:0.6f alpha:1.0f] | 124 [acceptButton setBackgroundColor:[UIColor colorWithWhite:0.6f alpha:1.0f] |
| 123 forState:UIControlStateDisabled]; | 125 forState:UIControlStateDisabled]; |
| 124 [constraints addObjectsFromArray:@[ | 126 [constraints addObjectsFromArray:@[ |
| 125 [acceptButton.widthAnchor | 127 [acceptButton.widthAnchor |
| 126 constraintGreaterThanOrEqualToConstant:kButtonMinWidth], | 128 constraintGreaterThanOrEqualToConstant:kButtonMinWidth], |
| 127 [acceptButton.heightAnchor constraintEqualToConstant:kButtonHeight] | 129 [acceptButton.heightAnchor constraintEqualToConstant:kButtonHeight] |
| 128 ]]; | 130 ]]; |
| 129 [acceptButton | 131 [acceptButton |
| 130 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_GOT_IT_BUTTON) | 132 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_GOT_IT_BUTTON) |
| 131 forState:UIControlStateNormal]; | 133 forState:UIControlStateNormal]; |
| 132 acceptButton.customTitleColor = [UIColor whiteColor]; | 134 acceptButton.customTitleColor = [UIColor whiteColor]; |
| 133 [acceptButton addTarget:_delegate | 135 [acceptButton addTarget:_delegate |
| 134 action:@selector(promoViewAcceptTapped) | 136 action:@selector(promoViewAcceptTapped) |
| 135 forControlEvents:UIControlEventTouchUpInside]; | 137 forControlEvents:UIControlEventTouchUpInside]; |
| 136 [acceptButton.titleLabel setFont:buttonFont]; | 138 [acceptButton.titleLabel setFont:buttonFont]; |
| 137 | 139 |
| 138 UIColor* customTitleColor = [[MDCPalette cr_bluePalette] tint500]; | 140 UIColor* customTitleColor = [[MDCPalette cr_bluePalette] tint500]; |
| 139 MDCButton* declineButton = [[[MDCFlatButton alloc] init] autorelease]; | 141 MDCButton* declineButton = [[MDCFlatButton alloc] init]; |
| 140 [constraints addObjectsFromArray:@[ | 142 [constraints addObjectsFromArray:@[ |
| 141 [declineButton.widthAnchor | 143 [declineButton.widthAnchor |
| 142 constraintGreaterThanOrEqualToConstant:kButtonMinWidth], | 144 constraintGreaterThanOrEqualToConstant:kButtonMinWidth], |
| 143 [declineButton.heightAnchor constraintEqualToConstant:kButtonHeight] | 145 [declineButton.heightAnchor constraintEqualToConstant:kButtonHeight] |
| 144 ]]; | 146 ]]; |
| 145 [declineButton setTitleColor:customTitleColor forState:UIControlStateNormal]; | 147 [declineButton setTitleColor:customTitleColor forState:UIControlStateNormal]; |
| 146 [declineButton | 148 [declineButton |
| 147 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_PROMO_OPTOUT) | 149 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_PROMO_OPTOUT) |
| 148 forState:UIControlStateNormal]; | 150 forState:UIControlStateNormal]; |
| 149 [declineButton addTarget:_delegate | 151 [declineButton addTarget:_delegate |
| 150 action:@selector(promoViewDeclineTapped) | 152 action:@selector(promoViewDeclineTapped) |
| 151 forControlEvents:UIControlEventTouchUpInside]; | 153 forControlEvents:UIControlEventTouchUpInside]; |
| 152 [declineButton.titleLabel setFont:buttonFont]; | 154 [declineButton.titleLabel setFont:buttonFont]; |
| 153 | 155 |
| 154 // Create the divider (a simple colored view) with height defined by | 156 // Create the divider (a simple colored view) with height defined by |
| 155 // |kDividerHeight| and width spanning this view's width. | 157 // |kDividerHeight| and width spanning this view's width. |
| 156 UIView* divider = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; | 158 UIView* divider = [[UIView alloc] initWithFrame:CGRectZero]; |
| 157 divider.backgroundColor = [UIColor colorWithWhite:0.745 alpha:1.0]; | 159 divider.backgroundColor = [UIColor colorWithWhite:0.745 alpha:1.0]; |
| 158 [constraints addObjectsFromArray:@[ | 160 [constraints addObjectsFromArray:@[ |
| 159 [divider.widthAnchor constraintEqualToAnchor:self.widthAnchor], | 161 [divider.widthAnchor constraintEqualToAnchor:self.widthAnchor], |
| 160 [divider.heightAnchor constraintEqualToConstant:kDividerHeight], | 162 [divider.heightAnchor constraintEqualToConstant:kDividerHeight], |
| 161 ]]; | 163 ]]; |
| 162 | 164 |
| 163 self.translatesAutoresizingMaskIntoConstraints = NO; | 165 self.translatesAutoresizingMaskIntoConstraints = NO; |
| 164 text.translatesAutoresizingMaskIntoConstraints = NO; | 166 text.translatesAutoresizingMaskIntoConstraints = NO; |
| 165 acceptButton.translatesAutoresizingMaskIntoConstraints = NO; | 167 acceptButton.translatesAutoresizingMaskIntoConstraints = NO; |
| 166 declineButton.translatesAutoresizingMaskIntoConstraints = NO; | 168 declineButton.translatesAutoresizingMaskIntoConstraints = NO; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 193 constraintEqualToAnchor:declineButton.trailingAnchor | 195 constraintEqualToAnchor:declineButton.trailingAnchor |
| 194 constant:kButtonSeparator], | 196 constant:kButtonSeparator], |
| 195 [acceptButton.trailingAnchor | 197 [acceptButton.trailingAnchor |
| 196 constraintEqualToAnchor:self.layoutMarginsGuide.trailingAnchor], | 198 constraintEqualToAnchor:self.layoutMarginsGuide.trailingAnchor], |
| 197 // Divider is centered horizontally at the bottom of the view. | 199 // Divider is centered horizontally at the bottom of the view. |
| 198 [divider.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], | 200 [divider.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], |
| 199 [divider.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], | 201 [divider.centerXAnchor constraintEqualToAnchor:self.centerXAnchor], |
| 200 ]]; | 202 ]]; |
| 201 | 203 |
| 202 [NSLayoutConstraint activateConstraints:constraints]; | 204 [NSLayoutConstraint activateConstraints:constraints]; |
| 203 _constraints.reset([constraints retain]); | 205 _constraints = constraints; |
| 204 | 206 |
| 205 return self; | 207 return self; |
| 206 } | 208 } |
| 207 | 209 |
| 208 - (void)dealloc { | 210 - (void)dealloc { |
| 209 // Fix for crbug.com/591043 -- Some constraints applying to autoreleased | 211 // Fix for crbug.com/591043 -- Some constraints applying to autoreleased |
| 210 // views may remain active with pointers to the to-be-deallocated views | 212 // views may remain active with pointers to the to-be-deallocated views |
| 211 // after the views are no longer being displayed. This ensures that all | 213 // after the views are no longer being displayed. This ensures that all |
| 212 // constraints are disabled and will not be applied even if some subviews | 214 // constraints are disabled and will not be applied even if some subviews |
| 213 // are lingering. | 215 // are lingering. |
| 214 [NSLayoutConstraint deactivateConstraints:_constraints]; | 216 [NSLayoutConstraint deactivateConstraints:_constraints]; |
| 215 [super dealloc]; | |
| 216 } | 217 } |
| 217 | 218 |
| 218 - (void)setHidden:(BOOL)hidden { | 219 - (void)setHidden:(BOOL)hidden { |
| 219 if (!hidden && self.disabled) | 220 if (!hidden && self.disabled) |
| 220 return; | 221 return; |
| 221 [self setClosure:hidden ? 0.0 : 1.0]; | 222 [self setClosure:hidden ? 0.0 : 1.0]; |
| 222 [super setHidden:hidden]; | 223 [super setHidden:hidden]; |
| 223 } | 224 } |
| 224 | 225 |
| 225 - (void)setClosure:(CGFloat)closure { | 226 - (void)setClosure:(CGFloat)closure { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 250 self.hidden = NO; | 251 self.hidden = NO; |
| 251 } | 252 } |
| 252 } | 253 } |
| 253 | 254 |
| 254 - (void)panelWillPromote:(ContextualSearchPanelView*)panel { | 255 - (void)panelWillPromote:(ContextualSearchPanelView*)panel { |
| 255 _delegate = nil; | 256 _delegate = nil; |
| 256 [panel removeMotionObserver:self]; | 257 [panel removeMotionObserver:self]; |
| 257 } | 258 } |
| 258 | 259 |
| 259 @end | 260 @end |
| OLD | NEW |