| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/popup_blocked_animation.h" |
| 6 |
| 7 #import <Cocoa/Cocoa.h> |
| 8 #import <QuartzCore/QuartzCore.h> |
| 9 |
| 10 #import "base/nsimage_cache_mac.h" |
| 11 #import "chrome/browser/cocoa/animatable_image.h" |
| 12 #include "chrome/browser/tab_contents/tab_contents.h" |
| 13 #include "chrome/common/notification_registrar.h" |
| 14 #include "chrome/common/notification_service.h" |
| 15 |
| 16 class PopupBlockedAnimationObserver; |
| 17 |
| 18 // A class for managing the Core Animation popup blocked animation. |
| 19 @interface PopupBlockedAnimationMac : NSObject { |
| 20 @private |
| 21 // The observer for the TabContents we are drawing on. |
| 22 scoped_ptr<PopupBlockedAnimationObserver> observer_; |
| 23 AnimatableImage* animation_; |
| 24 }; |
| 25 |
| 26 // Called by our the Observer if the tab is hidden or closed. |
| 27 - (void)animationComplete; |
| 28 |
| 29 @end |
| 30 |
| 31 // A helper class to monitor tab hidden and closed notifications. If we receive |
| 32 // such a notification, we stop the animation. |
| 33 class PopupBlockedAnimationObserver : public NotificationObserver { |
| 34 public: |
| 35 PopupBlockedAnimationObserver(PopupBlockedAnimationMac* owner, |
| 36 TabContents* tab_contents) |
| 37 : owner_(owner), |
| 38 tab_contents_(tab_contents) { |
| 39 registrar_.Add(this, |
| 40 NotificationType::TAB_CONTENTS_HIDDEN, |
| 41 Source<TabContents>(tab_contents_)); |
| 42 registrar_.Add(this, |
| 43 NotificationType::TAB_CONTENTS_DESTROYED, |
| 44 Source<TabContents>(tab_contents_)); |
| 45 } |
| 46 |
| 47 // Runs when a tab is hidden or destroyed. Let our owner know we should end |
| 48 // the animation. |
| 49 void Observe(NotificationType type, |
| 50 const NotificationSource& source, |
| 51 const NotificationDetails& details) { |
| 52 // This ends up deleting us. |
| 53 [owner_ animationComplete]; |
| 54 } |
| 55 |
| 56 private: |
| 57 // The object we need to inform when we get a notification. Weak. |
| 58 PopupBlockedAnimationMac* owner_; |
| 59 |
| 60 // The tab we are observing. Weak. |
| 61 TabContents* tab_contents_; |
| 62 |
| 63 // Used for registering to receive notifications and automatic clean up. |
| 64 NotificationRegistrar registrar_; |
| 65 |
| 66 DISALLOW_COPY_AND_ASSIGN(PopupBlockedAnimationObserver); |
| 67 }; |
| 68 |
| 69 @implementation PopupBlockedAnimationMac |
| 70 |
| 71 - (id)initWithTabContents:(TabContents*)tabContents { |
| 72 if ((self = [super init])) { |
| 73 NSImage* image = nsimage_cache::ImageNamed(@"popup_window_animation.pdf"); |
| 74 CGFloat imageWidth = [image size].width; |
| 75 CGFloat imageHeight = [image size].height; |
| 76 |
| 77 NSView* tabContentsView = tabContents->GetNativeView(); |
| 78 NSWindow* parentWindow = [tabContentsView window]; |
| 79 if (!parentWindow) { |
| 80 // The tab is no longer frontmost. |
| 81 [self release]; |
| 82 return nil; |
| 83 } |
| 84 |
| 85 NSRect windowFrame = [parentWindow frame]; |
| 86 |
| 87 // Sanity check the size in case there's no room to display the animation. |
| 88 if (imageWidth >= NSWidth(windowFrame) || |
| 89 imageHeight >= NSHeight(windowFrame)) { |
| 90 [self release]; |
| 91 return nil; |
| 92 } |
| 93 |
| 94 // Create the animation window to be the top-right quadrant of the window. |
| 95 // The animation travels from the center of the window to the blocked |
| 96 // content section of the Omnibox. This will release itself. |
| 97 NSRect animationFrame = windowFrame; |
| 98 CGFloat dX = NSWidth(animationFrame) / 2 - imageWidth / 2; |
| 99 CGFloat dY = NSHeight(animationFrame) / 2 - imageHeight / 2; |
| 100 animationFrame.origin.x += dX; |
| 101 animationFrame.origin.y += dY; |
| 102 animationFrame.size.width -= dX; |
| 103 animationFrame.size.height -= dY; |
| 104 animation_ = [[AnimatableImage alloc] initWithImage:image |
| 105 animationFrame:animationFrame]; |
| 106 [parentWindow addChildWindow:animation_ ordered:NSWindowAbove]; |
| 107 |
| 108 // Start the animation from the center of the window. |
| 109 NSRect contentFrame = [[animation_ contentView] frame]; |
| 110 [animation_ setStartFrame:CGRectMake(0, |
| 111 imageHeight / 2, |
| 112 imageWidth, |
| 113 imageHeight)]; |
| 114 |
| 115 // Set the end frame to be small (a la the actual blocked icon) and inset |
| 116 // slightly to the Omnibox. While the geometry won't align perfectly, it's |
| 117 // close enough for the user to take note of the new icon. These numbers |
| 118 // come from measuring the Omnibox without any page actions. |
| 119 [animation_ setEndFrame:CGRectMake(animationFrame.size.width - 115, |
| 120 animationFrame.size.height - 50, |
| 121 16, 16)]; |
| 122 [animation_ setStartOpacity:1.0]; |
| 123 [animation_ setEndOpacity:0.2]; |
| 124 [animation_ setDuration:0.7]; |
| 125 |
| 126 observer_.reset(new PopupBlockedAnimationObserver(self, tabContents)); |
| 127 |
| 128 // When the window is about to close, release this object and remove the |
| 129 // animation from the parent window. |
| 130 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
| 131 [center addObserver:self |
| 132 selector:@selector(windowWillClose:) |
| 133 name:NSWindowWillCloseNotification |
| 134 object:animation_]; |
| 135 [animation_ startAnimation]; |
| 136 } |
| 137 return self; |
| 138 } |
| 139 |
| 140 - (void)dealloc { |
| 141 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 142 [super dealloc]; |
| 143 } |
| 144 |
| 145 - (void)windowWillClose:(NSNotification*)notification { |
| 146 DCHECK([[notification object] isEqual:animation_]); |
| 147 [self animationComplete]; |
| 148 } |
| 149 |
| 150 - (void)animationComplete { |
| 151 [[animation_ parentWindow] removeChildWindow:animation_]; |
| 152 [self release]; |
| 153 } |
| 154 |
| 155 @end |
| 156 |
| 157 void PopupBlockedAnimation::Show(TabContents* tab_contents) { |
| 158 // The object will clean up itself at the end of the animation. |
| 159 [[PopupBlockedAnimationMac alloc] initWithTabContents:tab_contents]; |
| 160 } |
| OLD | NEW |