| Index: ui/base/cocoa/window_animator.mm
|
| diff --git a/ui/base/cocoa/window_animator.mm b/ui/base/cocoa/window_animator.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ee390f7610db1448dea83c2a346999d60f99f81f
|
| --- /dev/null
|
| +++ b/ui/base/cocoa/window_animator.mm
|
| @@ -0,0 +1,92 @@
|
| +// Copyright 2015 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 "ui/base/cocoa/window_animator.h"
|
| +
|
| +// Duration of show and hide animations.
|
| +const NSTimeInterval kDefaultAnimationDuration = 0.2;
|
| +
|
| +@implementation WindowAnimationController
|
| +
|
| +@synthesize orderInDuration = orderInDuration_;
|
| +@synthesize orderOutDuration = orderOutDuration_;
|
| +
|
| +- (id)init {
|
| + if ((self = [super init])) {
|
| + orderInDuration_ = kDefaultAnimationDuration;
|
| + orderOutDuration_ = kDefaultAnimationDuration;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (BOOL)isClosing {
|
| + return !!window_;
|
| +}
|
| +
|
| +- (void)animateWindow:(NSWindow*)window
|
| + targetOrigin:(NSPoint)targetOrigin
|
| + closing:(BOOL)closing
|
| + callback:(const base::Closure&)callback {
|
| + // First, stop the existing animation, if there is one.
|
| + [animation_ stopAnimation];
|
| +
|
| + callback_ = callback;
|
| +
|
| + NSRect targetFrame = [window frame];
|
| + targetFrame.origin = targetOrigin;
|
| +
|
| + // NSViewAnimation has a quirk when setting the curve to NSAnimationEaseOut
|
| + // where it attempts to auto-reverse the animation. FadeOut becomes FadeIn
|
| + // (good), but FrameKey is also switched (bad). So |targetFrame| needs to be
|
| + // put on the StartFrameKey when using NSAnimationEaseOut for showing.
|
| + NSArray* animationArray = @[
|
| + @{
|
| + NSViewAnimationTargetKey : window,
|
| + NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect,
|
| + (closing ? NSViewAnimationEndFrameKey : NSViewAnimationStartFrameKey) :
|
| + [NSValue valueWithRect:targetFrame]
|
| + }
|
| + ];
|
| + animation_.reset(
|
| + [[NSViewAnimation alloc] initWithViewAnimations:animationArray]);
|
| + [animation_ setDelegate:self];
|
| +
|
| + if (closing) {
|
| + [animation_ setDuration:orderOutDuration_];
|
| + [animation_ setAnimationCurve:NSAnimationEaseIn];
|
| + window_.reset([window retain]);
|
| + } else {
|
| + [animation_ setDuration:orderInDuration_];
|
| + [window setAlphaValue:0.0f];
|
| + [animation_ setAnimationCurve:NSAnimationEaseOut];
|
| + window_.reset();
|
| + }
|
| + // This once used a threaded animation, but AppKit would too often ignore
|
| + // -[NSView canDrawConcurrently:] and just redraw whole view hierarchies on
|
| + // the animation thread anyway, creating a minefield of race conditions.
|
| + // Non-threaded means the animation isn't as smooth and doesn't begin unless
|
| + // the UI runloop has spun up (after profile loading).
|
| + [animation_ setAnimationBlockingMode:NSAnimationNonblocking];
|
| +
|
| + [animation_ startAnimation];
|
| +}
|
| +
|
| +- (void)cancelAnimationWithCallback {
|
| + // Note: |animation_| can be nil, and this all turns into a no-op.
|
| + [animation_ stopAnimation];
|
| + [self animationDidEnd:animation_];
|
| +}
|
| +
|
| +- (void)animationDidEnd:(NSAnimation*)animation {
|
| + [window_ close];
|
| + window_.reset();
|
| + animation_.reset();
|
| +
|
| + if (!callback_.is_null()) {
|
| + callback_.Run();
|
| + callback_.Reset();
|
| + }
|
| +}
|
| +
|
| +@end
|
|
|