OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 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 <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #include "base/logging.h" // for NOTREACHED() | 7 #include "base/logging.h" // for NOTREACHED() |
8 #include "base/mac_util.h" | 8 #include "base/mac_util.h" |
9 #include "base/sys_string_conversions.h" | 9 #include "base/sys_string_conversions.h" |
| 10 #import "chrome/browser/cocoa/animatable_view.h" |
10 #include "chrome/browser/cocoa/event_utils.h" | 11 #include "chrome/browser/cocoa/event_utils.h" |
11 #include "chrome/browser/cocoa/infobar.h" | 12 #include "chrome/browser/cocoa/infobar.h" |
12 #import "chrome/browser/cocoa/infobar_container_controller.h" | 13 #import "chrome/browser/cocoa/infobar_container_controller.h" |
13 #import "chrome/browser/cocoa/infobar_controller.h" | 14 #import "chrome/browser/cocoa/infobar_controller.h" |
14 #include "chrome/browser/tab_contents/tab_contents.h" | 15 #include "chrome/browser/tab_contents/tab_contents.h" |
15 #include "skia/ext/skia_utils_mac.h" | 16 #include "skia/ext/skia_utils_mac.h" |
16 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 17 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
17 #include "webkit/glue/window_open_disposition.h" | 18 #include "webkit/glue/window_open_disposition.h" |
18 | 19 |
| 20 namespace { |
| 21 // Durations set to match the default SlideAnimation duration. |
| 22 const float kAnimateOpenDuration = 0.12; |
| 23 const float kAnimateCloseDuration = 0.12; |
| 24 } |
19 | 25 |
20 @interface InfoBarController (PrivateMethods) | 26 @interface InfoBarController (PrivateMethods) |
21 // Closes the infobar by calling RemoveDelegate on the container. | 27 // Asks the container controller to remove the infobar for this delegate. This |
22 // This will remove the infobar from its associated TabContents as | 28 // call will trigger a notification that starts the infobar animating closed. |
23 // well as trigger the deletion of this InfoBarController. Once the | 29 - (void)removeInfoBar; |
24 // delegate is removed from the container, it is no longer needed, so | 30 |
25 // we ask it to delete itself. | 31 // Performs final cleanup after an animation is finished or stopped, including |
26 - (void)closeInfoBar; | 32 // notifying the InfoBarDelegate that the infobar was closed and removing the |
| 33 // infobar from its container, if necessary. |
| 34 - (void)cleanUpAfterAnimation:(BOOL)finished; |
| 35 |
27 // Removes the ok and cancel buttons, and resizes the textfield to use the | 36 // Removes the ok and cancel buttons, and resizes the textfield to use the |
28 // space. | 37 // space. |
29 - (void)removeButtons; | 38 - (void)removeButtons; |
30 @end | 39 @end |
31 | 40 |
32 @implementation InfoBarController | 41 @implementation InfoBarController |
33 | 42 |
34 @synthesize containerController = containerController_; | 43 @synthesize containerController = containerController_; |
35 @synthesize delegate = delegate_; | 44 @synthesize delegate = delegate_; |
36 | 45 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 } | 78 } |
70 | 79 |
71 // Called when someone clicks on the cancel button. | 80 // Called when someone clicks on the cancel button. |
72 - (void)cancel:(id)sender { | 81 - (void)cancel:(id)sender { |
73 // Subclasses must override this method if they do not hide the cancel button. | 82 // Subclasses must override this method if they do not hide the cancel button. |
74 NOTREACHED(); | 83 NOTREACHED(); |
75 } | 84 } |
76 | 85 |
77 // Called when someone clicks on the close button. | 86 // Called when someone clicks on the close button. |
78 - (void)dismiss:(id)sender { | 87 - (void)dismiss:(id)sender { |
79 [self closeInfoBar]; | 88 [self removeInfoBar]; |
| 89 } |
| 90 |
| 91 - (AnimatableView*)animatableView { |
| 92 return static_cast<AnimatableView*>([self view]); |
| 93 } |
| 94 |
| 95 - (void)open { |
| 96 // Simply reset the frame size to its opened size, forcing a relayout. |
| 97 CGFloat finalHeight = [[self view] frame].size.height; |
| 98 [[self animatableView] setHeight:finalHeight]; |
| 99 } |
| 100 |
| 101 - (void)animateOpen { |
| 102 // Force the frame size to be 0 and then start an animation. |
| 103 NSRect frame = [[self view] frame]; |
| 104 CGFloat finalHeight = frame.size.height; |
| 105 frame.size.height = 0; |
| 106 [[self view] setFrame:frame]; |
| 107 [[self animatableView] animateToNewHeight:finalHeight |
| 108 duration:kAnimateOpenDuration]; |
| 109 } |
| 110 |
| 111 - (void)close { |
| 112 infoBarClosing_ = YES; |
| 113 [self cleanUpAfterAnimation:YES]; |
| 114 } |
| 115 |
| 116 - (void)animateClosed { |
| 117 // Start animating closed. We will receive a notification when the animation |
| 118 // is done, at which point we can remove our view from the hierarchy and |
| 119 // notify the delegate that the infobar was closed. |
| 120 [[self animatableView] animateToNewHeight:0 duration:kAnimateCloseDuration]; |
| 121 |
| 122 // The above call may trigger an animationDidStop: notification for any |
| 123 // currently-running animations, so do not set |infoBarClosing_| until after |
| 124 // starting the animation. |
| 125 infoBarClosing_ = YES; |
80 } | 126 } |
81 | 127 |
82 - (void)addAdditionalControls { | 128 - (void)addAdditionalControls { |
83 // Default implementation does nothing. | 129 // Default implementation does nothing. |
84 } | 130 } |
85 | 131 |
86 @end | 132 @end |
87 | 133 |
88 @implementation InfoBarController (PrivateMethods) | 134 @implementation InfoBarController (PrivateMethods) |
89 | 135 |
90 - (void)closeInfoBar { | 136 - (void)removeInfoBar { |
91 // Calling RemoveDelegate() triggers notifications which will remove | |
92 // the infobar view from the infobar container. At that point it is | |
93 // safe to ask the delegate to delete itself. | |
94 DCHECK(delegate_); | 137 DCHECK(delegate_); |
95 [containerController_ removeDelegate:delegate_]; | 138 [containerController_ removeDelegate:delegate_]; |
96 delegate_->InfoBarClosed(); | |
97 delegate_ = NULL; | |
98 } | 139 } |
99 | 140 |
100 - (void)removeButtons { | 141 - (void)removeButtons { |
101 // Extend the label all the way across. | 142 // Extend the label all the way across. |
102 // Remove the ok and cancel buttons, since they are not needed. | 143 // Remove the ok and cancel buttons, since they are not needed. |
103 NSRect labelFrame = [label_ frame]; | 144 NSRect labelFrame = [label_ frame]; |
104 labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame); | 145 labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame); |
105 [okButton_ removeFromSuperview]; | 146 [okButton_ removeFromSuperview]; |
106 [cancelButton_ removeFromSuperview]; | 147 [cancelButton_ removeFromSuperview]; |
107 [label_ setFrame:labelFrame]; | 148 [label_ setFrame:labelFrame]; |
108 } | 149 } |
109 | 150 |
| 151 - (void)cleanUpAfterAnimation:(BOOL)finished { |
| 152 // Don't need to do any cleanup if the bar was animating open. |
| 153 if (!infoBarClosing_) |
| 154 return; |
| 155 |
| 156 // Notify the delegate that the infobar was closed. The delegate may delete |
| 157 // itself as a result of InfoBarClosed(), so we null out its pointer. |
| 158 delegate_->InfoBarClosed(); |
| 159 delegate_ = NULL; |
| 160 |
| 161 // If the animation ran to completion, then we need to remove ourselves from |
| 162 // the container. If the animation was interrupted, then the container will |
| 163 // take care of removing us. |
| 164 // TODO(rohitrao): UGH! This works for now, but should be cleaner. |
| 165 if (finished) |
| 166 [containerController_ removeController:self]; |
| 167 } |
| 168 |
| 169 - (void)animationDidStop:(NSAnimation*)animation { |
| 170 [self cleanUpAfterAnimation:NO]; |
| 171 } |
| 172 |
| 173 - (void)animationDidEnd:(NSAnimation*)animation { |
| 174 [self cleanUpAfterAnimation:YES]; |
| 175 } |
| 176 |
110 @end | 177 @end |
111 | 178 |
112 | 179 |
113 ///////////////////////////////////////////////////////////////////////// | 180 ///////////////////////////////////////////////////////////////////////// |
114 // AlertInfoBarController implementation | 181 // AlertInfoBarController implementation |
115 | 182 |
116 @implementation AlertInfoBarController | 183 @implementation AlertInfoBarController |
117 | 184 |
118 // Alert infobars have a text message. | 185 // Alert infobars have a text message. |
119 - (void)addAdditionalControls { | 186 - (void)addAdditionalControls { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 [label_ setAttributedStringValue:infoText]; | 263 [label_ setAttributedStringValue:infoText]; |
197 } | 264 } |
198 | 265 |
199 // Called when someone clicks on the link in the infobar. This method | 266 // Called when someone clicks on the link in the infobar. This method |
200 // is called by the InfobarTextField on its delegate (the | 267 // is called by the InfobarTextField on its delegate (the |
201 // LinkInfoBarController). | 268 // LinkInfoBarController). |
202 - (void)linkClicked { | 269 - (void)linkClicked { |
203 WindowOpenDisposition disposition = | 270 WindowOpenDisposition disposition = |
204 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); | 271 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); |
205 if (delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition)) | 272 if (delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition)) |
206 [self closeInfoBar]; | 273 [self removeInfoBar]; |
207 } | 274 } |
208 | 275 |
209 @end | 276 @end |
210 | 277 |
211 | 278 |
212 ///////////////////////////////////////////////////////////////////////// | 279 ///////////////////////////////////////////////////////////////////////// |
213 // ConfirmInfoBarController implementation | 280 // ConfirmInfoBarController implementation |
214 | 281 |
215 @implementation ConfirmInfoBarController | 282 @implementation ConfirmInfoBarController |
216 | 283 |
217 // Called when someone clicks on the "OK" button. | 284 // Called when someone clicks on the "OK" button. |
218 - (IBAction)ok:(id)sender { | 285 - (IBAction)ok:(id)sender { |
219 if (delegate_->AsConfirmInfoBarDelegate()->Accept()) | 286 if (delegate_->AsConfirmInfoBarDelegate()->Accept()) |
220 [self closeInfoBar]; | 287 [self removeInfoBar]; |
221 } | 288 } |
222 | 289 |
223 // Called when someone clicks on the "Cancel" button. | 290 // Called when someone clicks on the "Cancel" button. |
224 - (IBAction)cancel:(id)sender { | 291 - (IBAction)cancel:(id)sender { |
225 if (delegate_->AsConfirmInfoBarDelegate()->Cancel()) | 292 if (delegate_->AsConfirmInfoBarDelegate()->Cancel()) |
226 [self closeInfoBar]; | 293 [self removeInfoBar]; |
227 } | 294 } |
228 | 295 |
229 // Confirm infobars can have OK and/or cancel buttons, depending on | 296 // Confirm infobars can have OK and/or cancel buttons, depending on |
230 // the return value of GetButtons(). We create each button if | 297 // the return value of GetButtons(). We create each button if |
231 // required and position them to the left of the close button. | 298 // required and position them to the left of the close button. |
232 - (void)addAdditionalControls { | 299 - (void)addAdditionalControls { |
233 ConfirmInfoBarDelegate* delegate = delegate_->AsConfirmInfoBarDelegate(); | 300 ConfirmInfoBarDelegate* delegate = delegate_->AsConfirmInfoBarDelegate(); |
234 int visibleButtons = delegate->GetButtons(); | 301 int visibleButtons = delegate->GetButtons(); |
235 | 302 |
236 NSRect okButtonFrame = [okButton_ frame]; | 303 NSRect okButtonFrame = [okButton_ frame]; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 LinkInfoBarController* controller = | 384 LinkInfoBarController* controller = |
318 [[LinkInfoBarController alloc] initWithDelegate:this]; | 385 [[LinkInfoBarController alloc] initWithDelegate:this]; |
319 return new InfoBar(controller); | 386 return new InfoBar(controller); |
320 } | 387 } |
321 | 388 |
322 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { | 389 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { |
323 ConfirmInfoBarController* controller = | 390 ConfirmInfoBarController* controller = |
324 [[ConfirmInfoBarController alloc] initWithDelegate:this]; | 391 [[ConfirmInfoBarController alloc] initWithDelegate:this]; |
325 return new InfoBar(controller); | 392 return new InfoBar(controller); |
326 } | 393 } |
OLD | NEW |