Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: ios/chrome/browser/ui/contextual_search/contextual_search_promo_view.mm

Issue 2588713002: Upstream Chrome on iOS source code [4/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_promo_view.h"
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"
10 #import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h"
11 #include "ios/chrome/browser/ui/uikit_ui_util.h"
12 #import "ios/chrome/browser/ui/util/label_link_controller.h"
13 #import "ios/chrome/common/material_timing.h"
14 #include "ios/chrome/common/string_util.h"
15 #include "ios/chrome/grit/ios_strings.h"
16 #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"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "url/gurl.h"
20
21 namespace {
22 const int kMargin = 16;
23 const int kSpaceBelowText = 32;
24 const int kButtonSeparator = 8;
25 const int kButtonHeight = 36;
26 const int kButtonMinWidth = 88;
27 const int kDividerHeight = 1;
28
29 const int kTextFontSize = 16;
30 const int kButtonFontSize = 14;
31 const CGFloat kTextColorGrayShade = 0.494;
32 const int kLinkColorRGB = 0x5D9AFF;
33
34 const CGFloat kLineSpace = 1.15;
35
36 // Animation timings.
37 const CGFloat kCloseDuration = ios::material::kDuration1;
38 }
39
40 @interface ContextualSearchPromoView ()
41 @property(nonatomic, assign) id<ContextualSearchPromoViewDelegate> delegate;
42 @end
43
44 @implementation ContextualSearchPromoView {
45 base::scoped_nsobject<LabelLinkController> _linkController;
46 base::scoped_nsobject<NSMutableArray> _constraints;
47 }
48
49 @synthesize disabled = _disabled;
50 @synthesize delegate = _delegate;
51
52 + (BOOL)requiresConstraintBasedLayout {
53 return YES;
54 }
55
56 - (instancetype)initWithFrame:(CGRect)frame
57 delegate:(id<ContextualSearchPromoViewDelegate>)delegate {
58 if (!(self = [super initWithFrame:frame]))
59 return nil;
60
61 self.delegate = delegate;
62 self.backgroundColor = [UIColor colorWithWhite:0.93 alpha:1.0];
63
64 // Temp array to accumulate constraints as views are created.
65 NSMutableArray* constraints = [NSMutableArray array];
66
67 // Initialize text label and its link controller.
68 UILabel* text = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
69 base::WeakNSObject<ContextualSearchPromoView> weakSelf(self);
70 _linkController.reset([[LabelLinkController alloc]
71 initWithLabel:text
72 action:^(const GURL& gurl) {
73 [[weakSelf delegate] promoViewSettingsTapped];
74 }]);
75 [_linkController setLinkColor:UIColorFromRGB(kLinkColorRGB)];
76
77 // Label is as wide as the content area of the view.
78 [constraints addObject:[text.widthAnchor
79 constraintEqualToAnchor:self.layoutMarginsGuide
80 .widthAnchor]];
81
82 // Parse out link location from the label text.
83 NSString* textString =
84 l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_SHORT_DESCRIPTION);
85 NSRange linkRange;
86 textString = ParseStringWithLink(textString, &linkRange);
87
88 // Build style attributes for the label.
89 NSMutableParagraphStyle* paragraphStyle =
90 [[[NSMutableParagraphStyle alloc] init] autorelease];
91 [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
92 [paragraphStyle setLineHeightMultiple:kLineSpace];
93 NSDictionary* attributes = @{
94 NSParagraphStyleAttributeName : paragraphStyle,
95 NSFontAttributeName :
96 [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:kTextFontSize],
97 NSForegroundColorAttributeName :
98 [UIColor colorWithWhite:kTextColorGrayShade alpha:1]
99 };
100
101 // Create and assign attributed text to label.
102 base::scoped_nsobject<NSMutableAttributedString> attributedText(
103 [[NSMutableAttributedString alloc] initWithString:textString]);
104 [attributedText setAttributes:attributes
105 range:NSMakeRange(0, textString.length)];
106 text.attributedText = attributedText;
107 [_linkController addLinkWithRange:linkRange
108 url:GURL("contextualSearch://settings")];
109 text.numberOfLines = 0;
110
111 UIFont* buttonFont =
112 [[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:kButtonFontSize];
113
114 // Create accept and decline buttons with dimensions defined by the
115 // minimum height and width constants.
116 MDCFlatButton* acceptButton = [[[MDCFlatButton alloc] init] autorelease];
117 acceptButton.hasOpaqueBackground = YES;
118 acceptButton.inkColor =
119 [[[MDCPalette cr_bluePalette] tint300] colorWithAlphaComponent:0.5f];
120 [acceptButton setBackgroundColor:[[MDCPalette cr_bluePalette] tint500]
121 forState:UIControlStateNormal];
122 [acceptButton setBackgroundColor:[UIColor colorWithWhite:0.6f alpha:1.0f]
123 forState:UIControlStateDisabled];
124 [constraints addObjectsFromArray:@[
125 [acceptButton.widthAnchor
126 constraintGreaterThanOrEqualToConstant:kButtonMinWidth],
127 [acceptButton.heightAnchor constraintEqualToConstant:kButtonHeight]
128 ]];
129 [acceptButton
130 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_GOT_IT_BUTTON)
131 forState:UIControlStateNormal];
132 acceptButton.customTitleColor = [UIColor whiteColor];
133 [acceptButton addTarget:_delegate
134 action:@selector(promoViewAcceptTapped)
135 forControlEvents:UIControlEventTouchUpInside];
136 [acceptButton.titleLabel setFont:buttonFont];
137
138 UIColor* customTitleColor = [[MDCPalette cr_bluePalette] tint500];
139 MDCButton* declineButton = [[[MDCFlatButton alloc] init] autorelease];
140 [constraints addObjectsFromArray:@[
141 [declineButton.widthAnchor
142 constraintGreaterThanOrEqualToConstant:kButtonMinWidth],
143 [declineButton.heightAnchor constraintEqualToConstant:kButtonHeight]
144 ]];
145 [declineButton setTitleColor:customTitleColor forState:UIControlStateNormal];
146 [declineButton
147 setTitle:l10n_util::GetNSString(IDS_IOS_CONTEXTUAL_SEARCH_PROMO_OPTOUT)
148 forState:UIControlStateNormal];
149 [declineButton addTarget:_delegate
150 action:@selector(promoViewDeclineTapped)
151 forControlEvents:UIControlEventTouchUpInside];
152 [declineButton.titleLabel setFont:buttonFont];
153
154 // Create the divider (a simple colored view) with height defined by
155 // |kDividerHeight| and width spanning this view's width.
156 UIView* divider = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
157 divider.backgroundColor = [UIColor colorWithWhite:0.745 alpha:1.0];
158 [constraints addObjectsFromArray:@[
159 [divider.widthAnchor constraintEqualToAnchor:self.widthAnchor],
160 [divider.heightAnchor constraintEqualToConstant:kDividerHeight],
161 ]];
162
163 self.translatesAutoresizingMaskIntoConstraints = NO;
164 text.translatesAutoresizingMaskIntoConstraints = NO;
165 acceptButton.translatesAutoresizingMaskIntoConstraints = NO;
166 declineButton.translatesAutoresizingMaskIntoConstraints = NO;
167 divider.translatesAutoresizingMaskIntoConstraints = NO;
168
169 [self addSubview:text];
170 [self addSubview:acceptButton];
171 [self addSubview:declineButton];
172 [self addSubview:divider];
173
174 self.layoutMargins = UIEdgeInsetsMake(kMargin, kMargin, kMargin, kMargin);
175
176 // Position all of the subviews
177 [constraints addObjectsFromArray:@[
178 // Text is at the top of the content area, centered horizontally.
179 [text.topAnchor constraintEqualToAnchor:self.layoutMarginsGuide.topAnchor],
180 [text.centerXAnchor
181 constraintEqualToAnchor:self.layoutMarginsGuide.centerXAnchor],
182 // Accept button is |kSpaceBelowText| below the text, and at the bottom of
183 // the content area.
184 [acceptButton.topAnchor constraintEqualToAnchor:text.bottomAnchor
185 constant:kSpaceBelowText],
186 [acceptButton.bottomAnchor
187 constraintEqualToAnchor:self.layoutMarginsGuide.bottomAnchor],
188 // Decline button's top is aligned with the accept button's
189 [declineButton.topAnchor constraintEqualToAnchor:acceptButton.topAnchor],
190 // Decline button is to the leading side of the accept button, which
191 // abuts the trailing edge of the content area.
192 [acceptButton.leadingAnchor
193 constraintEqualToAnchor:declineButton.trailingAnchor
194 constant:kButtonSeparator],
195 [acceptButton.trailingAnchor
196 constraintEqualToAnchor:self.layoutMarginsGuide.trailingAnchor],
197 // Divider is centered horizontally at the bottom of the view.
198 [divider.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
199 [divider.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
200 ]];
201
202 [NSLayoutConstraint activateConstraints:constraints];
203 _constraints.reset([constraints retain]);
204
205 return self;
206 }
207
208 - (void)dealloc {
209 // Fix for crbug.com/591043 -- Some constraints applying to autoreleased
210 // 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
212 // constraints are disabled and will not be applied even if some subviews
213 // are lingering.
214 [NSLayoutConstraint deactivateConstraints:_constraints];
215 [super dealloc];
216 }
217
218 - (void)setHidden:(BOOL)hidden {
219 if (!hidden && self.disabled)
220 return;
221 [self setClosure:hidden ? 0.0 : 1.0];
222 [super setHidden:hidden];
223 }
224
225 - (void)setClosure:(CGFloat)closure {
226 self.transform = CGAffineTransformMakeScale(1.0, closure);
227 }
228
229 - (void)closeAnimated:(BOOL)animated {
230 [UIView cr_animateWithDuration:animated ? kCloseDuration : 0
231 delay:0
232 curve:ios::material::CurveEaseOut
233 options:UIViewAnimationOptionBeginFromCurrentState
234 animations:^{
235 self.hidden = YES;
236 }
237 completion:nil];
238 }
239
240 #pragma mark - ContextualSearchPanelMotionObserver
241
242 - (void)panel:(ContextualSearchPanelView*)panel
243 didChangeToState:(ContextualSearch::PanelState)toState
244 fromState:(ContextualSearch::PanelState)fromState {
245 if (self.disabled)
246 return;
247 if (toState == ContextualSearch::COVERING) {
248 [self closeAnimated:YES];
249 } else if (fromState == ContextualSearch::COVERING) {
250 self.hidden = NO;
251 }
252 }
253
254 - (void)panelWillPromote:(ContextualSearchPanelView*)panel {
255 _delegate = nil;
256 [panel removeMotionObserver:self];
257 }
258
259 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698