OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/infobars/infobar_view.h" | 5 #import "ios/chrome/browser/ui/infobars/infobar_view.h" |
6 | 6 |
7 #import <CoreGraphics/CoreGraphics.h> | 7 #import <CoreGraphics/CoreGraphics.h> |
8 #import <QuartzCore/QuartzCore.h> | 8 #import <QuartzCore/QuartzCore.h> |
9 | 9 |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
11 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
12 #include "base/ios/weak_nsobject.h" | |
13 #include "base/logging.h" | 12 #include "base/logging.h" |
14 #include "base/mac/foundation_util.h" | 13 #include "base/mac/foundation_util.h" |
15 #include "base/strings/sys_string_conversions.h" | 14 #include "base/strings/sys_string_conversions.h" |
16 #include "components/strings/grit/components_strings.h" | 15 #include "components/strings/grit/components_strings.h" |
17 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" | 16 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" |
18 #import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h" | 17 #import "ios/chrome/browser/ui/infobars/infobar_view_delegate.h" |
19 #include "ios/chrome/browser/ui/ui_util.h" | 18 #include "ios/chrome/browser/ui/ui_util.h" |
20 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 19 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
21 #import "ios/chrome/browser/ui/util/label_link_controller.h" | 20 #import "ios/chrome/browser/ui/util/label_link_controller.h" |
22 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" | 21 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate
rialButtons.h" |
23 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 22 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
24 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
25 #import "ui/gfx/ios/NSString+CrStringDrawing.h" | 24 #import "ui/gfx/ios/NSString+CrStringDrawing.h" |
26 #import "ui/gfx/ios/uikit_util.h" | 25 #import "ui/gfx/ios/uikit_util.h" |
27 #include "url/gurl.h" | 26 #include "url/gurl.h" |
28 | 27 |
| 28 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 29 #error "This file requires ARC support." |
| 30 #endif |
| 31 |
29 namespace { | 32 namespace { |
30 | 33 |
31 const char kChromeInfobarURL[] = "chromeinternal://infobar/"; | 34 const char kChromeInfobarURL[] = "chromeinternal://infobar/"; |
32 | 35 |
33 // UX configuration constants for the shadow/rounded corners on the icon. | 36 // UX configuration constants for the shadow/rounded corners on the icon. |
34 const CGFloat kBaseSizeForEffects = 57.0; | 37 const CGFloat kBaseSizeForEffects = 57.0; |
35 const CGFloat kCornerRadius = 10.0; | 38 const CGFloat kCornerRadius = 10.0; |
36 const CGFloat kShadowVerticalOffset = 1.0; | 39 const CGFloat kShadowVerticalOffset = 1.0; |
37 const CGFloat kShadowOpacity = 0.5; | 40 const CGFloat kShadowOpacity = 0.5; |
38 const CGFloat kShadowRadius = 0.8; | 41 const CGFloat kShadowRadius = 0.8; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 // If |layout| is yes, it sets the frame of the label and the switch to fit | 78 // If |layout| is yes, it sets the frame of the label and the switch to fit |
76 // |width|. | 79 // |width|. |
77 - (CGFloat)heightRequiredForSwitchWithWidth:(CGFloat)width layout:(BOOL)layout; | 80 - (CGFloat)heightRequiredForSwitchWithWidth:(CGFloat)width layout:(BOOL)layout; |
78 | 81 |
79 // Returns the preferred width. A smaller width requires eliding the text. | 82 // Returns the preferred width. A smaller width requires eliding the text. |
80 - (CGFloat)preferredWidth; | 83 - (CGFloat)preferredWidth; |
81 | 84 |
82 @end | 85 @end |
83 | 86 |
84 @implementation SwitchView { | 87 @implementation SwitchView { |
85 base::scoped_nsobject<UILabel> label_; | 88 UILabel* label_; |
86 base::scoped_nsobject<UISwitch> switch_; | 89 UISwitch* switch_; |
87 CGFloat preferredTotalWidth_; | 90 CGFloat preferredTotalWidth_; |
88 CGFloat preferredLabelWidth_; | 91 CGFloat preferredLabelWidth_; |
89 } | 92 } |
90 | 93 |
91 - (id)initWithLabel:(NSString*)labelText isOn:(BOOL)isOn { | 94 - (id)initWithLabel:(NSString*)labelText isOn:(BOOL)isOn { |
92 // Creates switch and label. | 95 // Creates switch and label. |
93 base::scoped_nsobject<UILabel> tempLabel( | 96 UILabel* tempLabel = [[UILabel alloc] initWithFrame:CGRectZero]; |
94 [[UILabel alloc] initWithFrame:CGRectZero]); | |
95 [tempLabel setTextAlignment:NSTextAlignmentNatural]; | 97 [tempLabel setTextAlignment:NSTextAlignmentNatural]; |
96 [tempLabel setFont:[MDCTypography body1Font]]; | 98 [tempLabel setFont:[MDCTypography body1Font]]; |
97 [tempLabel setText:labelText]; | 99 [tempLabel setText:labelText]; |
98 [tempLabel setBackgroundColor:[UIColor clearColor]]; | 100 [tempLabel setBackgroundColor:[UIColor clearColor]]; |
99 [tempLabel setLineBreakMode:NSLineBreakByWordWrapping]; | 101 [tempLabel setLineBreakMode:NSLineBreakByWordWrapping]; |
100 [tempLabel setNumberOfLines:0]; | 102 [tempLabel setNumberOfLines:0]; |
101 [tempLabel setAdjustsFontSizeToFitWidth:NO]; | 103 [tempLabel setAdjustsFontSizeToFitWidth:NO]; |
102 base::scoped_nsobject<UISwitch> tempSwitch( | 104 UISwitch* tempSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; |
103 [[UISwitch alloc] initWithFrame:CGRectZero]); | |
104 [tempSwitch setExclusiveTouch:YES]; | 105 [tempSwitch setExclusiveTouch:YES]; |
105 [tempSwitch setAccessibilityLabel:labelText]; | 106 [tempSwitch setAccessibilityLabel:labelText]; |
106 [tempSwitch setOnTintColor:[[MDCPalette cr_bluePalette] tint500]]; | 107 [tempSwitch setOnTintColor:[[MDCPalette cr_bluePalette] tint500]]; |
107 [tempSwitch setOn:isOn]; | 108 [tempSwitch setOn:isOn]; |
108 | 109 |
109 // Computes the size and initializes the view. | 110 // Computes the size and initializes the view. |
110 CGSize maxSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); | 111 CGSize maxSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); |
111 CGSize labelSize = | 112 CGSize labelSize = |
112 [[tempLabel text] cr_boundingSizeWithSize:maxSize font:[tempLabel font]]; | 113 [[tempLabel text] cr_boundingSizeWithSize:maxSize font:[tempLabel font]]; |
113 CGSize switchSize = [tempSwitch frame].size; | 114 CGSize switchSize = [tempSwitch frame].size; |
114 CGRect frameRect = CGRectMake( | 115 CGRect frameRect = CGRectMake( |
115 0, 0, labelSize.width + kSpaceBetweenWidgets + switchSize.width, | 116 0, 0, labelSize.width + kSpaceBetweenWidgets + switchSize.width, |
116 std::max(labelSize.height, switchSize.height)); | 117 std::max(labelSize.height, switchSize.height)); |
117 self = [super initWithFrame:frameRect]; | 118 self = [super initWithFrame:frameRect]; |
118 if (!self) | 119 if (!self) |
119 return nil; | 120 return nil; |
120 label_.reset([tempLabel retain]); | 121 label_ = tempLabel; |
121 switch_.reset([tempSwitch retain]); | 122 switch_ = tempSwitch; |
122 | 123 |
123 // Sets the position of the label and the switch. The label is left aligned | 124 // Sets the position of the label and the switch. The label is left aligned |
124 // and the switch is right aligned. Both are vertically centered. | 125 // and the switch is right aligned. Both are vertically centered. |
125 CGRect labelFrame = | 126 CGRect labelFrame = |
126 CGRectMake(0, (self.frame.size.height - labelSize.height) / 2, | 127 CGRectMake(0, (self.frame.size.height - labelSize.height) / 2, |
127 labelSize.width, labelSize.height); | 128 labelSize.width, labelSize.height); |
128 CGRect switchFrame = | 129 CGRect switchFrame = |
129 CGRectMake(self.frame.size.width - switchSize.width, | 130 CGRectMake(self.frame.size.width - switchSize.width, |
130 (self.frame.size.height - switchSize.height) / 2, | 131 (self.frame.size.height - switchSize.height) / 2, |
131 switchSize.width, switchSize.height); | 132 switchSize.width, switchSize.height); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 | 217 |
217 // Returns the marker delimiting the start of a link. | 218 // Returns the marker delimiting the start of a link. |
218 + (NSString*)openingMarkerForLink; | 219 + (NSString*)openingMarkerForLink; |
219 // Returns the marker delimiting the end of a link. | 220 // Returns the marker delimiting the end of a link. |
220 + (NSString*)closingMarkerForLink; | 221 + (NSString*)closingMarkerForLink; |
221 | 222 |
222 @end | 223 @end |
223 | 224 |
224 @implementation InfoBarView { | 225 @implementation InfoBarView { |
225 // Delegates UIView events. | 226 // Delegates UIView events. |
226 InfoBarViewDelegate* delegate_; // weak | 227 InfoBarViewDelegate* delegate_; // weak. |
227 // The current height of this infobar (used for animations where part of the | 228 // The current height of this infobar (used for animations where part of the |
228 // infobar is hidden). | 229 // infobar is hidden). |
229 CGFloat visibleHeight_; | 230 CGFloat visibleHeight_; |
230 // The height of this infobar when fully visible. | 231 // The height of this infobar when fully visible. |
231 CGFloat targetHeight_; | 232 CGFloat targetHeight_; |
232 // View containing |imageView_|. Exists to apply drop shadows to the view. | 233 // View containing |imageView_|. Exists to apply drop shadows to the view. |
233 base::scoped_nsobject<UIView> imageViewContainer_; | 234 UIView* imageViewContainer_; |
234 // View containing the icon. | 235 // View containing the icon. |
235 base::scoped_nsobject<UIImageView> imageView_; | 236 UIImageView* imageView_; |
236 // Close button. | 237 // Close button. |
237 base::scoped_nsobject<UIButton> closeButton_; | 238 UIButton* closeButton_; |
238 // View containing the switch and its label. | 239 // View containing the switch and its label. |
239 base::scoped_nsobject<SwitchView> switchView_; | 240 SwitchView* switchView_; |
240 // We are using a LabelLinkController with an UILabel to be able to have | 241 // We are using a LabelLinkController with an UILabel to be able to have |
241 // parts of the label underlined and clickable. This label_ may be nil if | 242 // parts of the label underlined and clickable. This label_ may be nil if |
242 // the delegate returns an empty string for GetMessageText(). | 243 // the delegate returns an empty string for GetMessageText(). |
243 base::scoped_nsobject<LabelLinkController> labelLinkController_; | 244 LabelLinkController* labelLinkController_; |
244 UILabel* label_; // Weak. | 245 UILabel* label_; |
245 // Array of range information. The first element of the pair is the tag of | 246 // Array of range information. The first element of the pair is the tag of |
246 // the action and the second element is the range defining the link. | 247 // the action and the second element is the range defining the link. |
247 std::vector<std::pair<NSUInteger, NSRange>> linkRanges_; | 248 std::vector<std::pair<NSUInteger, NSRange>> linkRanges_; |
248 // Text for the label with link markers included. | 249 // Text for the label with link markers included. |
249 base::scoped_nsobject<NSString> markedLabel_; | 250 NSString* markedLabel_; |
250 // Buttons. | 251 // Buttons. |
251 // button1_ is tagged with ConfirmInfoBarDelegate::BUTTON_OK . | 252 // button1_ is tagged with ConfirmInfoBarDelegate::BUTTON_OK . |
252 // button2_ is tagged with ConfirmInfoBarDelegate::BUTTON_CANCEL . | 253 // button2_ is tagged with ConfirmInfoBarDelegate::BUTTON_CANCEL . |
253 base::scoped_nsobject<UIButton> button1_; | 254 UIButton* button1_; |
254 base::scoped_nsobject<UIButton> button2_; | 255 UIButton* button2_; |
255 // Drop shadow. | 256 // Drop shadow. |
256 base::scoped_nsobject<UIImageView> shadow_; | 257 UIImageView* shadow_; |
257 } | 258 } |
258 | 259 |
259 @synthesize visibleHeight = visibleHeight_; | 260 @synthesize visibleHeight = visibleHeight_; |
260 | 261 |
261 - (instancetype)initWithFrame:(CGRect)frame | 262 - (instancetype)initWithFrame:(CGRect)frame |
262 delegate:(InfoBarViewDelegate*)delegate { | 263 delegate:(InfoBarViewDelegate*)delegate { |
263 self = [super initWithFrame:frame]; | 264 self = [super initWithFrame:frame]; |
264 if (self) { | 265 if (self) { |
265 delegate_ = delegate; | 266 delegate_ = delegate; |
266 // Make the drop shadow. | 267 // Make the drop shadow. |
267 UIImage* shadowImage = [UIImage imageNamed:@"infobar_shadow"]; | 268 UIImage* shadowImage = [UIImage imageNamed:@"infobar_shadow"]; |
268 shadow_.reset([[UIImageView alloc] initWithImage:shadowImage]); | 269 shadow_ = [[UIImageView alloc] initWithImage:shadowImage]; |
269 [self addSubview:shadow_]; | 270 [self addSubview:shadow_]; |
270 [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | | 271 [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | |
271 UIViewAutoresizingFlexibleHeight]; | 272 UIViewAutoresizingFlexibleHeight]; |
272 [self setAccessibilityViewIsModal:YES]; | 273 [self setAccessibilityViewIsModal:YES]; |
273 } | 274 } |
274 return self; | 275 return self; |
275 } | 276 } |
276 | 277 |
277 - (void)dealloc { | |
278 [super dealloc]; | |
279 } | |
280 | 278 |
281 - (NSString*)markedLabel { | 279 - (NSString*)markedLabel { |
282 return markedLabel_; | 280 return markedLabel_; |
283 } | 281 } |
284 | 282 |
285 - (void)resetDelegate { | 283 - (void)resetDelegate { |
286 delegate_ = NULL; | 284 delegate_ = NULL; |
287 } | 285 } |
288 | 286 |
289 // Returns the width reserved for the icon. | 287 // Returns the width reserved for the icon. |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 } | 654 } |
657 | 655 |
658 - (void)addCloseButtonWithTag:(NSInteger)tag | 656 - (void)addCloseButtonWithTag:(NSInteger)tag |
659 target:(id)target | 657 target:(id)target |
660 action:(SEL)action { | 658 action:(SEL)action { |
661 DCHECK(!closeButton_); | 659 DCHECK(!closeButton_); |
662 // TODO(crbug/228611): Add IDR_ constant and use GetNativeImageNamed(). | 660 // TODO(crbug/228611): Add IDR_ constant and use GetNativeImageNamed(). |
663 NSString* imagePath = | 661 NSString* imagePath = |
664 [[NSBundle mainBundle] pathForResource:@"infobar_close" ofType:@"png"]; | 662 [[NSBundle mainBundle] pathForResource:@"infobar_close" ofType:@"png"]; |
665 UIImage* image = [UIImage imageWithContentsOfFile:imagePath]; | 663 UIImage* image = [UIImage imageWithContentsOfFile:imagePath]; |
666 closeButton_.reset([[UIButton buttonWithType:UIButtonTypeCustom] retain]); | 664 closeButton_ = [UIButton buttonWithType:UIButtonTypeCustom]; |
667 [closeButton_ setExclusiveTouch:YES]; | 665 [closeButton_ setExclusiveTouch:YES]; |
668 [closeButton_ setImage:image forState:UIControlStateNormal]; | 666 [closeButton_ setImage:image forState:UIControlStateNormal]; |
669 [closeButton_ addTarget:target | 667 [closeButton_ addTarget:target |
670 action:action | 668 action:action |
671 forControlEvents:UIControlEventTouchUpInside]; | 669 forControlEvents:UIControlEventTouchUpInside]; |
672 [closeButton_ setTag:tag]; | 670 [closeButton_ setTag:tag]; |
673 [closeButton_ setAccessibilityLabel:l10n_util::GetNSString(IDS_CLOSE)]; | 671 [closeButton_ setAccessibilityLabel:l10n_util::GetNSString(IDS_CLOSE)]; |
674 [self addSubview:closeButton_]; | 672 [self addSubview:closeButton_]; |
675 } | 673 } |
676 | 674 |
677 - (void)addSwitchWithLabel:(NSString*)label | 675 - (void)addSwitchWithLabel:(NSString*)label |
678 isOn:(BOOL)isOn | 676 isOn:(BOOL)isOn |
679 tag:(NSInteger)tag | 677 tag:(NSInteger)tag |
680 target:(id)target | 678 target:(id)target |
681 action:(SEL)action { | 679 action:(SEL)action { |
682 switchView_.reset([[SwitchView alloc] initWithLabel:label isOn:isOn]); | 680 switchView_ = [[SwitchView alloc] initWithLabel:label isOn:isOn]; |
683 [switchView_ setTag:tag target:target action:action]; | 681 [switchView_ setTag:tag target:target action:action]; |
684 [self addSubview:switchView_]; | 682 [self addSubview:switchView_]; |
685 } | 683 } |
686 | 684 |
687 - (void)addLeftIcon:(UIImage*)image { | 685 - (void)addLeftIcon:(UIImage*)image { |
688 if (!imageViewContainer_) { | 686 if (!imageViewContainer_) { |
689 imageViewContainer_.reset([[UIView alloc] init]); | 687 imageViewContainer_ = [[UIView alloc] init]; |
690 [self addSubview:imageViewContainer_]; | 688 [self addSubview:imageViewContainer_]; |
691 } | 689 } |
692 imageView_.reset([[UIImageView alloc] initWithImage:image]); | 690 imageView_ = [[UIImageView alloc] initWithImage:image]; |
693 [imageViewContainer_ addSubview:imageView_]; | 691 [imageViewContainer_ addSubview:imageView_]; |
694 } | 692 } |
695 | 693 |
696 - (void)addPlaceholderTransparentIcon:(CGSize const&)imageSize { | 694 - (void)addPlaceholderTransparentIcon:(CGSize const&)imageSize { |
697 UIGraphicsBeginImageContext(imageSize); | 695 UIGraphicsBeginImageContext(imageSize); |
698 UIImage* placeholder = UIGraphicsGetImageFromCurrentImageContext(); | 696 UIImage* placeholder = UIGraphicsGetImageFromCurrentImageContext(); |
699 UIGraphicsEndImageContext(); | 697 UIGraphicsEndImageContext(); |
700 [self addLeftIcon:placeholder]; | 698 [self addLeftIcon:placeholder]; |
701 } | 699 } |
702 | 700 |
(...skipping 16 matching lines...) Expand all Loading... |
719 } | 717 } |
720 | 718 |
721 - (NSString*)stripMarkersFromString:(NSString*)string { | 719 - (NSString*)stripMarkersFromString:(NSString*)string { |
722 linkRanges_.clear(); | 720 linkRanges_.clear(); |
723 for (;;) { | 721 for (;;) { |
724 // Find the opening marker, followed by the tag between parentheses. | 722 // Find the opening marker, followed by the tag between parentheses. |
725 NSRange startingRange = | 723 NSRange startingRange = |
726 [string rangeOfString:[[InfoBarView openingMarkerForLink] | 724 [string rangeOfString:[[InfoBarView openingMarkerForLink] |
727 stringByAppendingString:@"("]]; | 725 stringByAppendingString:@"("]]; |
728 if (!startingRange.length) | 726 if (!startingRange.length) |
729 return [[string copy] autorelease]; | 727 return [string copy]; |
730 // Read the tag. | 728 // Read the tag. |
731 NSUInteger beginTag = NSMaxRange(startingRange); | 729 NSUInteger beginTag = NSMaxRange(startingRange); |
732 NSRange closingParenthesis = [string | 730 NSRange closingParenthesis = [string |
733 rangeOfString:@")" | 731 rangeOfString:@")" |
734 options:NSLiteralSearch | 732 options:NSLiteralSearch |
735 range:NSMakeRange(beginTag, [string length] - beginTag)]; | 733 range:NSMakeRange(beginTag, [string length] - beginTag)]; |
736 if (closingParenthesis.location == NSNotFound) | 734 if (closingParenthesis.location == NSNotFound) |
737 return [[string copy] autorelease]; | 735 return [string copy]; |
738 NSInteger tag = [[string | 736 NSInteger tag = [[string |
739 substringWithRange:NSMakeRange(beginTag, closingParenthesis.location - | 737 substringWithRange:NSMakeRange(beginTag, closingParenthesis.location - |
740 beginTag)] integerValue]; | 738 beginTag)] integerValue]; |
741 // If the parsing fails, |tag| is 0. Negative values are not allowed. | 739 // If the parsing fails, |tag| is 0. Negative values are not allowed. |
742 if (tag <= 0) | 740 if (tag <= 0) |
743 return [[string copy] autorelease]; | 741 return [string copy]; |
744 // Find the closing marker. | 742 // Find the closing marker. |
745 startingRange.length = | 743 startingRange.length = |
746 closingParenthesis.location - startingRange.location + 1; | 744 closingParenthesis.location - startingRange.location + 1; |
747 NSRange endingRange = | 745 NSRange endingRange = |
748 [string rangeOfString:[InfoBarView closingMarkerForLink]]; | 746 [string rangeOfString:[InfoBarView closingMarkerForLink]]; |
749 DCHECK(endingRange.length); | 747 DCHECK(endingRange.length); |
750 // Compute range of link in stripped string and add it to the array. | 748 // Compute range of link in stripped string and add it to the array. |
751 NSRange rangeOfLinkInStrippedString = | 749 NSRange rangeOfLinkInStrippedString = |
752 NSMakeRange(startingRange.location, | 750 NSMakeRange(startingRange.location, |
753 endingRange.location - NSMaxRange(startingRange)); | 751 endingRange.location - NSMaxRange(startingRange)); |
754 linkRanges_.push_back(std::make_pair(tag, rangeOfLinkInStrippedString)); | 752 linkRanges_.push_back(std::make_pair(tag, rangeOfLinkInStrippedString)); |
755 // Creates a new string without the markers. | 753 // Creates a new string without the markers. |
756 NSString* beforeLink = [string substringToIndex:startingRange.location]; | 754 NSString* beforeLink = [string substringToIndex:startingRange.location]; |
757 NSRange rangeOfLink = | 755 NSRange rangeOfLink = |
758 NSMakeRange(NSMaxRange(startingRange), | 756 NSMakeRange(NSMaxRange(startingRange), |
759 endingRange.location - NSMaxRange(startingRange)); | 757 endingRange.location - NSMaxRange(startingRange)); |
760 NSString* link = [string substringWithRange:rangeOfLink]; | 758 NSString* link = [string substringWithRange:rangeOfLink]; |
761 NSString* afterLink = [string substringFromIndex:NSMaxRange(endingRange)]; | 759 NSString* afterLink = [string substringFromIndex:NSMaxRange(endingRange)]; |
762 string = [NSString stringWithFormat:@"%@%@%@", beforeLink, link, afterLink]; | 760 string = [NSString stringWithFormat:@"%@%@%@", beforeLink, link, afterLink]; |
763 } | 761 } |
764 } | 762 } |
765 | 763 |
766 - (void)addLabel:(NSString*)label { | 764 - (void)addLabel:(NSString*)label { |
767 [self addLabel:label action:nil]; | 765 [self addLabel:label action:nil]; |
768 } | 766 } |
769 | 767 |
770 - (void)addLabel:(NSString*)text action:(void (^)(NSUInteger))action { | 768 - (void)addLabel:(NSString*)text action:(void (^)(NSUInteger))action { |
771 markedLabel_.reset([text copy]); | 769 markedLabel_ = [text copy]; |
772 if (action) | 770 if (action) |
773 text = [self stripMarkersFromString:text]; | 771 text = [self stripMarkersFromString:text]; |
774 if ([label_ superview]) { | 772 if ([label_ superview]) { |
775 [label_ removeFromSuperview]; | 773 [label_ removeFromSuperview]; |
776 } | 774 } |
777 | 775 |
778 label_ = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; | 776 label_ = [[UILabel alloc] initWithFrame:CGRectZero]; |
779 | 777 |
780 UIFont* font = [MDCTypography subheadFont]; | 778 UIFont* font = [MDCTypography subheadFont]; |
781 | 779 |
782 [label_ setBackgroundColor:[UIColor clearColor]]; | 780 [label_ setBackgroundColor:[UIColor clearColor]]; |
783 | 781 |
784 NSMutableParagraphStyle* paragraphStyle = | 782 NSMutableParagraphStyle* paragraphStyle = |
785 [[[NSMutableParagraphStyle alloc] init] autorelease]; | 783 [[NSMutableParagraphStyle alloc] init]; |
786 paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; | 784 paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; |
787 paragraphStyle.lineSpacing = kLabelLineSpacing; | 785 paragraphStyle.lineSpacing = kLabelLineSpacing; |
788 NSDictionary* attributes = @{ | 786 NSDictionary* attributes = @{ |
789 NSParagraphStyleAttributeName : paragraphStyle, | 787 NSParagraphStyleAttributeName : paragraphStyle, |
790 NSFontAttributeName : font, | 788 NSFontAttributeName : font, |
791 }; | 789 }; |
792 [label_ setNumberOfLines:0]; | 790 [label_ setNumberOfLines:0]; |
793 | 791 |
794 [label_ setAttributedText:[[[NSAttributedString alloc] | 792 [label_ |
795 initWithString:text | 793 setAttributedText:[[NSAttributedString alloc] initWithString:text |
796 attributes:attributes] autorelease]]; | 794 attributes:attributes]]; |
797 | 795 |
798 [self addSubview:label_]; | 796 [self addSubview:label_]; |
799 | 797 |
800 if (linkRanges_.empty()) | 798 if (linkRanges_.empty()) |
801 return; | 799 return; |
802 | 800 |
803 labelLinkController_.reset([[LabelLinkController alloc] | 801 labelLinkController_ = [[LabelLinkController alloc] |
804 initWithLabel:label_ | 802 initWithLabel:label_ |
805 action:^(const GURL& gurl) { | 803 action:^(const GURL& gurl) { |
806 if (action) { | 804 if (action) { |
807 NSUInteger actionTag = [base::SysUTF8ToNSString( | 805 NSUInteger actionTag = [base::SysUTF8ToNSString( |
808 gurl.ExtractFileName()) integerValue]; | 806 gurl.ExtractFileName()) integerValue]; |
809 action(actionTag); | 807 action(actionTag); |
810 } | 808 } |
811 }]); | 809 }]; |
812 | 810 |
813 [labelLinkController_ setLinkUnderlineStyle:NSUnderlineStyleSingle]; | 811 [labelLinkController_ setLinkUnderlineStyle:NSUnderlineStyleSingle]; |
814 [labelLinkController_ setLinkColor:[UIColor blackColor]]; | 812 [labelLinkController_ setLinkColor:[UIColor blackColor]]; |
815 | 813 |
816 std::vector<std::pair<NSUInteger, NSRange>>::const_iterator it; | 814 std::vector<std::pair<NSUInteger, NSRange>>::const_iterator it; |
817 for (it = linkRanges_.begin(); it != linkRanges_.end(); ++it) { | 815 for (it = linkRanges_.begin(); it != linkRanges_.end(); ++it) { |
818 // The last part of the URL contains the tag, so it can be retrieved in the | 816 // The last part of the URL contains the tag, so it can be retrieved in the |
819 // callback. This tag is generally a command ID. | 817 // callback. This tag is generally a command ID. |
820 std::string url = std::string(kChromeInfobarURL) + | 818 std::string url = std::string(kChromeInfobarURL) + |
821 std::string(std::to_string((int)it->first)); | 819 std::string(std::to_string((int)it->first)); |
822 [labelLinkController_ addLinkWithRange:it->second url:GURL(url)]; | 820 [labelLinkController_ addLinkWithRange:it->second url:GURL(url)]; |
823 } | 821 } |
824 } | 822 } |
825 | 823 |
826 - (void)addButton1:(NSString*)title1 | 824 - (void)addButton1:(NSString*)title1 |
827 tag1:(NSInteger)tag1 | 825 tag1:(NSInteger)tag1 |
828 button2:(NSString*)title2 | 826 button2:(NSString*)title2 |
829 tag2:(NSInteger)tag2 | 827 tag2:(NSInteger)tag2 |
830 target:(id)target | 828 target:(id)target |
831 action:(SEL)action { | 829 action:(SEL)action { |
832 button1_.reset([[self infoBarButton:title1 | 830 button1_ = [self infoBarButton:title1 |
833 palette:[MDCPalette cr_bluePalette] | 831 palette:[MDCPalette cr_bluePalette] |
834 customTitleColor:[UIColor whiteColor] | 832 customTitleColor:[UIColor whiteColor] |
835 tag:tag1 | 833 tag:tag1 |
836 target:target | 834 target:target |
837 action:action] retain]); | 835 action:action]; |
838 [self addSubview:button1_]; | 836 [self addSubview:button1_]; |
839 | 837 |
840 button2_.reset([[self infoBarButton:title2 | 838 button2_ = [self infoBarButton:title2 |
841 palette:nil | 839 palette:nil |
842 customTitleColor:UIColorFromRGB(kButton2TitleColor) | 840 customTitleColor:UIColorFromRGB(kButton2TitleColor) |
843 tag:tag2 | 841 tag:tag2 |
844 target:target | 842 target:target |
845 action:action] retain]); | 843 action:action]; |
846 [self addSubview:button2_]; | 844 [self addSubview:button2_]; |
847 } | 845 } |
848 | 846 |
849 - (void)addButton:(NSString*)title | 847 - (void)addButton:(NSString*)title |
850 tag:(NSInteger)tag | 848 tag:(NSInteger)tag |
851 target:(id)target | 849 target:(id)target |
852 action:(SEL)action { | 850 action:(SEL)action { |
853 if (![title length]) | 851 if (![title length]) |
854 return; | 852 return; |
855 button1_.reset([[self infoBarButton:title | 853 button1_ = [self infoBarButton:title |
856 palette:[MDCPalette cr_bluePalette] | 854 palette:[MDCPalette cr_bluePalette] |
857 customTitleColor:[UIColor whiteColor] | 855 customTitleColor:[UIColor whiteColor] |
858 tag:tag | 856 tag:tag |
859 target:target | 857 target:target |
860 action:action] retain]); | 858 action:action]; |
861 [self addSubview:button1_]; | 859 [self addSubview:button1_]; |
862 } | 860 } |
863 | 861 |
864 // Initializes and returns a button for the infobar, with the specified | 862 // Initializes and returns a button for the infobar, with the specified |
865 // |message| and colors. | 863 // |message| and colors. |
866 - (UIButton*)infoBarButton:(NSString*)message | 864 - (UIButton*)infoBarButton:(NSString*)message |
867 palette:(MDCPalette*)palette | 865 palette:(MDCPalette*)palette |
868 customTitleColor:(UIColor*)customTitleColor | 866 customTitleColor:(UIColor*)customTitleColor |
869 tag:(NSInteger)tag | 867 tag:(NSInteger)tag |
870 target:(id)target | 868 target:(id)target |
871 action:(SEL)action { | 869 action:(SEL)action { |
872 base::scoped_nsobject<MDCFlatButton> button([[MDCFlatButton alloc] init]); | 870 MDCFlatButton* button = [[MDCFlatButton alloc] init]; |
873 button.get().inkColor = [[palette tint300] colorWithAlphaComponent:0.5f]; | 871 button.inkColor = [[palette tint300] colorWithAlphaComponent:0.5f]; |
874 [button setBackgroundColor:[palette tint500] forState:UIControlStateNormal]; | 872 [button setBackgroundColor:[palette tint500] forState:UIControlStateNormal]; |
875 [button setBackgroundColor:[UIColor colorWithWhite:0.8f alpha:1.0f] | 873 [button setBackgroundColor:[UIColor colorWithWhite:0.8f alpha:1.0f] |
876 forState:UIControlStateDisabled]; | 874 forState:UIControlStateDisabled]; |
877 if (palette) | 875 if (palette) |
878 button.get().hasOpaqueBackground = YES; | 876 button.hasOpaqueBackground = YES; |
879 if (customTitleColor) { | 877 if (customTitleColor) { |
880 button.get().tintAdjustmentMode = UIViewTintAdjustmentModeNormal; | 878 button.tintAdjustmentMode = UIViewTintAdjustmentModeNormal; |
881 button.get().customTitleColor = customTitleColor; | 879 button.customTitleColor = customTitleColor; |
882 } | 880 } |
883 button.get().titleLabel.adjustsFontSizeToFitWidth = YES; | 881 button.titleLabel.adjustsFontSizeToFitWidth = YES; |
884 button.get().titleLabel.minimumScaleFactor = 0.6f; | 882 button.titleLabel.minimumScaleFactor = 0.6f; |
885 [button setTitle:message forState:UIControlStateNormal]; | 883 [button setTitle:message forState:UIControlStateNormal]; |
886 [button setTag:tag]; | 884 [button setTag:tag]; |
887 [button addTarget:target | 885 [button addTarget:target |
888 action:action | 886 action:action |
889 forControlEvents:UIControlEventTouchUpInside]; | 887 forControlEvents:UIControlEventTouchUpInside]; |
890 // Without the call to layoutIfNeeded, |button| returns an incorrect | 888 // Without the call to layoutIfNeeded, |button| returns an incorrect |
891 // titleLabel the first time it is accessed in |narrowestWidthOfButton|. | 889 // titleLabel the first time it is accessed in |narrowestWidthOfButton|. |
892 [button layoutIfNeeded]; | 890 [button layoutIfNeeded]; |
893 return button.autorelease(); | 891 return button; |
894 } | 892 } |
895 | 893 |
896 - (CGRect)frameOfCloseButton:(BOOL)singleLineMode { | 894 - (CGRect)frameOfCloseButton:(BOOL)singleLineMode { |
897 DCHECK(closeButton_); | 895 DCHECK(closeButton_); |
898 // Add padding to increase the touchable area. | 896 // Add padding to increase the touchable area. |
899 CGSize closeButtonSize = [closeButton_ imageView].image.size; | 897 CGSize closeButtonSize = [closeButton_ imageView].image.size; |
900 closeButtonSize.width += kCloseButtonInnerPadding * 2; | 898 closeButtonSize.width += kCloseButtonInnerPadding * 2; |
901 closeButtonSize.height += kCloseButtonInnerPadding * 2; | 899 closeButtonSize.height += kCloseButtonInnerPadding * 2; |
902 CGFloat x = CGRectGetMaxX(self.frame) - closeButtonSize.width; | 900 CGFloat x = CGRectGetMaxX(self.frame) - closeButtonSize.width; |
903 // Aligns the close button at the top (height includes touch padding). | 901 // Aligns the close button at the top (height includes touch padding). |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 | 943 |
946 - (CGFloat)buttonMargin { | 944 - (CGFloat)buttonMargin { |
947 return kButtonMargin; | 945 return kButtonMargin; |
948 } | 946 } |
949 | 947 |
950 - (const std::vector<std::pair<NSUInteger, NSRange>>&)linkRanges { | 948 - (const std::vector<std::pair<NSUInteger, NSRange>>&)linkRanges { |
951 return linkRanges_; | 949 return linkRanges_; |
952 } | 950 } |
953 | 951 |
954 @end | 952 @end |
OLD | NEW |