OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 <Cocoa/Cocoa.h> |
| 6 #import <QuartzCore/QuartzCore.h> |
| 7 |
| 8 #import "chrome/browser/cocoa/animatable_view.h" |
| 9 |
| 10 // NSAnimation subclass that animates the height of an AnimatableView. Allows |
| 11 // the caller to start and cancel the animation as desired. |
| 12 @interface NSHeightAnimation : NSAnimation { |
| 13 @private |
| 14 AnimatableView* view_; // weak, owns us. |
| 15 CGFloat startHeight_; |
| 16 CGFloat endHeight_; |
| 17 } |
| 18 |
| 19 // Initialize a new height animation for the given view. The animation will not |
| 20 // start until startAnimation: is called. |
| 21 - (id)initWithView:(AnimatableView*)view |
| 22 finalHeight:(CGFloat)height |
| 23 duration:(NSTimeInterval)duration; |
| 24 @end |
| 25 |
| 26 @implementation NSHeightAnimation |
| 27 - (id)initWithView:(AnimatableView*)view |
| 28 finalHeight:(CGFloat)height |
| 29 duration:(NSTimeInterval)duration { |
| 30 if ((self = [super initWithDuration:duration |
| 31 animationCurve:NSAnimationEaseIn])) { |
| 32 view_ = view; |
| 33 startHeight_ = [view_ height]; |
| 34 endHeight_ = height; |
| 35 [self setAnimationBlockingMode:NSAnimationNonblocking]; |
| 36 [self setDelegate:view_]; |
| 37 } |
| 38 return self; |
| 39 } |
| 40 |
| 41 // Overridden to call setHeight for each progress tick. |
| 42 - (void)setCurrentProgress:(NSAnimationProgress)progress { |
| 43 [super setCurrentProgress:progress]; |
| 44 [view_ setHeight:((progress * (endHeight_ - startHeight_)) + startHeight_)]; |
| 45 } |
| 46 @end |
| 47 |
| 48 |
| 49 @implementation AnimatableView |
| 50 @synthesize delegate = delegate_; |
| 51 |
| 52 - (void)dealloc { |
| 53 // Stop the animation if it is running, since it holds a pointer to this view. |
| 54 [self stopAnimation]; |
| 55 [super dealloc]; |
| 56 } |
| 57 |
| 58 - (CGFloat)height { |
| 59 return [self frame].size.height; |
| 60 } |
| 61 |
| 62 - (void)setHeight:(CGFloat)newHeight { |
| 63 // Force the height to be an integer because some animations look terrible |
| 64 // with non-integer intermediate heights. We only ever set integer heights |
| 65 // for our views, so this shouldn't be a limitation in practice. |
| 66 int height = floor(newHeight); |
| 67 [resizeDelegate_ resizeView:self newHeight:height]; |
| 68 } |
| 69 |
| 70 - (void)animateToNewHeight:(CGFloat)newHeight |
| 71 duration:(NSTimeInterval)duration { |
| 72 [currentAnimation_ stopAnimation]; |
| 73 |
| 74 currentAnimation_.reset([[NSHeightAnimation alloc] initWithView:self |
| 75 finalHeight:newHeight |
| 76 duration:duration]); |
| 77 [currentAnimation_ startAnimation]; |
| 78 } |
| 79 |
| 80 - (void)stopAnimation { |
| 81 [currentAnimation_ stopAnimation]; |
| 82 } |
| 83 |
| 84 - (void)setResizeDelegate:(id<ViewResizer>)resizeDelegate { |
| 85 resizeDelegate_ = resizeDelegate; |
| 86 } |
| 87 |
| 88 - (void)animationDidStop:(NSAnimation*)animation { |
| 89 if ([delegate_ respondsToSelector:@selector(animationDidStop:)]) |
| 90 [delegate_ animationDidStop:animation]; |
| 91 currentAnimation_.reset(nil); |
| 92 } |
| 93 |
| 94 - (void)animationDidEnd:(NSAnimation*)animation { |
| 95 if ([delegate_ respondsToSelector:@selector(animationDidEnd:)]) |
| 96 [delegate_ animationDidEnd:animation]; |
| 97 currentAnimation_.reset(nil); |
| 98 } |
| 99 |
| 100 @end |
OLD | NEW |