OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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/today_extension/physical_web_optin_footer.h" |
| 6 |
| 7 #import "base/mac/scoped_block.h" |
| 8 #import "base/mac/scoped_nsobject.h" |
| 9 #include "ios/chrome/today_extension/interactive_label.h" |
| 10 #include "ios/chrome/today_extension/lock_screen_state.h" |
| 11 #import "ios/chrome/today_extension/transparent_button.h" |
| 12 #import "ios/chrome/today_extension/ui_util.h" |
| 13 #include "ios/today_extension/grit/ios_today_extension_strings.h" |
| 14 #import "ui/base/l10n/l10n_util.h" |
| 15 |
| 16 namespace { |
| 17 |
| 18 // Vertical space between the title and the description. |
| 19 const CGFloat kTitleVerticalMargin = 3; |
| 20 // Font size of the button. |
| 21 const CGFloat kButtonFontSize = 13; |
| 22 // Left and right padding inside the button. |
| 23 const CGFloat kButtonPadding = 8; |
| 24 // Space between buttons. |
| 25 const CGFloat kButtonSpacing = 4; |
| 26 // Height of the buttons. |
| 27 const CGFloat kButtonHeight = 30; |
| 28 // Vertical space between the description and the buttons. |
| 29 const CGFloat kButtonVerticalMargin = 16; |
| 30 // Font size of the explanation. |
| 31 const CGFloat kDescriptionFontSize = 14; |
| 32 |
| 33 } // namespace |
| 34 |
| 35 @interface PhysicalWebOptInFooter () |
| 36 |
| 37 - (void)optInButtonPressed:(id)sender; |
| 38 - (void)dismissButtonPressed:(id)sender; |
| 39 |
| 40 @end |
| 41 |
| 42 @implementation PhysicalWebOptInFooter { |
| 43 // Container of the views of the opt-in dialog. |
| 44 base::scoped_nsobject<UIView> _mainView; |
| 45 // Title. |
| 46 base::scoped_nsobject<UILabel> _titleView; |
| 47 // Explanation. |
| 48 base::scoped_nsobject<InteractiveLabel> _descriptionLabel; |
| 49 // Confirm opt-in. |
| 50 base::scoped_nsobject<TransparentButton> _optInButton; |
| 51 // Refuse opt-in. |
| 52 base::scoped_nsobject<TransparentButton> _dismissButton; |
| 53 // Physical Web logo. |
| 54 base::scoped_nsobject<UIImageView> _imageView; |
| 55 // Outer horizontal padding. |
| 56 CGFloat _horizontalPadding; |
| 57 // Physical Web logo size. |
| 58 CGSize _imageSize; |
| 59 // Distance between the icon and the title. |
| 60 CGFloat _imageTextSeparator; |
| 61 // Opt-in action block. |
| 62 base::mac::ScopedBlock<EnableDisableBlock> _optinAction; |
| 63 // Dismiss action block. |
| 64 base::mac::ScopedBlock<EnableDisableBlock> _dismissAction; |
| 65 // Whether the screen is locked. |
| 66 BOOL _locked; |
| 67 } |
| 68 |
| 69 - (id)initWithLeftInset:(CGFloat)leftInset |
| 70 learnMoreBlock:(LearnMoreBlock)learnMoreBlock |
| 71 optinAction:(EnableDisableBlock)optinAction |
| 72 dismissAction:(EnableDisableBlock)dismissAction { |
| 73 self = [super init]; |
| 74 if (self) { |
| 75 _mainView.reset([[UIView alloc] initWithFrame:CGRectZero]); |
| 76 _locked = [[LockScreenState sharedInstance] isScreenLocked]; |
| 77 [_mainView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 78 |
| 79 [_mainView setUserInteractionEnabled:YES]; |
| 80 |
| 81 // Creates the layout of the opt-in UI. |
| 82 UIImage* iconImage = [UIImage imageNamed:@"todayview_physical_web"]; |
| 83 _imageSize = [iconImage size]; |
| 84 _imageView.reset([[UIImageView alloc] init]); |
| 85 [_imageView setImage:iconImage]; |
| 86 [_imageView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 87 |
| 88 _titleView.reset([[UILabel alloc] initWithFrame:CGRectZero]); |
| 89 [_titleView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 90 [_titleView setText:l10n_util::GetNSString( |
| 91 IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_OPTIN_TITLE)]; |
| 92 UIFont* titleFont = |
| 93 [UIFont fontWithName:@"Helvetica" size:ui_util::kTitleFontSize]; |
| 94 [_titleView setTextColor:ui_util::TitleColor()]; |
| 95 [_titleView setFont:titleFont]; |
| 96 [_titleView setTextAlignment:ui_util::IsRTL() ? NSTextAlignmentRight |
| 97 : NSTextAlignmentLeft]; |
| 98 [_titleView sizeToFit]; |
| 99 |
| 100 NSString* description; |
| 101 if (_locked) { |
| 102 description = l10n_util::GetNSString( |
| 103 IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_OPTIN_UNLOCK); |
| 104 } else { |
| 105 description = l10n_util::GetNSString( |
| 106 IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_OPTIN_DESCRIPTION); |
| 107 } |
| 108 _descriptionLabel.reset([[InteractiveLabel alloc] |
| 109 initWithFrame:CGRectZero |
| 110 labelString:description |
| 111 fontSize:kDescriptionFontSize |
| 112 labelAlignment:ui_util::IsRTL() ? NSTextAlignmentRight |
| 113 : NSTextAlignmentLeft |
| 114 insets:UIEdgeInsetsZero |
| 115 buttonString:nil |
| 116 linkBlock:learnMoreBlock |
| 117 buttonBlock:NULL]); |
| 118 [_descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 119 UIStackView* textStack = [[[UIStackView alloc] |
| 120 initWithArrangedSubviews:@[ _titleView, _descriptionLabel ]] |
| 121 autorelease]; |
| 122 |
| 123 [textStack setAxis:UILayoutConstraintAxisVertical]; |
| 124 [textStack setDistribution:UIStackViewDistributionEqualSpacing]; |
| 125 [textStack setSpacing:kTitleVerticalMargin]; |
| 126 [textStack setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 127 |
| 128 [_mainView addSubview:textStack]; |
| 129 [_mainView addSubview:_imageView]; |
| 130 |
| 131 _horizontalPadding = leftInset + ui_util::ChromeIconOffset(); |
| 132 _imageTextSeparator = |
| 133 ui_util::ChromeTextOffset() - ui_util::ChromeIconOffset(); |
| 134 |
| 135 [NSLayoutConstraint activateConstraints:@[ |
| 136 [[textStack topAnchor] constraintEqualToAnchor:[_imageView topAnchor]], |
| 137 [[textStack topAnchor] |
| 138 constraintEqualToAnchor:[_mainView topAnchor] |
| 139 constant:ui_util::kSecondLineVerticalPadding], |
| 140 [[textStack leadingAnchor] |
| 141 constraintEqualToAnchor:[_imageView leadingAnchor] |
| 142 constant:_imageTextSeparator], |
| 143 [[textStack trailingAnchor] |
| 144 constraintEqualToAnchor:[_mainView trailingAnchor] |
| 145 constant:-_horizontalPadding], |
| 146 [[_imageView widthAnchor] constraintEqualToConstant:_imageSize.width], |
| 147 [[_imageView heightAnchor] constraintEqualToConstant:_imageSize.height], |
| 148 [[_imageView leadingAnchor] |
| 149 constraintEqualToAnchor:[_mainView leadingAnchor] |
| 150 constant:_horizontalPadding] |
| 151 ]]; |
| 152 |
| 153 if (!_locked) { |
| 154 UIView* buttons = [self createButtonsOptinAction:optinAction |
| 155 dismissAction:dismissAction]; |
| 156 [_mainView addSubview:buttons]; |
| 157 [[buttons topAnchor] constraintEqualToAnchor:[textStack bottomAnchor] |
| 158 constant:kButtonVerticalMargin] |
| 159 .active = YES; |
| 160 [[buttons centerXAnchor] |
| 161 constraintEqualToAnchor:[_mainView centerXAnchor]] |
| 162 .active = YES; |
| 163 } |
| 164 } |
| 165 return self; |
| 166 } |
| 167 |
| 168 - (UIView*)createButtonsOptinAction:(EnableDisableBlock)optinAction |
| 169 dismissAction:(EnableDisableBlock)dismissAction { |
| 170 UIFont* buttonFont = [UIFont fontWithName:@"Helvetica" size:kButtonFontSize]; |
| 171 |
| 172 _dismissButton.reset([[TransparentButton alloc] initWithFrame:CGRectZero]); |
| 173 [_dismissButton setCornerRadius:ui_util::kUIButtonCornerRadius]; |
| 174 [[_dismissButton titleLabel] setFont:buttonFont]; |
| 175 [_dismissButton setInkColor:ui_util::InkColor()]; |
| 176 [_dismissButton setTitleColor:ui_util::TitleColor() |
| 177 forState:UIControlStateNormal]; |
| 178 [_dismissButton |
| 179 setTitle:l10n_util::GetNSString( |
| 180 IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_OPTIN_DISMISS) |
| 181 forState:UIControlStateNormal]; |
| 182 [_dismissButton setBorderWidth:1.0]; |
| 183 [_dismissButton setBorderColor:ui_util::TitleColor()]; |
| 184 [_dismissButton addTarget:self |
| 185 action:@selector(dismissButtonPressed:) |
| 186 forControlEvents:UIControlEventTouchUpInside]; |
| 187 _dismissAction.reset(dismissAction, base::scoped_policy::RETAIN); |
| 188 [_dismissButton setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 189 |
| 190 _optInButton.reset([[TransparentButton alloc] initWithFrame:CGRectZero]); |
| 191 [_optInButton setCornerRadius:ui_util::kUIButtonCornerRadius]; |
| 192 [[_optInButton titleLabel] setFont:buttonFont]; |
| 193 [_optInButton setInkColor:ui_util::InkColor()]; |
| 194 [_optInButton setBackgroundColor:ui_util::BackgroundColor()]; |
| 195 [_optInButton setTitleColor:[UIColor blackColor] |
| 196 forState:UIControlStateNormal]; |
| 197 [_optInButton setTitle:l10n_util::GetNSString( |
| 198 IDS_IOS_PYSICAL_WEB_TODAY_EXTENSION_OPTIN_ACCEPT) |
| 199 forState:UIControlStateNormal]; |
| 200 [_optInButton addTarget:self |
| 201 action:@selector(optInButtonPressed:) |
| 202 forControlEvents:UIControlEventTouchUpInside]; |
| 203 [_optInButton setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 204 |
| 205 [[_optInButton heightAnchor] constraintEqualToConstant:kButtonHeight]; |
| 206 [[_dismissButton heightAnchor] constraintEqualToConstant:kButtonHeight]; |
| 207 [[_optInButton widthAnchor] |
| 208 constraintEqualToAnchor:[_dismissButton widthAnchor]]; |
| 209 |
| 210 _optinAction.reset(optinAction, base::scoped_policy::RETAIN); |
| 211 UIStackView* buttonStack = [[UIStackView alloc] |
| 212 initWithArrangedSubviews:@[ _dismissButton, _optInButton ]]; |
| 213 [buttonStack setUserInteractionEnabled:YES]; |
| 214 [buttonStack setAxis:UILayoutConstraintAxisHorizontal]; |
| 215 [buttonStack setSpacing:kButtonSpacing]; |
| 216 [buttonStack setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 217 |
| 218 [[_optInButton heightAnchor] constraintEqualToConstant:kButtonHeight].active = |
| 219 YES; |
| 220 [[_dismissButton heightAnchor] constraintEqualToConstant:kButtonHeight] |
| 221 .active = YES; |
| 222 |
| 223 [_optInButton setContentEdgeInsets:UIEdgeInsetsMake(0, kButtonPadding, 0, |
| 224 kButtonPadding)]; |
| 225 [_dismissButton setContentEdgeInsets:UIEdgeInsetsMake(0, kButtonPadding, 0, |
| 226 kButtonPadding)]; |
| 227 |
| 228 [[_optInButton widthAnchor] |
| 229 constraintEqualToAnchor:[_dismissButton widthAnchor]] |
| 230 .active = YES; |
| 231 return [buttonStack autorelease]; |
| 232 } |
| 233 |
| 234 - (CGFloat)heightForWidth:(CGFloat)width { |
| 235 CGFloat height = ui_util::kSecondLineVerticalPadding + |
| 236 [_titleView frame].size.height + kTitleVerticalMargin + |
| 237 [_descriptionLabel |
| 238 sizeThatFits:CGSizeMake(width - (_horizontalPadding * 2 + |
| 239 _imageTextSeparator), |
| 240 CGFLOAT_MAX)] |
| 241 .height + |
| 242 ui_util::kSecondLineVerticalPadding; |
| 243 |
| 244 if (!_locked) { |
| 245 height += kButtonVerticalMargin + kButtonHeight; |
| 246 } |
| 247 return height; |
| 248 } |
| 249 |
| 250 - (UIView*)view { |
| 251 return _mainView; |
| 252 } |
| 253 |
| 254 - (void)optInButtonPressed:(id)sender { |
| 255 _optinAction.get()(); |
| 256 } |
| 257 |
| 258 - (void)dismissButtonPressed:(id)sender { |
| 259 _dismissAction.get()(); |
| 260 } |
| 261 |
| 262 @end |
OLD | NEW |