OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 "ui/base/cocoa/window_animator.h" |
| 6 |
| 7 // Duration of show and hide animations. |
| 8 const NSTimeInterval kDefaultAnimationDuration = 0.2; |
| 9 |
| 10 @implementation WindowAnimationController |
| 11 |
| 12 @synthesize orderInDuration = orderInDuration_; |
| 13 @synthesize orderOutDuration = orderOutDuration_; |
| 14 |
| 15 - (id)init { |
| 16 if ((self = [super init])) { |
| 17 orderInDuration_ = kDefaultAnimationDuration; |
| 18 orderOutDuration_ = kDefaultAnimationDuration; |
| 19 } |
| 20 return self; |
| 21 } |
| 22 |
| 23 - (BOOL)isClosing { |
| 24 return !!window_; |
| 25 } |
| 26 |
| 27 - (void)animateWindow:(NSWindow*)window |
| 28 targetOrigin:(NSPoint)targetOrigin |
| 29 closing:(BOOL)closing |
| 30 callback:(const base::Closure&)callback { |
| 31 // First, stop the existing animation, if there is one. |
| 32 [animation_ stopAnimation]; |
| 33 |
| 34 callback_ = callback; |
| 35 |
| 36 NSRect targetFrame = [window frame]; |
| 37 targetFrame.origin = targetOrigin; |
| 38 |
| 39 // NSViewAnimation has a quirk when setting the curve to NSAnimationEaseOut |
| 40 // where it attempts to auto-reverse the animation. FadeOut becomes FadeIn |
| 41 // (good), but FrameKey is also switched (bad). So |targetFrame| needs to be |
| 42 // put on the StartFrameKey when using NSAnimationEaseOut for showing. |
| 43 NSArray* animationArray = @[ |
| 44 @{ |
| 45 NSViewAnimationTargetKey : window, |
| 46 NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect, |
| 47 (closing ? NSViewAnimationEndFrameKey : NSViewAnimationStartFrameKey) : |
| 48 [NSValue valueWithRect:targetFrame] |
| 49 } |
| 50 ]; |
| 51 animation_.reset( |
| 52 [[NSViewAnimation alloc] initWithViewAnimations:animationArray]); |
| 53 [animation_ setDelegate:self]; |
| 54 |
| 55 if (closing) { |
| 56 [animation_ setDuration:orderOutDuration_]; |
| 57 [animation_ setAnimationCurve:NSAnimationEaseIn]; |
| 58 window_.reset([window retain]); |
| 59 } else { |
| 60 [animation_ setDuration:orderInDuration_]; |
| 61 [window setAlphaValue:0.0f]; |
| 62 [animation_ setAnimationCurve:NSAnimationEaseOut]; |
| 63 window_.reset(); |
| 64 } |
| 65 // This once used a threaded animation, but AppKit would too often ignore |
| 66 // -[NSView canDrawConcurrently:] and just redraw whole view hierarchies on |
| 67 // the animation thread anyway, creating a minefield of race conditions. |
| 68 // Non-threaded means the animation isn't as smooth and doesn't begin unless |
| 69 // the UI runloop has spun up (after profile loading). |
| 70 [animation_ setAnimationBlockingMode:NSAnimationNonblocking]; |
| 71 |
| 72 [animation_ startAnimation]; |
| 73 } |
| 74 |
| 75 - (void)cancelAnimationWithCallback { |
| 76 // Note: |animation_| can be nil, and this all turns into a no-op. |
| 77 [animation_ stopAnimation]; |
| 78 [self animationDidEnd:animation_]; |
| 79 } |
| 80 |
| 81 - (void)animationDidEnd:(NSAnimation*)animation { |
| 82 [window_ close]; |
| 83 window_.reset(); |
| 84 animation_.reset(); |
| 85 |
| 86 if (!callback_.is_null()) { |
| 87 callback_.Run(); |
| 88 callback_.Reset(); |
| 89 } |
| 90 } |
| 91 |
| 92 @end |
OLD | NEW |