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

Side by Side Diff: chrome/browser/cocoa/popup_blocked_animation_mac.mm

Issue 3014005: [Mac] Display a quick animation when a popup is blocked so the user notices it in the Omnibox. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: CGImage Created 10 years, 5 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
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698