| Index: chrome/browser/ui/cocoa/info_bubble_window.mm
|
| diff --git a/chrome/browser/ui/cocoa/info_bubble_window.mm b/chrome/browser/ui/cocoa/info_bubble_window.mm
|
| index d4bff5d45190efbf3a0aea9cc8eb5ba57c9c39e5..b334baab2ce5bf6456865abb1baac01a024ea13d 100644
|
| --- a/chrome/browser/ui/cocoa/info_bubble_window.mm
|
| +++ b/chrome/browser/ui/cocoa/info_bubble_window.mm
|
| @@ -12,21 +12,16 @@
|
| #include "content/public/browser/notification_registrar.h"
|
| #include "content/public/browser/notification_service.h"
|
| #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
|
| +#import "ui/base/cocoa/window_animator.h"
|
|
|
| namespace {
|
| const CGFloat kOrderInSlideOffset = 10;
|
| const NSTimeInterval kOrderInAnimationDuration = 0.075;
|
| const NSTimeInterval kOrderOutAnimationDuration = 0.15;
|
| -// The minimum representable time interval. This can be used as the value
|
| -// passed to +[NSAnimationContext setDuration:] to stop an in-progress
|
| -// animation as quickly as possible.
|
| -const NSTimeInterval kMinimumTimeInterval =
|
| - std::numeric_limits<NSTimeInterval>::min();
|
| } // namespace
|
|
|
| @interface InfoBubbleWindow (Private)
|
| - (void)appIsTerminating;
|
| -- (void)finishCloseAfterAnimation;
|
| @end
|
|
|
| // A helper class to proxy app notifications to the window.
|
| @@ -60,37 +55,6 @@ class AppNotificationBridge : public content::NotificationObserver {
|
| DISALLOW_COPY_AND_ASSIGN(AppNotificationBridge);
|
| };
|
|
|
| -// A delegate object for watching the alphaValue animation on InfoBubbleWindows.
|
| -// An InfoBubbleWindow instance cannot be the delegate for its own animation
|
| -// because CAAnimations retain their delegates, and since the InfoBubbleWindow
|
| -// retains its animations a retain loop would be formed.
|
| -@interface InfoBubbleWindowCloser : NSObject {
|
| - @private
|
| - InfoBubbleWindow* window_; // Weak. Window to close.
|
| -}
|
| -- (id)initWithWindow:(InfoBubbleWindow*)window;
|
| -@end
|
| -
|
| -@implementation InfoBubbleWindowCloser
|
| -
|
| -- (id)initWithWindow:(InfoBubbleWindow*)window {
|
| - if ((self = [super init])) {
|
| - window_ = window;
|
| - }
|
| - return self;
|
| -}
|
| -
|
| -// Callback for the alpha animation. Closes window_ if appropriate.
|
| -- (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag {
|
| - // When alpha reaches zero, close window_.
|
| - if ([window_ alphaValue] == 0.0) {
|
| - [window_ finishCloseAfterAnimation];
|
| - }
|
| -}
|
| -
|
| -@end
|
| -
|
| -
|
| @implementation InfoBubbleWindow
|
|
|
| @synthesize allowedAnimations = allowedAnimations_;
|
| @@ -118,19 +82,9 @@ class AppNotificationBridge : public content::NotificationObserver {
|
| // Start invisible. Will be made visible when ordered front.
|
| [self setAlphaValue:0.0];
|
|
|
| - // Set up alphaValue animation so that self is delegate for the animation.
|
| - // Setting up the delegate is required so that the
|
| - // animationDidStop:finished: callback can be handled.
|
| - // Notice that only the alphaValue Animation is replaced in case
|
| - // superclasses set up animations.
|
| - CAAnimation* alphaAnimation = [CABasicAnimation animation];
|
| - base::scoped_nsobject<InfoBubbleWindowCloser> delegate(
|
| - [[InfoBubbleWindowCloser alloc] initWithWindow:self]);
|
| - [alphaAnimation setDelegate:delegate];
|
| - NSMutableDictionary* animations =
|
| - [NSMutableDictionary dictionaryWithDictionary:[self animations]];
|
| - [animations setObject:alphaAnimation forKey:@"alphaValue"];
|
| - [self setAnimations:animations];
|
| + animation_controller_.reset([[WindowAnimationController alloc] init]);
|
| + [animation_controller_ setOrderInDuration:kOrderInAnimationDuration];
|
| + [animation_controller_ setOrderOutDuration:kOrderOutAnimationDuration];
|
| }
|
| return self;
|
| }
|
| @@ -150,43 +104,24 @@ class AppNotificationBridge : public content::NotificationObserver {
|
| return allowShareParentKeyState_;
|
| }
|
|
|
| -- (void)close {
|
| - // Block the window from receiving events while it fades out.
|
| - closing_ = YES;
|
| -
|
| +- (void)animateClose {
|
| if ((allowedAnimations_ & info_bubble::kAnimateOrderOut) == 0) {
|
| - [self finishCloseAfterAnimation];
|
| - } else {
|
| - // Apply animations to hide self.
|
| - [NSAnimationContext beginGrouping];
|
| - [[NSAnimationContext currentContext]
|
| - gtm_setDuration:kOrderOutAnimationDuration
|
| - eventMask:NSLeftMouseUpMask];
|
| - [[self animator] setAlphaValue:0.0];
|
| - [NSAnimationContext endGrouping];
|
| + [self close];
|
| + return;
|
| }
|
| +
|
| + // Fade out in place and close.
|
| + [animation_controller_ animateWindow:self
|
| + targetOrigin:[self frame].origin
|
| + closing:YES
|
| + callback:base::Closure()];
|
| }
|
|
|
| // If the app is terminating but the window is still fading out, cancel the
|
| // animation and close the window to prevent it from leaking.
|
| // See http://crbug.com/37717
|
| - (void)appIsTerminating {
|
| - if ((allowedAnimations_ & info_bubble::kAnimateOrderOut) == 0)
|
| - return; // The close has already happened with no Core Animation.
|
| -
|
| - // Cancel the current animation so that it closes immediately, triggering
|
| - // |finishCloseAfterAnimation|.
|
| - [NSAnimationContext beginGrouping];
|
| - [[NSAnimationContext currentContext] setDuration:kMinimumTimeInterval];
|
| - [[self animator] setAlphaValue:0.0];
|
| - [NSAnimationContext endGrouping];
|
| -}
|
| -
|
| -// Called by InfoBubbleWindowCloser when the window is to be really closed
|
| -// after the fading animation is complete.
|
| -- (void)finishCloseAfterAnimation {
|
| - if (closing_)
|
| - [super close];
|
| + [animation_controller_ cancelAnimationWithCallback];
|
| }
|
|
|
| // Adds animation for info bubbles being ordered to the front.
|
| @@ -205,18 +140,10 @@ class AppNotificationBridge : public content::NotificationObserver {
|
| newOrigin.y += kOrderInSlideOffset;
|
| [self setFrameOrigin:newOrigin];
|
|
|
| - // Apply animations to show and move self.
|
| - [NSAnimationContext beginGrouping];
|
| - // The star currently triggers on mouse down, not mouse up.
|
| - NSTimeInterval duration =
|
| - (allowedAnimations_ & info_bubble::kAnimateOrderIn)
|
| - ? kOrderInAnimationDuration : kMinimumTimeInterval;
|
| - [[NSAnimationContext currentContext]
|
| - gtm_setDuration:duration
|
| - eventMask:NSLeftMouseUpMask | NSLeftMouseDownMask];
|
| - [[self animator] setAlphaValue:1.0];
|
| - [[self animator] setFrame:frame display:YES];
|
| - [NSAnimationContext endGrouping];
|
| + [animation_controller_ animateWindow:self
|
| + targetOrigin:frame.origin
|
| + closing:NO
|
| + callback:base::Closure()];
|
| } else {
|
| [super orderWindow:orderingMode relativeTo:otherWindowNumber];
|
| }
|
| @@ -225,12 +152,12 @@ class AppNotificationBridge : public content::NotificationObserver {
|
| // If the window is currently animating a close, block all UI events to the
|
| // window.
|
| - (void)sendEvent:(NSEvent*)theEvent {
|
| - if (!closing_)
|
| + if (![self isClosing])
|
| [super sendEvent:theEvent];
|
| }
|
|
|
| - (BOOL)isClosing {
|
| - return closing_;
|
| + return [animation_controller_ isClosing];
|
| }
|
|
|
| @end
|
|
|