summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/infobar_controller.mm
diff options
context:
space:
mode:
authorrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-03 23:55:55 +0000
committerrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-03 23:55:55 +0000
commitfc701bfe7df9de83bfbf5c93f23b455a47ba6bd8 (patch)
tree74a4fba00d45604b03d26378db27259a7b8a6ebc /chrome/browser/cocoa/infobar_controller.mm
parent5e36967c2b96745b13f3bc8d9ca56f62d888ae1d (diff)
downloadchromium_src-fc701bfe7df9de83bfbf5c93f23b455a47ba6bd8.zip
chromium_src-fc701bfe7df9de83bfbf5c93f23b455a47ba6bd8.tar.gz
chromium_src-fc701bfe7df9de83bfbf5c93f23b455a47ba6bd8.tar.bz2
[Mac] Enables animations for the infobar. Changes the control flow for infobar opening/closing to match Windows more closely.
Nib file changes: - Embedded the InfoBarGradientView inside an AnimatableView. - Rebound [controller view] to the AnimatableView and added an infoBarView_ IBOutlet. - Bound the AnimatableView's delegate_ to the InfoBarController. BUG=http://crbug.com/25599 TEST=Infobars should animate in and out, except for during tab switches. Review URL: http://codereview.chromium.org/354008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30893 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/infobar_controller.mm')
-rw-r--r--chrome/browser/cocoa/infobar_controller.mm99
1 files changed, 83 insertions, 16 deletions
diff --git a/chrome/browser/cocoa/infobar_controller.mm b/chrome/browser/cocoa/infobar_controller.mm
index e8b1999..2f053b8b4 100644
--- a/chrome/browser/cocoa/infobar_controller.mm
+++ b/chrome/browser/cocoa/infobar_controller.mm
@@ -7,6 +7,7 @@
#include "base/logging.h" // for NOTREACHED()
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
+#import "chrome/browser/cocoa/animatable_view.h"
#include "chrome/browser/cocoa/event_utils.h"
#include "chrome/browser/cocoa/infobar.h"
#import "chrome/browser/cocoa/infobar_container_controller.h"
@@ -16,14 +17,22 @@
#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#include "webkit/glue/window_open_disposition.h"
+namespace {
+// Durations set to match the default SlideAnimation duration.
+const float kAnimateOpenDuration = 0.12;
+const float kAnimateCloseDuration = 0.12;
+}
@interface InfoBarController (PrivateMethods)
-// Closes the infobar by calling RemoveDelegate on the container.
-// This will remove the infobar from its associated TabContents as
-// well as trigger the deletion of this InfoBarController. Once the
-// delegate is removed from the container, it is no longer needed, so
-// we ask it to delete itself.
-- (void)closeInfoBar;
+// Asks the container controller to remove the infobar for this delegate. This
+// call will trigger a notification that starts the infobar animating closed.
+- (void)removeInfoBar;
+
+// Performs final cleanup after an animation is finished or stopped, including
+// notifying the InfoBarDelegate that the infobar was closed and removing the
+// infobar from its container, if necessary.
+- (void)cleanUpAfterAnimation:(BOOL)finished;
+
// Removes the ok and cancel buttons, and resizes the textfield to use the
// space.
- (void)removeButtons;
@@ -76,7 +85,44 @@
// Called when someone clicks on the close button.
- (void)dismiss:(id)sender {
- [self closeInfoBar];
+ [self removeInfoBar];
+}
+
+- (AnimatableView*)animatableView {
+ return static_cast<AnimatableView*>([self view]);
+}
+
+- (void)open {
+ // Simply reset the frame size to its opened size, forcing a relayout.
+ CGFloat finalHeight = [[self view] frame].size.height;
+ [[self animatableView] setHeight:finalHeight];
+}
+
+- (void)animateOpen {
+ // Force the frame size to be 0 and then start an animation.
+ NSRect frame = [[self view] frame];
+ CGFloat finalHeight = frame.size.height;
+ frame.size.height = 0;
+ [[self view] setFrame:frame];
+ [[self animatableView] animateToNewHeight:finalHeight
+ duration:kAnimateOpenDuration];
+}
+
+- (void)close {
+ infoBarClosing_ = YES;
+ [self cleanUpAfterAnimation:YES];
+}
+
+- (void)animateClosed {
+ // Start animating closed. We will receive a notification when the animation
+ // is done, at which point we can remove our view from the hierarchy and
+ // notify the delegate that the infobar was closed.
+ [[self animatableView] animateToNewHeight:0 duration:kAnimateCloseDuration];
+
+ // The above call may trigger an animationDidStop: notification for any
+ // currently-running animations, so do not set |infoBarClosing_| until after
+ // starting the animation.
+ infoBarClosing_ = YES;
}
- (void)addAdditionalControls {
@@ -87,14 +133,9 @@
@implementation InfoBarController (PrivateMethods)
-- (void)closeInfoBar {
- // Calling RemoveDelegate() triggers notifications which will remove
- // the infobar view from the infobar container. At that point it is
- // safe to ask the delegate to delete itself.
+- (void)removeInfoBar {
DCHECK(delegate_);
[containerController_ removeDelegate:delegate_];
- delegate_->InfoBarClosed();
- delegate_ = NULL;
}
- (void)removeButtons {
@@ -107,6 +148,32 @@
[label_ setFrame:labelFrame];
}
+- (void)cleanUpAfterAnimation:(BOOL)finished {
+ // Don't need to do any cleanup if the bar was animating open.
+ if (!infoBarClosing_)
+ return;
+
+ // Notify the delegate that the infobar was closed. The delegate may delete
+ // itself as a result of InfoBarClosed(), so we null out its pointer.
+ delegate_->InfoBarClosed();
+ delegate_ = NULL;
+
+ // If the animation ran to completion, then we need to remove ourselves from
+ // the container. If the animation was interrupted, then the container will
+ // take care of removing us.
+ // TODO(rohitrao): UGH! This works for now, but should be cleaner.
+ if (finished)
+ [containerController_ removeController:self];
+}
+
+- (void)animationDidStop:(NSAnimation*)animation {
+ [self cleanUpAfterAnimation:NO];
+}
+
+- (void)animationDidEnd:(NSAnimation*)animation {
+ [self cleanUpAfterAnimation:YES];
+}
+
@end
@@ -203,7 +270,7 @@
WindowOpenDisposition disposition =
event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
if (delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition))
- [self closeInfoBar];
+ [self removeInfoBar];
}
@end
@@ -217,13 +284,13 @@
// Called when someone clicks on the "OK" button.
- (IBAction)ok:(id)sender {
if (delegate_->AsConfirmInfoBarDelegate()->Accept())
- [self closeInfoBar];
+ [self removeInfoBar];
}
// Called when someone clicks on the "Cancel" button.
- (IBAction)cancel:(id)sender {
if (delegate_->AsConfirmInfoBarDelegate()->Cancel())
- [self closeInfoBar];
+ [self removeInfoBar];
}
// Confirm infobars can have OK and/or cancel buttons, depending on