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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/chrome/browser/ui/fade_truncated_label.mm
diff --git a/ios/chrome/browser/ui/fade_truncated_label.mm b/ios/chrome/browser/ui/fade_truncated_label.mm
new file mode 100644
index 0000000000000000000000000000000000000000..8aa4d7da478e54673e0707afc929259c1aa844aa
--- /dev/null
+++ b/ios/chrome/browser/ui/fade_truncated_label.mm
@@ -0,0 +1,190 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/fade_truncated_label.h"
+
+#include <algorithm>
+#include "base/mac/objc_property_releaser.h"
+#import "ios/chrome/browser/ui/animation_util.h"
+#import "ios/chrome/browser/ui/reversed_animation.h"
+#import "ui/gfx/ios/uikit_util.h"
+
+namespace {
+// Animation key used for frame animations.
+NSString* const kFadeTruncatedLabelAnimationKey =
+ @"FadeTruncatedLabelAnimationKey";
+}
+
+@interface FadeTruncatedLabel () {
+ base::mac::ObjCPropertyReleaser _propertyReleaser_FadeTruncatedLabel;
+}
+
+// Layer used to apply fade truncation to label.
+@property(nonatomic, retain) CAGradientLayer* maskLayer;
+
+// Temporary label used during animations.
+@property(nonatomic, retain) UILabel* animationLabel;
+
+// Returns the percentage of the label's width at which to begin the fade
+// gradient.
++ (CGFloat)gradientPercentageForText:(NSString*)text
+ withAttributes:(NSDictionary*)attributes
+ inBounds:(CGRect)bounds;
+
+@end
+
+@implementation FadeTruncatedLabel
+
+@synthesize maskLayer = _maskLayer;
+@synthesize animationLabel = _animationLabel;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ // Initialize property releaser.
+ _propertyReleaser_FadeTruncatedLabel.Init(self, [FadeTruncatedLabel class]);
+
+ // Set background color and line break mode.
+ self.backgroundColor = [UIColor clearColor];
+ self.lineBreakMode = NSLineBreakByClipping;
+
+ // Instantiate |maskLayer| and add as mask.
+ self.maskLayer = [[self class] maskLayerForText:self.text
+ withAttributes:@{
+ NSFontAttributeName : self.font
+ }
+ inBounds:{CGPointZero, frame.size}];
+ self.layer.mask = self.maskLayer;
+ }
+ return self;
+}
+
+#pragma mark - UILabel overrides
+
+- (void)drawTextInRect:(CGRect)rect {
+ // Draw if not animating.
+ if (!self.animationLabel)
+ [super drawTextInRect:rect];
+
+ // Update the mask gradient.
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ self.maskLayer.frame = rect;
+ NSDictionary* fontAttributes = @{NSFontAttributeName : self.font};
+ CGFloat gradientBeginPercentage =
+ [[self class] gradientPercentageForText:self.text
+ withAttributes:fontAttributes
+ inBounds:self.maskLayer.bounds];
+ self.maskLayer.locations = @[ @(gradientBeginPercentage), @(1.0) ];
+ [CATransaction commit];
+}
+
+#pragma mark - Animations
+
+- (void)animateFromBeginFrame:(CGRect)beginFrame
+ toEndFrame:(CGRect)endFrame
+ duration:(CFTimeInterval)duration
+ timingFunction:(CAMediaTimingFunction*)timingFunction {
+ CAAnimation* frameAnimation = nil;
+
+ // Animate the label.
+ frameAnimation = FrameAnimationMake(self.layer, beginFrame, endFrame);
+ frameAnimation.duration = duration;
+ frameAnimation.timingFunction = timingFunction;
+ [self.layer addAnimation:frameAnimation
+ forKey:kFadeTruncatedLabelAnimationKey];
+
+ // When animating, add a temporary label using the larger frame size so that
+ // truncation can occur via the gradient rather than by the edge of the text
+ // layer's backing store.
+ CGSize animationTextSize =
+ CGSizeMake(std::max(beginFrame.size.width, endFrame.size.width),
+ std::max(beginFrame.size.height, endFrame.size.height));
+ self.animationLabel = [[[UILabel alloc]
+ initWithFrame:{CGPointZero, animationTextSize}] autorelease];
+ self.animationLabel.text = self.text;
+ self.animationLabel.textColor = self.textColor;
+ self.animationLabel.font = self.font;
+ [self addSubview:self.animationLabel];
+
+ // Animate the mask layer.
+ CGRect beginBounds = {CGPointZero, beginFrame.size};
+ CGRect endBounds = {CGPointZero, endFrame.size};
+ frameAnimation = FrameAnimationMake(self.maskLayer, beginBounds, endBounds);
+ frameAnimation.duration = duration;
+ frameAnimation.timingFunction = timingFunction;
+ NSDictionary* attributes = @{NSFontAttributeName : self.font};
+ CGFloat beginGradientPercentage =
+ [[self class] gradientPercentageForText:self.text
+ withAttributes:attributes
+ inBounds:beginBounds];
+ CGFloat endGradientPercentage =
+ [[self class] gradientPercentageForText:self.text
+ withAttributes:attributes
+ inBounds:endBounds];
+ CABasicAnimation* gradientAnimation =
+ [CABasicAnimation animationWithKeyPath:@"locations"];
+ gradientAnimation.fromValue = @[ @(beginGradientPercentage), @(1.0) ];
+ gradientAnimation.toValue = @[ @(endGradientPercentage), @(1.0) ];
+ gradientAnimation.duration = duration;
+ gradientAnimation.timingFunction = timingFunction;
+ CAAnimation* animation =
+ AnimationGroupMake(@[ frameAnimation, gradientAnimation ]);
+ [self.maskLayer addAnimation:animation
+ forKey:kFadeTruncatedLabelAnimationKey];
+}
+
+- (void)reverseAnimations {
+ // Reverse the animations, but leave the animation label in place.
+ ReverseAnimationsForKeyForLayers(kFadeTruncatedLabelAnimationKey,
+ @[ self.layer, self.maskLayer ]);
+}
+
+- (void)cleanUpAnimations {
+ // Remove animation label and redraw.
+ [self.animationLabel removeFromSuperview];
+ self.animationLabel = nil;
+ [self setNeedsDisplay];
+ // Remove animations from layers.
+ RemoveAnimationForKeyFromLayers(kFadeTruncatedLabelAnimationKey,
+ @[ self.layer, self.maskLayer ]);
+}
+
+#pragma mark - Class methods
+
++ (CGFloat)gradientPercentageForText:(NSString*)text
+ withAttributes:(NSDictionary*)attributes
+ inBounds:(CGRect)bounds {
+ CGSize textSize =
+ ui::AlignSizeToUpperPixel([text sizeWithAttributes:attributes]);
+ CGFloat gradientBeginPercentage = 1.0;
+ if (textSize.width > bounds.size.width) {
+ // Fade width is chosen to match GTMFadeTruncatingLabel.
+ CGFloat fadeWidth =
+ std::min<CGFloat>(bounds.size.height * 2, floor(bounds.size.width / 4));
+ gradientBeginPercentage =
+ (bounds.size.width - fadeWidth) / bounds.size.width;
+ }
+ return gradientBeginPercentage;
+}
+
++ (CAGradientLayer*)maskLayerForText:(NSString*)text
+ withAttributes:(NSDictionary*)attributes
+ inBounds:(CGRect)bounds {
+ CAGradientLayer* maskLayer = [CAGradientLayer layer];
+ maskLayer.bounds = bounds;
+ maskLayer.colors = @[
+ reinterpret_cast<id>([UIColor blackColor].CGColor),
+ reinterpret_cast<id>([UIColor clearColor].CGColor)
+ ];
+ maskLayer.startPoint = CGPointMake(0.0, 0.5);
+ maskLayer.endPoint = CGPointMake(1.0, 0.5);
+ CGFloat gradientBeginPercentage = [self gradientPercentageForText:text
+ withAttributes:attributes
+ inBounds:bounds];
+ maskLayer.locations = @[ @(gradientBeginPercentage), @(1.0) ];
+ return maskLayer;
+}
+
+@end
« 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