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 |