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

Unified Diff: chrome/browser/ui/cocoa/download/download_shelf_controller.mm

Issue 12995025: [Mac] DownloadShelf should be notified when autoclosing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/download/download_shelf_controller.mm
diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm
index 16ea814138133fb0a5a7335bf60b4bd9ccc94fc5..9c66a90aa6329203c015dc71bcd3fb712edc07f4 100644
--- a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm
+++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm
@@ -71,16 +71,13 @@ const NSSize kHoverCloseButtonDefaultSize = { 18, 18 };
} // namespace
@interface DownloadShelfController(Private)
-- (void)showDownloadShelf:(BOOL)enable;
+- (void)viewFrameDidChange:(NSNotification*)notification;
- (void)layoutItems:(BOOL)skipFirst;
- (void)closed;
-- (BOOL)canAutoClose;
-
-- (void)viewFrameDidChange:(NSNotification*)notification;
-
+- (void)maybeAutoCloseAfterDelay;
+- (void)autoClose;
- (void)installTrackingArea;
- (void)cancelAutoCloseAndRemoveTrackingArea;
-
- (void)willEnterFullscreen;
- (void)willLeaveFullscreen;
- (void)updateCloseButton;
@@ -150,144 +147,44 @@ const NSSize kHoverCloseButtonDefaultSize = { 18, 18 };
[super dealloc];
}
-// Called after the frame's rect has changed; usually when the height is
-// animated.
-- (void)viewFrameDidChange:(NSNotification*)notification {
asanka 2013/03/22 20:11:01 Methods were re-ordered to match declaration order
Nico 2013/03/22 20:24:11 Can you land that part as a separate CL? That woul
asanka 2013/03/22 21:22:13 I undid the re-ordering. I see the point about mes
- // Anchor subviews at the top of |view|, so that it looks like the shelf
- // is sliding out.
- CGFloat newShelfHeight = NSHeight([[self view] frame]);
- if (newShelfHeight == currentShelfHeight_)
- return;
-
- for (NSView* view in [[self view] subviews]) {
- NSRect frame = [view frame];
- frame.origin.y -= currentShelfHeight_ - newShelfHeight;
- [view setFrame:frame];
- }
- currentShelfHeight_ = newShelfHeight;
-}
-
-- (AnimatableView*)animatableView {
- return static_cast<AnimatableView*>([self view]);
-}
-
-- (void)showDownloadsTab:(id)sender {
+- (IBAction)showDownloadsTab:(id)sender {
chrome::ShowDownloads(bridge_->browser());
}
-- (void)remove:(DownloadItemController*)download {
- // Look for the download in our controller array and remove it. This will
- // explicity release it so that it removes itself as an Observer of the
- // DownloadItem. We don't want to wait for autorelease since the DownloadItem
- // we are observing will likely be gone by then.
- [[NSNotificationCenter defaultCenter] removeObserver:download];
-
- // TODO(dmaclach): Remove -- http://crbug.com/25845
- [[download view] removeFromSuperview];
-
- [downloadItemControllers_ removeObject:download];
-
- [self layoutItems];
-
- // Check to see if we have any downloads remaining and if not, hide the shelf.
- if (![downloadItemControllers_ count])
- [self showDownloadShelf:NO];
-}
-
-- (void)downloadWasOpened:(DownloadItemController*)item_controller {
- // This should only be called on the main thead.
- DCHECK([NSThread isMainThread]);
-
- if ([self canAutoClose])
- [self installTrackingArea];
+- (IBAction)handleClose:(id)sender {
+ bridge_->Close(DownloadShelf::USER_ACTION);
}
-// We need to explicitly release our download controllers here since they need
-// to remove themselves as observers before the remaining shutdown happens.
-- (void)exiting {
- [[self animatableView] stopAnimation];
- [self cancelAutoCloseAndRemoveTrackingArea];
- downloadItemControllers_.reset();
-}
-
-// Show or hide the bar based on the value of |enable|. Handles animating the
-// resize of the content view.
-- (void)showDownloadShelf:(BOOL)enable {
- if ([self isVisible] == enable)
+- (void)showDownloadShelf:(BOOL)show
+ isUserAction:(BOOL)isUserAction {
+ if ([self isVisible] == show)
return;
+ if (!show) {
+ [self cancelAutoCloseAndRemoveTrackingArea];
+ int numInProgress = 0;
+ for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) {
+ if ([[downloadItemControllers_ objectAtIndex:i]download]->IsInProgress())
+ ++numInProgress;
+ }
+ download_util::RecordShelfClose(
+ [downloadItemControllers_ count], numInProgress, !isUserAction);
+ }
// Animate the shelf out, but not in.
// TODO(rohitrao): We do not animate on the way in because Cocoa is already
// doing a lot of work to set up the download arrow animation. I've chosen to
// do no animation over janky animation. Find a way to make animating in
// smoother.
AnimatableView* view = [self animatableView];
- if (enable)
+ if (show)
[view setHeight:maxShelfHeight_];
else
[view animateToNewHeight:0 duration:kDownloadShelfCloseDuration];
- barIsVisible_ = enable;
+ barIsVisible_ = show;
[self updateCloseButton];
}
-- (DownloadShelf*)bridge {
- return bridge_.get();
-}
-
-- (BOOL)isVisible {
- return barIsVisible_;
-}
-
-- (void)show:(id)sender {
- [self showDownloadShelf:YES];
-}
-
-- (void)hide:(id)sender {
- [self cancelAutoCloseAndRemoveTrackingArea];
-
- // If |sender| isn't nil, then we're being closed from the UI by the user and
- // we need to tell our shelf implementation to close. Otherwise, we're being
- // closed programmatically by our shelf implementation.
- bool auto_closed = (sender == nil);
-
- int numInProgress = 0;
- for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) {
- if ([[downloadItemControllers_ objectAtIndex:i]download]->IsInProgress())
- ++numInProgress;
- }
- download_util::RecordShelfClose(
- [downloadItemControllers_ count], numInProgress, auto_closed);
- if (auto_closed)
- [self showDownloadShelf:NO];
- else
- bridge_->Close();
-}
-
-- (void)animationDidEnd:(NSAnimation*)animation {
- if (![self isVisible])
- [self closed];
-}
-
-- (float)height {
- return maxShelfHeight_;
-}
-
-// If |skipFirst| is true, the frame of the leftmost item is not set.
-- (void)layoutItems:(BOOL)skipFirst {
- CGFloat currentX = 0;
- for (DownloadItemController* itemController
- in downloadItemControllers_.get()) {
- NSRect frame = [[itemController view] frame];
- frame.origin.x = currentX;
- frame.size.width = [itemController preferredSize].width;
- if (!skipFirst)
- [[[itemController view] animator] setFrame:frame];
- currentX += frame.size.width + kDownloadItemPadding;
- skipFirst = NO;
- }
-}
-
- (void)layoutItems {
[self layoutItems:NO];
}
@@ -350,6 +247,91 @@ const NSSize kHoverCloseButtonDefaultSize = { 18, 18 };
[self layoutItems:YES];
}
+- (void)remove:(DownloadItemController*)download {
+ // Look for the download in our controller array and remove it. This will
+ // explicity release it so that it removes itself as an Observer of the
+ // DownloadItem. We don't want to wait for autorelease since the DownloadItem
+ // we are observing will likely be gone by then.
+ [[NSNotificationCenter defaultCenter] removeObserver:download];
+
+ // TODO(dmaclach): Remove -- http://crbug.com/25845
+ [[download view] removeFromSuperview];
+
+ [downloadItemControllers_ removeObject:download];
+ [self layoutItems];
+
+ // If there are no more downloads or if all the remaining downloads have been
+ // opened, we can close the shelf.
+ [self maybeAutoCloseAfterDelay];
+}
+
+- (void)downloadWasOpened:(DownloadItemController*)item_controller {
+ // This should only be called on the main thead.
+ DCHECK([NSThread isMainThread]);
+ [self maybeAutoCloseAfterDelay];
+}
+
+// We need to explicitly release our download controllers here since they need
+// to remove themselves as observers before the remaining shutdown happens.
+- (void)exiting {
+ [[self animatableView] stopAnimation];
+ [self cancelAutoCloseAndRemoveTrackingArea];
+ downloadItemControllers_.reset();
+}
+
+- (AnimatableView*)animatableView {
+ return static_cast<AnimatableView*>([self view]);
+}
+
+- (DownloadShelf*)bridge {
+ return bridge_.get();
+}
+
+- (BOOL)isVisible {
+ return barIsVisible_;
+}
+
+- (float)height {
+ return maxShelfHeight_;
+}
+
+// Called after the frame's rect has changed; usually when the height is
+// animated.
+- (void)viewFrameDidChange:(NSNotification*)notification {
+ // Anchor subviews at the top of |view|, so that it looks like the shelf
+ // is sliding out.
+ CGFloat newShelfHeight = NSHeight([[self view] frame]);
+ if (newShelfHeight == currentShelfHeight_)
+ return;
+
+ for (NSView* view in [[self view] subviews]) {
+ NSRect frame = [view frame];
+ frame.origin.y -= currentShelfHeight_ - newShelfHeight;
+ [view setFrame:frame];
+ }
+ currentShelfHeight_ = newShelfHeight;
+}
+
+- (void)animationDidEnd:(NSAnimation*)animation {
+ if (![self isVisible])
+ [self closed];
+}
+
+// If |skipFirst| is true, the frame of the leftmost item is not set.
+- (void)layoutItems:(BOOL)skipFirst {
+ CGFloat currentX = 0;
+ for (DownloadItemController* itemController
+ in downloadItemControllers_.get()) {
+ NSRect frame = [[itemController view] frame];
+ frame.origin.x = currentX;
+ frame.size.width = [itemController preferredSize].width;
+ if (!skipFirst)
+ [[[itemController view] animator] setFrame:frame];
+ currentX += frame.size.width + kDownloadItemPadding;
+ skipFirst = NO;
+ }
+}
+
- (void)closed {
// Don't remove completed downloads if the shelf is just being auto-hidden
// rather than explicitly closed by the user.
@@ -383,24 +365,41 @@ const NSSize kHoverCloseButtonDefaultSize = { 18, 18 };
- (void)mouseExited:(NSEvent*)event {
// Cancel any previous hide requests, just to be safe.
[NSObject cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(hide:)
- object:self];
+ selector:@selector(autoClose)
+ object:nil];
// Schedule an autoclose after a delay. If the mouse is moved back into the
// view, or if an item is added to the shelf, the timer will be canceled.
- [self performSelector:@selector(hide:)
- withObject:self
+ [self performSelector:@selector(autoClose)
+ withObject:nil
afterDelay:kAutoCloseDelaySeconds];
}
-- (BOOL)canAutoClose {
+- (void)maybeAutoCloseAfterDelay {
+ // We can close the shelf automatically if all the downloads on the shelf have
+ // been opened.
for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) {
DownloadItemController* itemController =
[downloadItemControllers_ objectAtIndex:i];
if (![itemController download]->GetOpened())
- return NO;
+ return;
}
- return YES;
+
+ if ([self isVisible] && [downloadItemControllers_ count] > 0) {
+ // If the shelf is visible and has download items remaining on it, close the
+ // shelf after the user moves the mouse out of the download shelf.
+ [self installTrackingArea];
+ } else {
+ // We notify the DownloadShelf of our intention to close even if the shelf
+ // is currently hidden. If the shelf was temporarily hidden (e.g. because
+ // the browser window entered fullscreen mode), then this prevents the shelf
+ // from being shown again when the browser exits fullscreen mode.
+ [self autoClose];
+ }
+}
+
+- (void)autoClose {
+ bridge_->Close(DownloadShelf::AUTOMATIC);
}
- (void)installTrackingArea {
@@ -420,8 +419,8 @@ const NSSize kHoverCloseButtonDefaultSize = { 18, 18 };
- (void)cancelAutoCloseAndRemoveTrackingArea {
[NSObject cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(hide:)
- object:self];
+ selector:@selector(autoClose)
+ object:nil];
if (trackingArea_.get()) {
[[self view] removeTrackingArea:trackingArea_];

Powered by Google App Engine
This is Rietveld 408576698