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

Side by Side Diff: chrome/browser/ui/cocoa/info_bubble_window.mm

Issue 952793002: Mac: Make ui/base/cocoa WindowAnimator Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git add Created 5 years, 9 months 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/info_bubble_window.h ('k') | ui/base/cocoa/window_animator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/info_bubble_window.h" 5 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/mac/scoped_nsobject.h" 9 #include "base/mac/scoped_nsobject.h"
10 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/chrome_notification_types.h"
11 #include "content/public/browser/notification_observer.h" 11 #include "content/public/browser/notification_observer.h"
12 #include "content/public/browser/notification_registrar.h" 12 #include "content/public/browser/notification_registrar.h"
13 #include "content/public/browser/notification_service.h" 13 #include "content/public/browser/notification_service.h"
14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h " 14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h "
15 #import "ui/base/cocoa/window_animator.h"
15 16
16 namespace { 17 namespace {
17 const CGFloat kOrderInSlideOffset = 10; 18 const CGFloat kOrderInSlideOffset = 10;
18 const NSTimeInterval kOrderInAnimationDuration = 0.075; 19 const NSTimeInterval kOrderInAnimationDuration = 0.075;
19 const NSTimeInterval kOrderOutAnimationDuration = 0.15; 20 const NSTimeInterval kOrderOutAnimationDuration = 0.15;
20 // The minimum representable time interval. This can be used as the value
21 // passed to +[NSAnimationContext setDuration:] to stop an in-progress
22 // animation as quickly as possible.
23 const NSTimeInterval kMinimumTimeInterval =
24 std::numeric_limits<NSTimeInterval>::min();
25 } // namespace 21 } // namespace
26 22
27 @interface InfoBubbleWindow (Private) 23 @interface InfoBubbleWindow (Private)
28 - (void)appIsTerminating; 24 - (void)appIsTerminating;
29 - (void)finishCloseAfterAnimation;
30 @end 25 @end
31 26
32 // A helper class to proxy app notifications to the window. 27 // A helper class to proxy app notifications to the window.
33 class AppNotificationBridge : public content::NotificationObserver { 28 class AppNotificationBridge : public content::NotificationObserver {
34 public: 29 public:
35 explicit AppNotificationBridge(InfoBubbleWindow* owner) : owner_(owner) { 30 explicit AppNotificationBridge(InfoBubbleWindow* owner) : owner_(owner) {
36 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 31 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
37 content::NotificationService::AllSources()); 32 content::NotificationService::AllSources());
38 } 33 }
39 34
(...skipping 13 matching lines...) Expand all
53 private: 48 private:
54 // The object we need to inform when we get a notification. Weak. Owns us. 49 // The object we need to inform when we get a notification. Weak. Owns us.
55 InfoBubbleWindow* owner_; 50 InfoBubbleWindow* owner_;
56 51
57 // Used for registering to receive notifications and automatic clean up. 52 // Used for registering to receive notifications and automatic clean up.
58 content::NotificationRegistrar registrar_; 53 content::NotificationRegistrar registrar_;
59 54
60 DISALLOW_COPY_AND_ASSIGN(AppNotificationBridge); 55 DISALLOW_COPY_AND_ASSIGN(AppNotificationBridge);
61 }; 56 };
62 57
63 // A delegate object for watching the alphaValue animation on InfoBubbleWindows.
64 // An InfoBubbleWindow instance cannot be the delegate for its own animation
65 // because CAAnimations retain their delegates, and since the InfoBubbleWindow
66 // retains its animations a retain loop would be formed.
67 @interface InfoBubbleWindowCloser : NSObject {
68 @private
69 InfoBubbleWindow* window_; // Weak. Window to close.
70 }
71 - (id)initWithWindow:(InfoBubbleWindow*)window;
72 @end
73
74 @implementation InfoBubbleWindowCloser
75
76 - (id)initWithWindow:(InfoBubbleWindow*)window {
77 if ((self = [super init])) {
78 window_ = window;
79 }
80 return self;
81 }
82
83 // Callback for the alpha animation. Closes window_ if appropriate.
84 - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag {
85 // When alpha reaches zero, close window_.
86 if ([window_ alphaValue] == 0.0) {
87 [window_ finishCloseAfterAnimation];
88 }
89 }
90
91 @end
92
93
94 @implementation InfoBubbleWindow 58 @implementation InfoBubbleWindow
95 59
96 @synthesize allowedAnimations = allowedAnimations_; 60 @synthesize allowedAnimations = allowedAnimations_;
97 @synthesize canBecomeKeyWindow = canBecomeKeyWindow_; 61 @synthesize canBecomeKeyWindow = canBecomeKeyWindow_;
98 @synthesize allowShareParentKeyState = allowShareParentKeyState_; 62 @synthesize allowShareParentKeyState = allowShareParentKeyState_;
99 63
100 - (id)initWithContentRect:(NSRect)contentRect 64 - (id)initWithContentRect:(NSRect)contentRect
101 styleMask:(NSUInteger)aStyle 65 styleMask:(NSUInteger)aStyle
102 backing:(NSBackingStoreType)bufferingType 66 backing:(NSBackingStoreType)bufferingType
103 defer:(BOOL)flag { 67 defer:(BOOL)flag {
104 if ((self = [super initWithContentRect:contentRect 68 if ((self = [super initWithContentRect:contentRect
105 styleMask:NSBorderlessWindowMask 69 styleMask:NSBorderlessWindowMask
106 backing:bufferingType 70 backing:bufferingType
107 defer:flag])) { 71 defer:flag])) {
108 [self setBackgroundColor:[NSColor clearColor]]; 72 [self setBackgroundColor:[NSColor clearColor]];
109 [self setExcludedFromWindowsMenu:YES]; 73 [self setExcludedFromWindowsMenu:YES];
110 [self setAllowShareParentKeyState:YES]; 74 [self setAllowShareParentKeyState:YES];
111 [self setOpaque:NO]; 75 [self setOpaque:NO];
112 [self setHasShadow:YES]; 76 [self setHasShadow:YES];
113 canBecomeKeyWindow_ = YES; 77 canBecomeKeyWindow_ = YES;
114 allowedAnimations_ = info_bubble::kAnimateOrderIn | 78 allowedAnimations_ = info_bubble::kAnimateOrderIn |
115 info_bubble::kAnimateOrderOut; 79 info_bubble::kAnimateOrderOut;
116 notificationBridge_.reset(new AppNotificationBridge(self)); 80 notificationBridge_.reset(new AppNotificationBridge(self));
117 81
118 // Start invisible. Will be made visible when ordered front. 82 // Start invisible. Will be made visible when ordered front.
119 [self setAlphaValue:0.0]; 83 [self setAlphaValue:0.0];
120 84
121 // Set up alphaValue animation so that self is delegate for the animation. 85 animation_controller_.reset([[WindowAnimationController alloc] init]);
122 // Setting up the delegate is required so that the 86 [animation_controller_ setOrderInDuration:kOrderInAnimationDuration];
123 // animationDidStop:finished: callback can be handled. 87 [animation_controller_ setOrderOutDuration:kOrderOutAnimationDuration];
124 // Notice that only the alphaValue Animation is replaced in case
125 // superclasses set up animations.
126 CAAnimation* alphaAnimation = [CABasicAnimation animation];
127 base::scoped_nsobject<InfoBubbleWindowCloser> delegate(
128 [[InfoBubbleWindowCloser alloc] initWithWindow:self]);
129 [alphaAnimation setDelegate:delegate];
130 NSMutableDictionary* animations =
131 [NSMutableDictionary dictionaryWithDictionary:[self animations]];
132 [animations setObject:alphaAnimation forKey:@"alphaValue"];
133 [self setAnimations:animations];
134 } 88 }
135 return self; 89 return self;
136 } 90 }
137 91
138 // According to 92 // According to
139 // http://www.cocoabuilder.com/archive/message/cocoa/2006/6/19/165953, 93 // http://www.cocoabuilder.com/archive/message/cocoa/2006/6/19/165953,
140 // NSBorderlessWindowMask windows cannot become key or main. In this 94 // NSBorderlessWindowMask windows cannot become key or main. In this
141 // case, this is not necessarily a desired behavior. As an example, the 95 // case, this is not necessarily a desired behavior. As an example, the
142 // bubble could have buttons. 96 // bubble could have buttons.
143 - (BOOL)canBecomeKeyWindow { 97 - (BOOL)canBecomeKeyWindow {
144 return canBecomeKeyWindow_; 98 return canBecomeKeyWindow_;
145 } 99 }
146 100
147 // Lets the traffic light buttons on the browser window keep their "active" 101 // Lets the traffic light buttons on the browser window keep their "active"
148 // state while an info bubble is open. Only has an effect on 10.7. 102 // state while an info bubble is open. Only has an effect on 10.7.
149 - (BOOL)_sharesParentKeyState { 103 - (BOOL)_sharesParentKeyState {
150 return allowShareParentKeyState_; 104 return allowShareParentKeyState_;
151 } 105 }
152 106
153 - (void)close { 107 - (void)animateClose {
154 // Block the window from receiving events while it fades out. 108 if ((allowedAnimations_ & info_bubble::kAnimateOrderOut) == 0) {
155 closing_ = YES; 109 [self close];
110 return;
111 }
156 112
157 if ((allowedAnimations_ & info_bubble::kAnimateOrderOut) == 0) { 113 // Fade out in place and close.
158 [self finishCloseAfterAnimation]; 114 [animation_controller_ animateWindow:self
159 } else { 115 targetOrigin:[self frame].origin
160 // Apply animations to hide self. 116 closing:YES
161 [NSAnimationContext beginGrouping]; 117 callback:base::Closure()];
162 [[NSAnimationContext currentContext]
163 gtm_setDuration:kOrderOutAnimationDuration
164 eventMask:NSLeftMouseUpMask];
165 [[self animator] setAlphaValue:0.0];
166 [NSAnimationContext endGrouping];
167 }
168 } 118 }
169 119
170 // If the app is terminating but the window is still fading out, cancel the 120 // If the app is terminating but the window is still fading out, cancel the
171 // animation and close the window to prevent it from leaking. 121 // animation and close the window to prevent it from leaking.
172 // See http://crbug.com/37717 122 // See http://crbug.com/37717
173 - (void)appIsTerminating { 123 - (void)appIsTerminating {
174 if ((allowedAnimations_ & info_bubble::kAnimateOrderOut) == 0) 124 [animation_controller_ cancelAnimationWithCallback];
175 return; // The close has already happened with no Core Animation.
176
177 // Cancel the current animation so that it closes immediately, triggering
178 // |finishCloseAfterAnimation|.
179 [NSAnimationContext beginGrouping];
180 [[NSAnimationContext currentContext] setDuration:kMinimumTimeInterval];
181 [[self animator] setAlphaValue:0.0];
182 [NSAnimationContext endGrouping];
183 }
184
185 // Called by InfoBubbleWindowCloser when the window is to be really closed
186 // after the fading animation is complete.
187 - (void)finishCloseAfterAnimation {
188 if (closing_)
189 [super close];
190 } 125 }
191 126
192 // Adds animation for info bubbles being ordered to the front. 127 // Adds animation for info bubbles being ordered to the front.
193 - (void)orderWindow:(NSWindowOrderingMode)orderingMode 128 - (void)orderWindow:(NSWindowOrderingMode)orderingMode
194 relativeTo:(NSInteger)otherWindowNumber { 129 relativeTo:(NSInteger)otherWindowNumber {
195 // According to the documentation '0' is the otherWindowNumber when the window 130 // According to the documentation '0' is the otherWindowNumber when the window
196 // is ordered front. 131 // is ordered front.
197 if (orderingMode == NSWindowAbove && otherWindowNumber == 0) { 132 if (orderingMode == NSWindowAbove && otherWindowNumber == 0) {
198 // Order self appropriately assuming that its alpha is zero as set up 133 // Order self appropriately assuming that its alpha is zero as set up
199 // in the designated initializer. 134 // in the designated initializer.
200 [super orderWindow:orderingMode relativeTo:otherWindowNumber]; 135 [super orderWindow:orderingMode relativeTo:otherWindowNumber];
201 136
202 // Set up frame so it can be adjust down by a few pixels. 137 // Set up frame so it can be adjust down by a few pixels.
203 NSRect frame = [self frame]; 138 NSRect frame = [self frame];
204 NSPoint newOrigin = frame.origin; 139 NSPoint newOrigin = frame.origin;
205 newOrigin.y += kOrderInSlideOffset; 140 newOrigin.y += kOrderInSlideOffset;
206 [self setFrameOrigin:newOrigin]; 141 [self setFrameOrigin:newOrigin];
207 142
208 // Apply animations to show and move self. 143 [animation_controller_ animateWindow:self
209 [NSAnimationContext beginGrouping]; 144 targetOrigin:frame.origin
210 // The star currently triggers on mouse down, not mouse up. 145 closing:NO
211 NSTimeInterval duration = 146 callback:base::Closure()];
212 (allowedAnimations_ & info_bubble::kAnimateOrderIn)
213 ? kOrderInAnimationDuration : kMinimumTimeInterval;
214 [[NSAnimationContext currentContext]
215 gtm_setDuration:duration
216 eventMask:NSLeftMouseUpMask | NSLeftMouseDownMask];
217 [[self animator] setAlphaValue:1.0];
218 [[self animator] setFrame:frame display:YES];
219 [NSAnimationContext endGrouping];
220 } else { 147 } else {
221 [super orderWindow:orderingMode relativeTo:otherWindowNumber]; 148 [super orderWindow:orderingMode relativeTo:otherWindowNumber];
222 } 149 }
223 } 150 }
224 151
225 // If the window is currently animating a close, block all UI events to the 152 // If the window is currently animating a close, block all UI events to the
226 // window. 153 // window.
227 - (void)sendEvent:(NSEvent*)theEvent { 154 - (void)sendEvent:(NSEvent*)theEvent {
228 if (!closing_) 155 if (![self isClosing])
229 [super sendEvent:theEvent]; 156 [super sendEvent:theEvent];
230 } 157 }
231 158
232 - (BOOL)isClosing { 159 - (BOOL)isClosing {
233 return closing_; 160 return [animation_controller_ isClosing];
234 } 161 }
235 162
236 @end 163 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/info_bubble_window.h ('k') | ui/base/cocoa/window_animator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698