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

Side by Side Diff: ios/chrome/browser/ui/fade_truncated_label.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/fade_truncated_label.h"
6
7 #include <algorithm>
8 #include "base/mac/objc_property_releaser.h"
9 #import "ios/chrome/browser/ui/animation_util.h"
10 #import "ios/chrome/browser/ui/reversed_animation.h"
11 #import "ui/gfx/ios/uikit_util.h"
12
13 namespace {
14 // Animation key used for frame animations.
15 NSString* const kFadeTruncatedLabelAnimationKey =
16 @"FadeTruncatedLabelAnimationKey";
17 }
18
19 @interface FadeTruncatedLabel () {
20 base::mac::ObjCPropertyReleaser _propertyReleaser_FadeTruncatedLabel;
21 }
22
23 // Layer used to apply fade truncation to label.
24 @property(nonatomic, retain) CAGradientLayer* maskLayer;
25
26 // Temporary label used during animations.
27 @property(nonatomic, retain) UILabel* animationLabel;
28
29 // Returns the percentage of the label's width at which to begin the fade
30 // gradient.
31 + (CGFloat)gradientPercentageForText:(NSString*)text
32 withAttributes:(NSDictionary*)attributes
33 inBounds:(CGRect)bounds;
34
35 @end
36
37 @implementation FadeTruncatedLabel
38
39 @synthesize maskLayer = _maskLayer;
40 @synthesize animationLabel = _animationLabel;
41
42 - (instancetype)initWithFrame:(CGRect)frame {
43 self = [super initWithFrame:frame];
44 if (self) {
45 // Initialize property releaser.
46 _propertyReleaser_FadeTruncatedLabel.Init(self, [FadeTruncatedLabel class]);
47
48 // Set background color and line break mode.
49 self.backgroundColor = [UIColor clearColor];
50 self.lineBreakMode = NSLineBreakByClipping;
51
52 // Instantiate |maskLayer| and add as mask.
53 self.maskLayer = [[self class] maskLayerForText:self.text
54 withAttributes:@{
55 NSFontAttributeName : self.font
56 }
57 inBounds:{CGPointZero, frame.size}];
58 self.layer.mask = self.maskLayer;
59 }
60 return self;
61 }
62
63 #pragma mark - UILabel overrides
64
65 - (void)drawTextInRect:(CGRect)rect {
66 // Draw if not animating.
67 if (!self.animationLabel)
68 [super drawTextInRect:rect];
69
70 // Update the mask gradient.
71 [CATransaction begin];
72 [CATransaction setDisableActions:YES];
73 self.maskLayer.frame = rect;
74 NSDictionary* fontAttributes = @{NSFontAttributeName : self.font};
75 CGFloat gradientBeginPercentage =
76 [[self class] gradientPercentageForText:self.text
77 withAttributes:fontAttributes
78 inBounds:self.maskLayer.bounds];
79 self.maskLayer.locations = @[ @(gradientBeginPercentage), @(1.0) ];
80 [CATransaction commit];
81 }
82
83 #pragma mark - Animations
84
85 - (void)animateFromBeginFrame:(CGRect)beginFrame
86 toEndFrame:(CGRect)endFrame
87 duration:(CFTimeInterval)duration
88 timingFunction:(CAMediaTimingFunction*)timingFunction {
89 CAAnimation* frameAnimation = nil;
90
91 // Animate the label.
92 frameAnimation = FrameAnimationMake(self.layer, beginFrame, endFrame);
93 frameAnimation.duration = duration;
94 frameAnimation.timingFunction = timingFunction;
95 [self.layer addAnimation:frameAnimation
96 forKey:kFadeTruncatedLabelAnimationKey];
97
98 // When animating, add a temporary label using the larger frame size so that
99 // truncation can occur via the gradient rather than by the edge of the text
100 // layer's backing store.
101 CGSize animationTextSize =
102 CGSizeMake(std::max(beginFrame.size.width, endFrame.size.width),
103 std::max(beginFrame.size.height, endFrame.size.height));
104 self.animationLabel = [[[UILabel alloc]
105 initWithFrame:{CGPointZero, animationTextSize}] autorelease];
106 self.animationLabel.text = self.text;
107 self.animationLabel.textColor = self.textColor;
108 self.animationLabel.font = self.font;
109 [self addSubview:self.animationLabel];
110
111 // Animate the mask layer.
112 CGRect beginBounds = {CGPointZero, beginFrame.size};
113 CGRect endBounds = {CGPointZero, endFrame.size};
114 frameAnimation = FrameAnimationMake(self.maskLayer, beginBounds, endBounds);
115 frameAnimation.duration = duration;
116 frameAnimation.timingFunction = timingFunction;
117 NSDictionary* attributes = @{NSFontAttributeName : self.font};
118 CGFloat beginGradientPercentage =
119 [[self class] gradientPercentageForText:self.text
120 withAttributes:attributes
121 inBounds:beginBounds];
122 CGFloat endGradientPercentage =
123 [[self class] gradientPercentageForText:self.text
124 withAttributes:attributes
125 inBounds:endBounds];
126 CABasicAnimation* gradientAnimation =
127 [CABasicAnimation animationWithKeyPath:@"locations"];
128 gradientAnimation.fromValue = @[ @(beginGradientPercentage), @(1.0) ];
129 gradientAnimation.toValue = @[ @(endGradientPercentage), @(1.0) ];
130 gradientAnimation.duration = duration;
131 gradientAnimation.timingFunction = timingFunction;
132 CAAnimation* animation =
133 AnimationGroupMake(@[ frameAnimation, gradientAnimation ]);
134 [self.maskLayer addAnimation:animation
135 forKey:kFadeTruncatedLabelAnimationKey];
136 }
137
138 - (void)reverseAnimations {
139 // Reverse the animations, but leave the animation label in place.
140 ReverseAnimationsForKeyForLayers(kFadeTruncatedLabelAnimationKey,
141 @[ self.layer, self.maskLayer ]);
142 }
143
144 - (void)cleanUpAnimations {
145 // Remove animation label and redraw.
146 [self.animationLabel removeFromSuperview];
147 self.animationLabel = nil;
148 [self setNeedsDisplay];
149 // Remove animations from layers.
150 RemoveAnimationForKeyFromLayers(kFadeTruncatedLabelAnimationKey,
151 @[ self.layer, self.maskLayer ]);
152 }
153
154 #pragma mark - Class methods
155
156 + (CGFloat)gradientPercentageForText:(NSString*)text
157 withAttributes:(NSDictionary*)attributes
158 inBounds:(CGRect)bounds {
159 CGSize textSize =
160 ui::AlignSizeToUpperPixel([text sizeWithAttributes:attributes]);
161 CGFloat gradientBeginPercentage = 1.0;
162 if (textSize.width > bounds.size.width) {
163 // Fade width is chosen to match GTMFadeTruncatingLabel.
164 CGFloat fadeWidth =
165 std::min<CGFloat>(bounds.size.height * 2, floor(bounds.size.width / 4));
166 gradientBeginPercentage =
167 (bounds.size.width - fadeWidth) / bounds.size.width;
168 }
169 return gradientBeginPercentage;
170 }
171
172 + (CAGradientLayer*)maskLayerForText:(NSString*)text
173 withAttributes:(NSDictionary*)attributes
174 inBounds:(CGRect)bounds {
175 CAGradientLayer* maskLayer = [CAGradientLayer layer];
176 maskLayer.bounds = bounds;
177 maskLayer.colors = @[
178 reinterpret_cast<id>([UIColor blackColor].CGColor),
179 reinterpret_cast<id>([UIColor clearColor].CGColor)
180 ];
181 maskLayer.startPoint = CGPointMake(0.0, 0.5);
182 maskLayer.endPoint = CGPointMake(1.0, 0.5);
183 CGFloat gradientBeginPercentage = [self gradientPercentageForText:text
184 withAttributes:attributes
185 inBounds:bounds];
186 maskLayer.locations = @[ @(gradientBeginPercentage), @(1.0) ];
187 return maskLayer;
188 }
189
190 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/fade_truncated_label.h ('k') | ios/chrome/browser/ui/fancy_ui/bidi_container_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698