OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 // For performance reasons, the composition of the card frame is broken up into | 5 // For performance reasons, the composition of the card frame is broken up into |
6 // four pieces. The overall structure of the CardView is: | 6 // four pieces. The overall structure of the CardView is: |
7 // - CardView | 7 // - CardView |
8 // - Snapshot (UIImageView) | 8 // - Snapshot (UIImageView) |
9 // - FrameTop (UIImageView) | 9 // - FrameTop (UIImageView) |
10 // - FrameLeft (UIImageView) | 10 // - FrameLeft (UIImageView) |
11 // - FrameRight (UIImageView) | 11 // - FrameRight (UIImageView) |
12 // - FrameBottom (UIImageView) | 12 // - FrameBottom (UIImageView) |
13 // - CardTabView (UIView::DrawRect) | 13 // - CardTabView (UIView::DrawRect) |
14 // | 14 // |
15 // While it would be simpler to put the frame in one transparent UIImageView, | 15 // While it would be simpler to put the frame in one transparent UIImageView, |
16 // that would make the entire snapshot area needlessly color-blended. Instead | 16 // that would make the entire snapshot area needlessly color-blended. Instead |
17 // the frame is broken up into four pieces, top, left, bottom, right. | 17 // the frame is broken up into four pieces, top, left, bottom, right. |
18 // | 18 // |
19 // The frame's tab gets its own view above everything else (CardTabView) so that | 19 // The frame's tab gets its own view above everything else (CardTabView) so that |
20 // it can be animated out. It's also transparent since the tab has a curve and | 20 // it can be animated out. It's also transparent since the tab has a curve and |
21 // a shadow. | 21 // a shadow. |
22 | 22 |
23 #import "ios/chrome/browser/ui/stack_view/card_view.h" | 23 #import "ios/chrome/browser/ui/stack_view/card_view.h" |
24 | 24 |
25 #import <QuartzCore/QuartzCore.h> | 25 #import <QuartzCore/QuartzCore.h> |
26 #include <algorithm> | 26 #include <algorithm> |
27 | 27 |
28 #import "base/mac/foundation_util.h" | 28 #import "base/mac/foundation_util.h" |
29 | 29 #import "base/mac/objc_property_releaser.h" |
| 30 #import "base/mac/scoped_nsobject.h" |
30 #include "components/strings/grit/components_strings.h" | 31 #include "components/strings/grit/components_strings.h" |
31 #import "ios/chrome/browser/ui/animation_util.h" | 32 #import "ios/chrome/browser/ui/animation_util.h" |
32 #import "ios/chrome/browser/ui/reversed_animation.h" | 33 #import "ios/chrome/browser/ui/reversed_animation.h" |
33 #import "ios/chrome/browser/ui/rtl_geometry.h" | 34 #import "ios/chrome/browser/ui/rtl_geometry.h" |
34 #import "ios/chrome/browser/ui/stack_view/close_button.h" | 35 #import "ios/chrome/browser/ui/stack_view/close_button.h" |
35 #import "ios/chrome/browser/ui/stack_view/title_label.h" | 36 #import "ios/chrome/browser/ui/stack_view/title_label.h" |
36 #import "ios/chrome/browser/ui/ui_util.h" | 37 #import "ios/chrome/browser/ui/ui_util.h" |
37 #import "ios/chrome/common/material_timing.h" | 38 #import "ios/chrome/common/material_timing.h" |
38 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 39 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
39 #include "ui/base/l10n/l10n_util.h" | 40 #include "ui/base/l10n/l10n_util.h" |
40 #include "ui/base/resource/resource_bundle.h" | 41 #include "ui/base/resource/resource_bundle.h" |
41 #include "ui/gfx/favicon_size.h" | 42 #include "ui/gfx/favicon_size.h" |
42 #include "ui/gfx/image/image.h" | 43 #include "ui/gfx/image/image.h" |
43 #import "ui/gfx/ios/uikit_util.h" | 44 #import "ui/gfx/ios/uikit_util.h" |
44 | 45 |
45 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
46 #error "This file requires ARC support." | |
47 #endif | |
48 | |
49 using ios::material::TimingFunction; | 46 using ios::material::TimingFunction; |
50 | 47 |
51 const UIEdgeInsets kCardImageInsets = {48.0, 4.0, 4.0, 4.0}; | 48 const UIEdgeInsets kCardImageInsets = {48.0, 4.0, 4.0, 4.0}; |
52 const CGFloat kCardFrameInset = 1.0; | 49 const CGFloat kCardFrameInset = 1.0; |
53 const CGFloat kCardShadowThickness = 16.0; | 50 const CGFloat kCardShadowThickness = 16.0; |
54 const CGFloat kCardFrameCornerRadius = 4.0; | 51 const CGFloat kCardFrameCornerRadius = 4.0; |
55 const CGFloat kCardTabTopInset = 4; | 52 const CGFloat kCardTabTopInset = 4; |
56 const CGFloat kCardFrameBackgroundBrightness = 242.0 / 255.0; | 53 const CGFloat kCardFrameBackgroundBrightness = 242.0 / 255.0; |
57 const CGFloat kCardFrameBackgroundBrightnessIncognito = 80.0 / 255.0; | 54 const CGFloat kCardFrameBackgroundBrightnessIncognito = 80.0 / 255.0; |
58 const CGFloat kCardFrameImageSnapshotOverlap = 1.0; | 55 const CGFloat kCardFrameImageSnapshotOverlap = 1.0; |
(...skipping 22 matching lines...) Expand all Loading... |
81 return [UIImage imageNamed:name]; | 78 return [UIImage imageNamed:name]; |
82 } | 79 } |
83 | 80 |
84 } // namespace | 81 } // namespace |
85 | 82 |
86 #pragma mark - | 83 #pragma mark - |
87 | 84 |
88 @interface CardTabView : UIView | 85 @interface CardTabView : UIView |
89 | 86 |
90 @property(nonatomic, assign) CardCloseButtonSide closeButtonSide; | 87 @property(nonatomic, assign) CardCloseButtonSide closeButtonSide; |
91 @property(nonatomic, strong) UIImageView* favIconView; | 88 @property(nonatomic, retain) UIImageView* favIconView; |
92 @property(nonatomic, strong) UIImage* favicon; | 89 @property(nonatomic, retain) UIImage* favicon; |
93 @property(nonatomic, strong) CloseButton* closeButton; | 90 @property(nonatomic, retain) CloseButton* closeButton; |
94 @property(nonatomic, strong) TitleLabel* titleLabel; | 91 @property(nonatomic, retain) TitleLabel* titleLabel; |
95 @property(nonatomic, assign) BOOL isIncognito; | 92 @property(nonatomic, assign) BOOL isIncognito; |
96 | 93 |
97 // Layout helper selectors that calculate the frames for subviews given the | 94 // Layout helper selectors that calculate the frames for subviews given the |
98 // bounds of the card tab. Note that the frames returned by these selectors | 95 // bounds of the card tab. Note that the frames returned by these selectors |
99 // will be different depending on the value of the |displaySide| property. | 96 // will be different depending on the value of the |displaySide| property. |
100 - (LayoutRect)faviconLayoutForBounds:(CGRect)bounds; | 97 - (LayoutRect)faviconLayoutForBounds:(CGRect)bounds; |
101 - (CGRect)faviconFrameForBounds:(CGRect)bounds; | 98 - (CGRect)faviconFrameForBounds:(CGRect)bounds; |
102 - (LayoutRect)titleLabelLayoutForBounds:(CGRect)bounds; | 99 - (LayoutRect)titleLabelLayoutForBounds:(CGRect)bounds; |
103 - (CGRect)titleLabelFrameForBounds:(CGRect)bounds; | 100 - (CGRect)titleLabelFrameForBounds:(CGRect)bounds; |
104 - (LayoutRect)closeButtonLayoutForBounds:(CGRect)bounds; | 101 - (LayoutRect)closeButtonLayoutForBounds:(CGRect)bounds; |
(...skipping 15 matching lines...) Expand all Loading... |
120 - (void)cleanUpAnimations; | 117 - (void)cleanUpAnimations; |
121 | 118 |
122 // Initialize a CardTabView with |frame| and |isIncognito| state. | 119 // Initialize a CardTabView with |frame| and |isIncognito| state. |
123 - (instancetype)initWithFrame:(CGRect)frame | 120 - (instancetype)initWithFrame:(CGRect)frame |
124 isIncognito:(BOOL)isIncognito NS_DESIGNATED_INITIALIZER; | 121 isIncognito:(BOOL)isIncognito NS_DESIGNATED_INITIALIZER; |
125 | 122 |
126 - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; | 123 - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; |
127 | 124 |
128 @end | 125 @end |
129 | 126 |
130 @implementation CardTabView | 127 @implementation CardTabView { |
| 128 base::mac::ObjCPropertyReleaser _propertyReleaser_CardTabView; |
| 129 } |
131 | 130 |
132 #pragma mark - Property Implementation | 131 #pragma mark - Property Implementation |
133 | 132 |
134 @synthesize closeButtonSide = _closeButtonSide; | 133 @synthesize closeButtonSide = _closeButtonSide; |
135 @synthesize favIconView = _faviconView; | 134 @synthesize favIconView = _faviconView; |
136 @synthesize favicon = _favicon; | 135 @synthesize favicon = _favicon; |
137 @synthesize closeButton = _closeButton; | 136 @synthesize closeButton = _closeButton; |
138 @synthesize titleLabel = _titleLabel; | 137 @synthesize titleLabel = _titleLabel; |
139 @synthesize isIncognito = _isIncognito; | 138 @synthesize isIncognito = _isIncognito; |
140 | 139 |
141 - (instancetype)initWithFrame:(CGRect)frame { | 140 - (instancetype)initWithFrame:(CGRect)frame { |
142 return [self initWithFrame:frame isIncognito:NO]; | 141 return [self initWithFrame:frame isIncognito:NO]; |
143 } | 142 } |
144 | 143 |
145 - (instancetype)initWithFrame:(CGRect)frame isIncognito:(BOOL)isIncognito { | 144 - (instancetype)initWithFrame:(CGRect)frame isIncognito:(BOOL)isIncognito { |
146 self = [super initWithFrame:frame]; | 145 self = [super initWithFrame:frame]; |
147 if (!self) | 146 if (!self) |
148 return self; | 147 return self; |
149 | 148 |
| 149 _propertyReleaser_CardTabView.Init(self, [CardTabView class]); |
150 _isIncognito = isIncognito; | 150 _isIncognito = isIncognito; |
151 | 151 |
152 UIImage* image = ImageWithName(@"default_favicon", _isIncognito); | 152 UIImage* image = ImageWithName(@"default_favicon", _isIncognito); |
153 _faviconView = [[UIImageView alloc] initWithImage:image]; | 153 _faviconView = [[UIImageView alloc] initWithImage:image]; |
154 [self addSubview:_faviconView]; | 154 [self addSubview:_faviconView]; |
155 | 155 |
156 UIImage* normal = ImageWithName(@"card_close_button", _isIncognito); | 156 UIImage* normal = ImageWithName(@"card_close_button", _isIncognito); |
157 UIImage* pressed = ImageWithName(@"card_close_button_pressed", _isIncognito); | 157 UIImage* pressed = ImageWithName(@"card_close_button_pressed", _isIncognito); |
158 | 158 |
159 _closeButton = [[CloseButton alloc] initWithFrame:CGRectZero]; | 159 _closeButton = [[CloseButton alloc] initWithFrame:CGRectZero]; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 | 265 |
266 - (void)setTitle:(NSString*)title { | 266 - (void)setTitle:(NSString*)title { |
267 [_titleLabel setText:title]; | 267 [_titleLabel setText:title]; |
268 [_closeButton setAccessibilityValue:title]; | 268 [_closeButton setAccessibilityValue:title]; |
269 | 269 |
270 [self setNeedsUpdateConstraints]; | 270 [self setNeedsUpdateConstraints]; |
271 } | 271 } |
272 | 272 |
273 - (void)setFavicon:(UIImage*)favicon { | 273 - (void)setFavicon:(UIImage*)favicon { |
274 if (favicon != _favicon) { | 274 if (favicon != _favicon) { |
| 275 [favicon retain]; |
| 276 [_favicon release]; |
275 _favicon = favicon; | 277 _favicon = favicon; |
276 [self updateFaviconImage]; | 278 [self updateFaviconImage]; |
277 } | 279 } |
278 } | 280 } |
279 | 281 |
280 - (void)updateTitleColors { | 282 - (void)updateTitleColors { |
281 UIColor* titleColor = [UIColor blackColor]; | 283 UIColor* titleColor = [UIColor blackColor]; |
282 if (_isIncognito) | 284 if (_isIncognito) |
283 titleColor = [UIColor whiteColor]; | 285 titleColor = [UIColor whiteColor]; |
284 | 286 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 else if (element == _titleLabel) | 430 else if (element == _titleLabel) |
429 index = closeButtonLeading ? 1 : 0; | 431 index = closeButtonLeading ? 1 : 0; |
430 return index; | 432 return index; |
431 } | 433 } |
432 | 434 |
433 @end | 435 @end |
434 | 436 |
435 #pragma mark - | 437 #pragma mark - |
436 | 438 |
437 @interface CardView () { | 439 @interface CardView () { |
438 UIImageView* _contents; | 440 base::scoped_nsobject<UIImageView> _contents; |
439 CardTabView* _tab; | 441 base::scoped_nsobject<CardTabView> _tab; |
440 id _cardCloseTarget; // weak | 442 id _cardCloseTarget; // weak |
441 SEL _cardCloseAction; | 443 SEL _cardCloseAction; |
442 id _accessibilityTarget; // weak | 444 id _accessibilityTarget; // weak |
443 SEL _accessibilityAction; | 445 SEL _accessibilityAction; |
444 | 446 |
445 BOOL _isIncognito; // YES if the card should use the incognito styling. | 447 BOOL _isIncognito; // YES if the card should use the incognito styling. |
446 | 448 |
447 // Pieces of the card frame, split into four UIViews. | 449 // Pieces of the card frame, split into four UIViews. |
448 UIImageView* _frameLeft; | 450 base::scoped_nsobject<UIImageView> _frameLeft; |
449 UIImageView* _frameRight; | 451 base::scoped_nsobject<UIImageView> _frameRight; |
450 UIImageView* _frameTop; | 452 base::scoped_nsobject<UIImageView> _frameTop; |
451 UIImageView* _frameBottom; | 453 base::scoped_nsobject<UIImageView> _frameBottom; |
452 UIImageView* _frameShadowImageView; | 454 base::scoped_nsobject<UIImageView> _frameShadowImageView; |
453 CALayer* _shadowMask; | 455 base::scoped_nsobject<CALayer> _shadowMask; |
454 } | 456 } |
455 | 457 |
456 // The LayoutRect for the CardTabView. | 458 // The LayoutRect for the CardTabView. |
457 - (LayoutRect)tabLayout; | 459 - (LayoutRect)tabLayout; |
458 | 460 |
459 // Sends |_cardCloseAction| to |_cardCloseTarget| with |self| as the sender. | 461 // Sends |_cardCloseAction| to |_cardCloseTarget| with |self| as the sender. |
460 - (void)closeButtonWasTapped:(id)sender; | 462 - (void)closeButtonWasTapped:(id)sender; |
461 | 463 |
462 // Resizes/zooms the snapshot to avoid stretching given the card's current | 464 // Resizes/zooms the snapshot to avoid stretching given the card's current |
463 // bounds. | 465 // bounds. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 if (!self) | 504 if (!self) |
503 return self; | 505 return self; |
504 | 506 |
505 _isIncognito = isIncognito; | 507 _isIncognito = isIncognito; |
506 CGRect bounds = self.bounds; | 508 CGRect bounds = self.bounds; |
507 | 509 |
508 self.opaque = NO; | 510 self.opaque = NO; |
509 self.contentMode = UIViewContentModeRedraw; | 511 self.contentMode = UIViewContentModeRedraw; |
510 | 512 |
511 CGRect shadowFrame = UIEdgeInsetsInsetRect(bounds, kCardShadowLayoutOutsets); | 513 CGRect shadowFrame = UIEdgeInsetsInsetRect(bounds, kCardShadowLayoutOutsets); |
512 _frameShadowImageView = [[UIImageView alloc] initWithFrame:shadowFrame]; | 514 _frameShadowImageView.reset([[UIImageView alloc] initWithFrame:shadowFrame]); |
513 [_frameShadowImageView | 515 [_frameShadowImageView |
514 setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | | 516 setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | |
515 UIViewAutoresizingFlexibleHeight)]; | 517 UIViewAutoresizingFlexibleHeight)]; |
516 [self addSubview:_frameShadowImageView]; | 518 [self addSubview:_frameShadowImageView]; |
517 | 519 |
518 // Calling properties for side-effects. | 520 // Calling properties for side-effects. |
519 self.shouldShowShadow = YES; | 521 self.shouldShowShadow = YES; |
520 self.shouldMaskShadow = YES; | 522 self.shouldMaskShadow = YES; |
521 | 523 |
522 UIImage* image = [UIImage imageNamed:kCardShadowImageName]; | 524 UIImage* image = [UIImage imageNamed:kCardShadowImageName]; |
523 image = [image resizableImageWithCapInsets:kShadowStretchInsets]; | 525 image = [image resizableImageWithCapInsets:kShadowStretchInsets]; |
524 [_frameShadowImageView setImage:image]; | 526 [_frameShadowImageView setImage:image]; |
525 | 527 |
526 CGRect snapshotFrame = UIEdgeInsetsInsetRect(bounds, kCardImageInsets); | 528 CGRect snapshotFrame = UIEdgeInsetsInsetRect(bounds, kCardImageInsets); |
527 _contents = [[UIImageView alloc] initWithFrame:snapshotFrame]; | 529 _contents.reset([[UIImageView alloc] initWithFrame:snapshotFrame]); |
528 [_contents setClipsToBounds:YES]; | 530 [_contents setClipsToBounds:YES]; |
529 [_contents setContentMode:UIViewContentModeScaleAspectFill]; | 531 [_contents setContentMode:UIViewContentModeScaleAspectFill]; |
530 [_contents setFrame:snapshotFrame]; | 532 [_contents setFrame:snapshotFrame]; |
531 [_contents setAutoresizingMask:UIViewAutoresizingFlexibleWidth | | 533 [_contents setAutoresizingMask:UIViewAutoresizingFlexibleWidth | |
532 UIViewAutoresizingFlexibleHeight]; | 534 UIViewAutoresizingFlexibleHeight]; |
533 [self addSubview:_contents]; | 535 [self addSubview:_contents]; |
534 | 536 |
535 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_left" | 537 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_left" |
536 : @"border_frame_left"]; | 538 : @"border_frame_left"]; |
537 UIEdgeInsets imageStretchInsets = UIEdgeInsetsMake( | 539 UIEdgeInsets imageStretchInsets = UIEdgeInsetsMake( |
538 0.5 * image.size.height, 0.0, 0.5 * image.size.height, 0.0); | 540 0.5 * image.size.height, 0.0, 0.5 * image.size.height, 0.0); |
539 image = [image resizableImageWithCapInsets:imageStretchInsets]; | 541 image = [image resizableImageWithCapInsets:imageStretchInsets]; |
540 _frameLeft = [[UIImageView alloc] initWithImage:image]; | 542 _frameLeft.reset([[UIImageView alloc] initWithImage:image]); |
541 [self addSubview:_frameLeft]; | 543 [self addSubview:_frameLeft]; |
542 | 544 |
543 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_right" | 545 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_right" |
544 : @"border_frame_right"]; | 546 : @"border_frame_right"]; |
545 imageStretchInsets = UIEdgeInsetsMake(0.5 * image.size.height, 0.0, | 547 imageStretchInsets = UIEdgeInsetsMake(0.5 * image.size.height, 0.0, |
546 0.5 * image.size.height, 0.0); | 548 0.5 * image.size.height, 0.0); |
547 image = [image resizableImageWithCapInsets:imageStretchInsets]; | 549 image = [image resizableImageWithCapInsets:imageStretchInsets]; |
548 _frameRight = [[UIImageView alloc] initWithImage:image]; | 550 _frameRight.reset([[UIImageView alloc] initWithImage:image]); |
549 [self addSubview:_frameRight]; | 551 [self addSubview:_frameRight]; |
550 | 552 |
551 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_top" | 553 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_top" |
552 : @"border_frame_top"]; | 554 : @"border_frame_top"]; |
553 imageStretchInsets = UIEdgeInsetsMake(0.0, 0.5 * image.size.width, 0.0, | 555 imageStretchInsets = UIEdgeInsetsMake(0.0, 0.5 * image.size.width, 0.0, |
554 0.5 * image.size.width); | 556 0.5 * image.size.width); |
555 image = [image resizableImageWithCapInsets:imageStretchInsets]; | 557 image = [image resizableImageWithCapInsets:imageStretchInsets]; |
556 _frameTop = [[UIImageView alloc] initWithImage:image]; | 558 _frameTop.reset([[UIImageView alloc] initWithImage:image]); |
557 [self addSubview:_frameTop]; | 559 [self addSubview:_frameTop]; |
558 | 560 |
559 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_bottom" | 561 image = [UIImage imageNamed:isIncognito ? @"border_frame_incognito_bottom" |
560 : @"border_frame_bottom"]; | 562 : @"border_frame_bottom"]; |
561 imageStretchInsets = UIEdgeInsetsMake(0.0, 0.5 * image.size.width, 0.0, | 563 imageStretchInsets = UIEdgeInsetsMake(0.0, 0.5 * image.size.width, 0.0, |
562 0.5 * image.size.width); | 564 0.5 * image.size.width); |
563 image = [image resizableImageWithCapInsets:imageStretchInsets]; | 565 image = [image resizableImageWithCapInsets:imageStretchInsets]; |
564 _frameBottom = [[UIImageView alloc] initWithImage:image]; | 566 _frameBottom.reset([[UIImageView alloc] initWithImage:image]); |
565 [self addSubview:_frameBottom]; | 567 [self addSubview:_frameBottom]; |
566 | 568 |
567 _tab = [[CardTabView alloc] initWithFrame:LayoutRectGetRect([self tabLayout]) | 569 _tab.reset([[CardTabView alloc] |
568 isIncognito:_isIncognito]; | 570 initWithFrame:LayoutRectGetRect([self tabLayout]) |
| 571 isIncognito:_isIncognito]); |
569 [_tab setCloseButtonSide:IsPortrait() ? CardCloseButtonSide::TRAILING | 572 [_tab setCloseButtonSide:IsPortrait() ? CardCloseButtonSide::TRAILING |
570 : CardCloseButtonSide::LEADING]; | 573 : CardCloseButtonSide::LEADING]; |
571 [[_tab closeButton] addTarget:self | 574 [[_tab closeButton] addTarget:self |
572 action:@selector(closeButtonWasTapped:) | 575 action:@selector(closeButtonWasTapped:) |
573 forControlEvents:UIControlEventTouchUpInside]; | 576 forControlEvents:UIControlEventTouchUpInside]; |
574 [[_tab closeButton] | 577 [[_tab closeButton] |
575 addAccessibilityElementFocusedTarget:self | 578 addAccessibilityElementFocusedTarget:self |
576 action:@selector(elementDidBecomeFocused:)]; | 579 action:@selector(elementDidBecomeFocused:)]; |
577 [_tab closeButton].accessibilityIdentifier = [self closeButtonId]; | 580 [_tab closeButton].accessibilityIdentifier = [self closeButtonId]; |
578 | 581 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 640 |
638 - (TitleLabel*)titleLabel { | 641 - (TitleLabel*)titleLabel { |
639 return [_tab titleLabel]; | 642 return [_tab titleLabel]; |
640 } | 643 } |
641 | 644 |
642 - (void)setFavicon:(UIImage*)favicon { | 645 - (void)setFavicon:(UIImage*)favicon { |
643 [_tab setFavicon:favicon]; | 646 [_tab setFavicon:favicon]; |
644 } | 647 } |
645 | 648 |
646 - (void)closeButtonWasTapped:(id)sender { | 649 - (void)closeButtonWasTapped:(id)sender { |
647 #pragma clang diagnostic push | |
648 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" | |
649 [_cardCloseTarget performSelector:_cardCloseAction withObject:self]; | 650 [_cardCloseTarget performSelector:_cardCloseAction withObject:self]; |
650 #pragma clang diagnostic pop | |
651 // Disable the tab's close button to prevent touch handling from the button | 651 // Disable the tab's close button to prevent touch handling from the button |
652 // while it's animating closed. | 652 // while it's animating closed. |
653 [_tab closeButton].enabled = NO; | 653 [_tab closeButton].enabled = NO; |
654 } | 654 } |
655 | 655 |
656 - (void)addCardCloseTarget:(id)target action:(SEL)action { | 656 - (void)addCardCloseTarget:(id)target action:(SEL)action { |
657 DCHECK(!target || [target respondsToSelector:action]); | 657 DCHECK(!target || [target respondsToSelector:action]); |
658 _cardCloseTarget = target; | 658 _cardCloseTarget = target; |
659 _cardCloseAction = action; | 659 _cardCloseAction = action; |
660 } | 660 } |
(...skipping 11 matching lines...) Expand all Loading... |
672 CGRect cardBounds = {CGPointZero, cardSize}; | 672 CGRect cardBounds = {CGPointZero, cardSize}; |
673 CGSize viewSize = UIEdgeInsetsInsetRect(cardBounds, kCardImageInsets).size; | 673 CGSize viewSize = UIEdgeInsetsInsetRect(cardBounds, kCardImageInsets).size; |
674 CGSize imageSize = [_contents image].size; | 674 CGSize imageSize = [_contents image].size; |
675 CGFloat zoomRatio = std::max(viewSize.height / imageSize.height, | 675 CGFloat zoomRatio = std::max(viewSize.height / imageSize.height, |
676 viewSize.width / imageSize.width); | 676 viewSize.width / imageSize.width); |
677 return CGRectMake(0.0, 0.0, viewSize.width / (zoomRatio * imageSize.width), | 677 return CGRectMake(0.0, 0.0, viewSize.width / (zoomRatio * imageSize.width), |
678 viewSize.height / (zoomRatio * imageSize.height)); | 678 viewSize.height / (zoomRatio * imageSize.height)); |
679 } | 679 } |
680 | 680 |
681 - (void)updateImageBoundsAndZoom { | 681 - (void)updateImageBoundsAndZoom { |
682 UIImageView* imageView = _contents; | 682 UIImageView* imageView = _contents.get(); |
683 DCHECK(!CGRectEqualToRect(self.bounds, CGRectZero)); | 683 DCHECK(!CGRectEqualToRect(self.bounds, CGRectZero)); |
684 | 684 |
685 imageView.frame = UIEdgeInsetsInsetRect(self.bounds, kCardImageInsets); | 685 imageView.frame = UIEdgeInsetsInsetRect(self.bounds, kCardImageInsets); |
686 if (imageView.image) { | 686 if (imageView.image) { |
687 // Zoom the image to fill the available space. | 687 // Zoom the image to fill the available space. |
688 imageView.layer.contentsRect = | 688 imageView.layer.contentsRect = |
689 [self imageContentsRectForCardSize:self.bounds.size]; | 689 [self imageContentsRectForCardSize:self.bounds.size]; |
690 } | 690 } |
691 } | 691 } |
692 | 692 |
693 - (void)updateSnapshotAnimations { | 693 - (void)updateSnapshotAnimations { |
694 CAAnimation* snapshotAnimation = | 694 CAAnimation* snapshotAnimation = |
695 [[_contents layer] animationForKey:kCardViewAnimationKey]; | 695 [[_contents layer] animationForKey:kCardViewAnimationKey]; |
696 if (!snapshotAnimation) | 696 if (!snapshotAnimation) |
697 return; | 697 return; |
698 | 698 |
699 // Create copy of animation (animations become immutable after they're added | 699 // Create copy of animation (animations become immutable after they're added |
700 // to the layer). | 700 // to the layer). |
701 CAAnimationGroup* updatedAnimation = [snapshotAnimation copy]; | 701 base::scoped_nsobject<CAAnimationGroup> updatedAnimation( |
| 702 static_cast<CAAnimationGroup*>([snapshotAnimation copy])); |
702 // Extract begin and end sizes of the card. | 703 // Extract begin and end sizes of the card. |
703 CAAnimation* cardAnimation = | 704 CAAnimation* cardAnimation = |
704 [self.layer animationForKey:kCardViewAnimationKey]; | 705 [self.layer animationForKey:kCardViewAnimationKey]; |
705 CABasicAnimation* cardBoundsAnimation = | 706 CABasicAnimation* cardBoundsAnimation = |
706 FindAnimationForKeyPath(@"bounds", cardAnimation); | 707 FindAnimationForKeyPath(@"bounds", cardAnimation); |
707 CGSize beginCardSize = [cardBoundsAnimation.fromValue CGRectValue].size; | 708 CGSize beginCardSize = [cardBoundsAnimation.fromValue CGRectValue].size; |
708 CGSize endCardSize = [cardBoundsAnimation.toValue CGRectValue].size; | 709 CGSize endCardSize = [cardBoundsAnimation.toValue CGRectValue].size; |
709 // Update the contentsRect animation. | 710 // Update the contentsRect animation. |
710 CABasicAnimation* contentsRectAnimation = | 711 CABasicAnimation* contentsRectAnimation = |
711 FindAnimationForKeyPath(@"contentsRect", updatedAnimation); | 712 FindAnimationForKeyPath(@"contentsRect", updatedAnimation); |
(...skipping 26 matching lines...) Expand all Loading... |
738 } | 739 } |
739 return LayoutRectGetRect(maskLayout); | 740 return LayoutRectGetRect(maskLayout); |
740 } | 741 } |
741 | 742 |
742 - (void)updateShadowMask { | 743 - (void)updateShadowMask { |
743 if (!self.shouldShowShadow) | 744 if (!self.shouldShowShadow) |
744 return; | 745 return; |
745 | 746 |
746 if (self.shouldMaskShadow) { | 747 if (self.shouldMaskShadow) { |
747 if (!_shadowMask) { | 748 if (!_shadowMask) { |
748 _shadowMask = [[CALayer alloc] init]; | 749 _shadowMask.reset([[CALayer alloc] init]); |
749 [_shadowMask setBackgroundColor:[UIColor blackColor].CGColor]; | 750 [_shadowMask setBackgroundColor:[UIColor blackColor].CGColor]; |
750 } | 751 } |
751 [_frameShadowImageView layer].mask = _shadowMask; | 752 [_frameShadowImageView layer].mask = _shadowMask; |
752 [_shadowMask setFrame:[self shadowMaskFrameForBounds:self.bounds]]; | 753 [_shadowMask setFrame:[self shadowMaskFrameForBounds:self.bounds]]; |
753 } else { | 754 } else { |
754 [_frameShadowImageView layer].mask = nil; | 755 [_frameShadowImageView layer].mask = nil; |
755 } | 756 } |
756 } | 757 } |
757 | 758 |
758 - (LayoutRect)tabLayout { | 759 - (LayoutRect)tabLayout { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 frameAnimation = FrameAnimationMake( | 945 frameAnimation = FrameAnimationMake( |
945 [_frameShadowImageView layer], | 946 [_frameShadowImageView layer], |
946 UIEdgeInsetsInsetRect(beginBounds, kCardShadowLayoutOutsets), | 947 UIEdgeInsetsInsetRect(beginBounds, kCardShadowLayoutOutsets), |
947 UIEdgeInsetsInsetRect(endBounds, kCardShadowLayoutOutsets)); | 948 UIEdgeInsetsInsetRect(endBounds, kCardShadowLayoutOutsets)); |
948 frameAnimation.duration = frameDuration; | 949 frameAnimation.duration = frameDuration; |
949 frameAnimation.timingFunction = frameTiming; | 950 frameAnimation.timingFunction = frameTiming; |
950 [[_frameShadowImageView layer] addAnimation:frameAnimation | 951 [[_frameShadowImageView layer] addAnimation:frameAnimation |
951 forKey:kCardViewAnimationKey]; | 952 forKey:kCardViewAnimationKey]; |
952 if (self.shouldMaskShadow) { | 953 if (self.shouldMaskShadow) { |
953 frameAnimation = FrameAnimationMake( | 954 frameAnimation = FrameAnimationMake( |
954 _shadowMask, [self shadowMaskFrameForBounds:beginBounds], | 955 _shadowMask.get(), [self shadowMaskFrameForBounds:beginBounds], |
955 [self shadowMaskFrameForBounds:endBounds]); | 956 [self shadowMaskFrameForBounds:endBounds]); |
956 frameAnimation.duration = frameDuration; | 957 frameAnimation.duration = frameDuration; |
957 frameAnimation.timingFunction = frameTiming; | 958 frameAnimation.timingFunction = frameTiming; |
958 [_shadowMask addAnimation:frameAnimation forKey:kCardViewAnimationKey]; | 959 [_shadowMask addAnimation:frameAnimation forKey:kCardViewAnimationKey]; |
959 } | 960 } |
960 } | 961 } |
961 | 962 |
962 // Update content snapshot | 963 // Update content snapshot |
963 CGRect beginContentFrame = | 964 CGRect beginContentFrame = |
964 UIEdgeInsetsInsetRect(beginBounds, kCardImageInsets); | 965 UIEdgeInsetsInsetRect(beginBounds, kCardImageInsets); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 [_tab titleLabel]); | 1022 [_tab titleLabel]); |
1022 } | 1023 } |
1023 | 1024 |
1024 - (void)addAccessibilityTarget:(id)target action:(SEL)action { | 1025 - (void)addAccessibilityTarget:(id)target action:(SEL)action { |
1025 DCHECK(!target || [target respondsToSelector:action]); | 1026 DCHECK(!target || [target respondsToSelector:action]); |
1026 _accessibilityTarget = target; | 1027 _accessibilityTarget = target; |
1027 _accessibilityAction = action; | 1028 _accessibilityAction = action; |
1028 } | 1029 } |
1029 | 1030 |
1030 - (void)elementDidBecomeFocused:(id)sender { | 1031 - (void)elementDidBecomeFocused:(id)sender { |
1031 #pragma clang diagnostic push | |
1032 #pragma clang diagnostic ignored "-Warc-performSelector-leaks" | |
1033 [_accessibilityTarget performSelector:_accessibilityAction withObject:sender]; | 1032 [_accessibilityTarget performSelector:_accessibilityAction withObject:sender]; |
1034 #pragma clang diagnostic pop | |
1035 } | 1033 } |
1036 | 1034 |
1037 @end | 1035 @end |
OLD | NEW |