OLD | NEW |
(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/bookmarks/bookmark_promo_cell.h" |
| 6 |
| 7 #import <QuartzCore/QuartzCore.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #import "base/mac/objc_property_releaser.h" |
| 11 #import "base/mac/scoped_nsobject.h" |
| 12 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
| 13 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" |
| 14 #import "ios/chrome/browser/ui/rtl_geometry.h" |
| 15 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 16 #include "ios/chrome/grit/ios_chromium_strings.h" |
| 17 #include "ios/chrome/grit/ios_strings.h" |
| 18 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" |
| 19 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF
ontLoader.h" |
| 20 #import "ui/base/l10n/l10n_util_mac.h" |
| 21 |
| 22 namespace { |
| 23 |
| 24 const CGFloat kPadding = 16; |
| 25 const CGFloat kButtonHeight = 36; |
| 26 const CGFloat kTitleSubtitleSpace = 8; |
| 27 const CGFloat kSubtitleButtonsSpace = 8; |
| 28 const CGFloat kButtonsSpace = 8; |
| 29 |
| 30 void SetTextWithLineHeight(UILabel* label, NSString* text, CGFloat lineHeight) { |
| 31 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( |
| 32 [[NSMutableParagraphStyle alloc] init]); |
| 33 [paragraphStyle setMinimumLineHeight:lineHeight]; |
| 34 [paragraphStyle setMaximumLineHeight:lineHeight]; |
| 35 NSDictionary* attributes = @{NSParagraphStyleAttributeName : paragraphStyle}; |
| 36 base::scoped_nsobject<NSAttributedString> attributedString( |
| 37 [[NSAttributedString alloc] initWithString:text attributes:attributes]); |
| 38 label.attributedText = attributedString; |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
| 43 // The view that contains the promo UI: the title, the subtitle, the dismiss and |
| 44 // the sign in buttons. It is common to all size classes, but can be embedded |
| 45 // differently within the BookmarkPromoCell. |
| 46 @interface BookmarkPromoView : UIView |
| 47 |
| 48 @property(nonatomic, assign) UILabel* titleLabel; |
| 49 @property(nonatomic, assign) UILabel* subtitleLabel; |
| 50 @property(nonatomic, assign) MDCFlatButton* signInButton; |
| 51 @property(nonatomic, assign) MDCFlatButton* dismissButton; |
| 52 |
| 53 @end |
| 54 |
| 55 @implementation BookmarkPromoView |
| 56 |
| 57 @synthesize titleLabel = _titleLabel; |
| 58 @synthesize subtitleLabel = _subtitleLabel; |
| 59 @synthesize signInButton = _signInButton; |
| 60 @synthesize dismissButton = _dismissButton; |
| 61 |
| 62 + (BOOL)requiresConstraintBasedLayout { |
| 63 return YES; |
| 64 } |
| 65 |
| 66 - (instancetype)initWithFrame:(CGRect)frame { |
| 67 self = [super initWithFrame:frame]; |
| 68 if (self) { |
| 69 self.backgroundColor = [UIColor whiteColor]; |
| 70 self.accessibilityIdentifier = @"promo_view"; |
| 71 |
| 72 // The title. |
| 73 _titleLabel = [[[UILabel alloc] init] autorelease]; |
| 74 _titleLabel.textColor = bookmark_utils_ios::darkTextColor(); |
| 75 _titleLabel.font = |
| 76 [[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:16]; |
| 77 _titleLabel.numberOfLines = 0; |
| 78 SetTextWithLineHeight(_titleLabel, |
| 79 l10n_util::GetNSString(IDS_IOS_BOOKMARK_PROMO_TITLE), |
| 80 20.f); |
| 81 _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; |
| 82 [self addSubview:_titleLabel]; |
| 83 |
| 84 // The subtitle. |
| 85 _subtitleLabel = [[[UILabel alloc] init] autorelease]; |
| 86 _subtitleLabel.textColor = bookmark_utils_ios::darkTextColor(); |
| 87 _subtitleLabel.font = |
| 88 [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:14]; |
| 89 _subtitleLabel.numberOfLines = 0; |
| 90 SetTextWithLineHeight( |
| 91 _subtitleLabel, l10n_util::GetNSString(IDS_IOS_BOOKMARK_PROMO_MESSAGE), |
| 92 20.f); |
| 93 _subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO; |
| 94 [self addSubview:_subtitleLabel]; |
| 95 |
| 96 // The sign-in button. |
| 97 _signInButton = [[[MDCFlatButton alloc] init] autorelease]; |
| 98 [_signInButton setBackgroundColor:[[MDCPalette cr_bluePalette] tint500] |
| 99 forState:UIControlStateNormal]; |
| 100 _signInButton.customTitleColor = [UIColor whiteColor]; |
| 101 _signInButton.inkColor = [UIColor colorWithWhite:1 alpha:0.2]; |
| 102 [_signInButton |
| 103 setTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_PROMO_SIGN_IN_BUTTON) |
| 104 forState:UIControlStateNormal]; |
| 105 _signInButton.accessibilityIdentifier = @"promo_sign_in_button"; |
| 106 _signInButton.translatesAutoresizingMaskIntoConstraints = NO; |
| 107 [self addSubview:_signInButton]; |
| 108 |
| 109 // The dismiss button. |
| 110 _dismissButton = [[[MDCFlatButton alloc] init] autorelease]; |
| 111 [_dismissButton |
| 112 setTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_PROMO_DISMISS_BUTTON) |
| 113 forState:UIControlStateNormal]; |
| 114 _dismissButton.customTitleColor = [[MDCPalette cr_bluePalette] tint500]; |
| 115 _dismissButton.accessibilityIdentifier = @"promo_no_thanks_button"; |
| 116 _dismissButton.translatesAutoresizingMaskIntoConstraints = NO; |
| 117 [self addSubview:_dismissButton]; |
| 118 } |
| 119 return self; |
| 120 } |
| 121 |
| 122 - (void)updateConstraints { |
| 123 if ([[self constraints] count] == 0) { |
| 124 NSDictionary* views = @{ |
| 125 @"title" : self.titleLabel, |
| 126 @"subtitle" : self.subtitleLabel, |
| 127 @"signIn" : self.signInButton, |
| 128 @"dismiss" : self.dismissButton, |
| 129 }; |
| 130 NSDictionary* metrics = @{ |
| 131 @"p" : @(kPadding), |
| 132 @"b" : @(kButtonHeight), |
| 133 @"s1" : @(kTitleSubtitleSpace), |
| 134 @"s2" : @(kSubtitleButtonsSpace), |
| 135 @"s3" : @(kButtonsSpace), |
| 136 }; |
| 137 // clang-format off |
| 138 NSArray* constraints = @[ |
| 139 @"V:|-(p)-[title]-(s1)-[subtitle]-(s2)-[signIn(==b)]-(p)-|", |
| 140 @"H:|-(p)-[title]-(>=p)-|", |
| 141 @"H:|-(p)-[subtitle]-(>=p)-|", |
| 142 @"H:|-(>=p)-[dismiss]-(s3)-[signIn]-(p)-|" |
| 143 ]; |
| 144 // clang-format on |
| 145 ApplyVisualConstraintsWithMetricsAndOptions( |
| 146 constraints, views, metrics, LayoutOptionForRTLSupport(), self); |
| 147 AddSameCenterYConstraint(self, self.signInButton, self.dismissButton); |
| 148 } |
| 149 [super updateConstraints]; |
| 150 } |
| 151 |
| 152 @end |
| 153 |
| 154 @interface BookmarkPromoCell () { |
| 155 base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkPromoCell; |
| 156 } |
| 157 @property(nonatomic, assign) BookmarkPromoView* promoView; |
| 158 @property(nonatomic, retain) NSArray* compactContentViewConstraints; |
| 159 @property(nonatomic, retain) NSArray* regularContentViewConstraints; |
| 160 @end |
| 161 |
| 162 @implementation BookmarkPromoCell |
| 163 |
| 164 @synthesize delegate = _delegate; |
| 165 @synthesize promoView = _promoView; |
| 166 @synthesize compactContentViewConstraints = _compactContentViewConstraints; |
| 167 @synthesize regularContentViewConstraints = _regularContentViewConstraints; |
| 168 |
| 169 + (NSString*)reuseIdentifier { |
| 170 return @"BookmarkPromoCell"; |
| 171 } |
| 172 |
| 173 + (BOOL)requiresConstraintBasedLayout { |
| 174 return YES; |
| 175 } |
| 176 |
| 177 - (instancetype)initWithFrame:(CGRect)frame { |
| 178 self = [super initWithFrame:frame]; |
| 179 if (self) { |
| 180 _propertyReleaser_BookmarkPromoCell.Init(self, [BookmarkPromoCell class]); |
| 181 self.contentView.translatesAutoresizingMaskIntoConstraints = NO; |
| 182 |
| 183 _promoView = [[[BookmarkPromoView alloc] initWithFrame:frame] autorelease]; |
| 184 [_promoView.signInButton addTarget:self |
| 185 action:@selector(signIn:) |
| 186 forControlEvents:UIControlEventTouchUpInside]; |
| 187 [_promoView.dismissButton addTarget:self |
| 188 action:@selector(dismiss:) |
| 189 forControlEvents:UIControlEventTouchUpInside]; |
| 190 _promoView.translatesAutoresizingMaskIntoConstraints = NO; |
| 191 [self.contentView addSubview:_promoView]; |
| 192 [self updatePromoView]; |
| 193 } |
| 194 return self; |
| 195 } |
| 196 |
| 197 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { |
| 198 [self updatePromoView]; |
| 199 } |
| 200 |
| 201 - (void)updateConstraints { |
| 202 if ([[self constraints] count] == 0) { |
| 203 NSArray* constraints = @[ @"H:|[contentView]|" ]; |
| 204 NSDictionary* views = @{ @"contentView" : self.contentView }; |
| 205 ApplyVisualConstraintsWithMetricsAndOptions( |
| 206 constraints, views, nil, LayoutOptionForRTLSupport(), self); |
| 207 } |
| 208 [super updateConstraints]; |
| 209 } |
| 210 |
| 211 - (void)prepareForReuse { |
| 212 [super prepareForReuse]; |
| 213 _delegate = nil; |
| 214 } |
| 215 |
| 216 #pragma mark - Private |
| 217 |
| 218 - (void)updatePromoView { |
| 219 if (IsCompact(self)) { |
| 220 self.promoView.layer.cornerRadius = 0; |
| 221 self.promoView.layer.borderWidth = 0; |
| 222 self.promoView.layer.borderColor = NULL; |
| 223 [self.contentView removeConstraints:self.regularContentViewConstraints]; |
| 224 [self.contentView addConstraints:self.compactContentViewConstraints]; |
| 225 } else { |
| 226 self.promoView.layer.cornerRadius = 3.0; |
| 227 self.promoView.layer.borderWidth = 0.5; |
| 228 self.promoView.layer.borderColor = UIColorFromRGB(0xCECECE).CGColor; |
| 229 [self.contentView removeConstraints:self.compactContentViewConstraints]; |
| 230 [self.contentView addConstraints:self.regularContentViewConstraints]; |
| 231 } |
| 232 } |
| 233 |
| 234 - (NSArray*)compactContentViewConstraints { |
| 235 if (!_compactContentViewConstraints) { |
| 236 NSMutableArray* array = [NSMutableArray array]; |
| 237 NSDictionary* views = @{ @"promoView" : self.promoView }; |
| 238 [array |
| 239 addObjectsFromArray:[NSLayoutConstraint |
| 240 constraintsWithVisualFormat:@"H:|[promoView]|" |
| 241 options:0 |
| 242 metrics:nil |
| 243 views:views]]; |
| 244 [array |
| 245 addObjectsFromArray:[NSLayoutConstraint |
| 246 constraintsWithVisualFormat:@"V:|[promoView]|" |
| 247 options:0 |
| 248 metrics:nil |
| 249 views:views]]; |
| 250 _compactContentViewConstraints = [array copy]; |
| 251 } |
| 252 return _compactContentViewConstraints; |
| 253 } |
| 254 |
| 255 - (NSArray*)regularContentViewConstraints { |
| 256 if (!_regularContentViewConstraints) { |
| 257 NSMutableArray* array = [NSMutableArray array]; |
| 258 NSDictionary* views = @{ @"promoView" : self.promoView }; |
| 259 [array addObjectsFromArray: |
| 260 [NSLayoutConstraint |
| 261 constraintsWithVisualFormat:@"H:|-(p)-[promoView]-(p)-|" |
| 262 options:0 |
| 263 metrics:@{ |
| 264 @"p" : @(kPadding) |
| 265 } |
| 266 views:views]]; |
| 267 [array addObjectsFromArray: |
| 268 [NSLayoutConstraint |
| 269 constraintsWithVisualFormat:@"V:|-(p)-[promoView]-(p)-|" |
| 270 options:0 |
| 271 metrics:@{ |
| 272 @"p" : @(kPadding / 2.0) |
| 273 } |
| 274 views:views]]; |
| 275 _regularContentViewConstraints = [array copy]; |
| 276 } |
| 277 return _regularContentViewConstraints; |
| 278 } |
| 279 |
| 280 #pragma mark - Private actions |
| 281 |
| 282 - (void)signIn:(id)sender { |
| 283 [self.delegate bookmarkPromoCellDidTapSignIn:self]; |
| 284 } |
| 285 |
| 286 - (void)dismiss:(id)sender { |
| 287 [self.delegate bookmarkPromoCellDidTapDismiss:self]; |
| 288 } |
| 289 |
| 290 @end |
OLD | NEW |