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

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

Issue 159623: Implement the download arrow animation for Mac (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/browser.cc ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Name: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4 //
5 // This file contains the Mac implementation the download animation, displayed
6 // at the start of a download. The animation produces an arrow pointing
7 // downwards and animates towards the bottom of the window where the new
8 // download appears in the download shelf.
9
10 #include "chrome/browser/download/download_started_animation.h"
11
12 #import <QuartzCore/QuartzCore.h>
13
14 #include "app/resource_bundle.h"
15 #include "base/scoped_cftyperef.h"
16 #include "base/scoped_nsobject.h"
17 #include "chrome/browser/tab_contents/tab_contents.h"
18 #include "chrome/browser/tab_contents/tab_contents_view_mac.h"
19 #include "chrome/common/notification_registrar.h"
20 #include "chrome/common/notification_service.h"
21 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
22
23 class DownloadAnimationTabObserver;
24
25 // A class for managing the Core Animation download animation.
26 @interface DownloadStartedAnimationMac : NSObject {
27 // The download arrow image which we are responsible for freeing.
28 scoped_cftyperef<CGImageRef> image_;
29
30 // The TabContents we will animate in (weak).
31 TabContents* tabContents_;
32
33 // The cocoa view object for our TabContents (weak).
34 NSView* view_;
35
36 // The observer for the TabContents we are drawing on.
37 scoped_ptr<DownloadAnimationTabObserver> observer_;
38
39 // Our animation layer.
40 scoped_nsobject<CALayer> layer_;
41
42 // Set once the animation is complete, either by interrupting (via window
43 // close) or through normal a end of the animation.
44 BOOL isComplete_;
45 };
46
47 // Called by our DownloadAnimationTabObserver if the tab is hidden or closed.
48 - (void)animationComplete;
49
50 @end // interface DownloadStartedAnimationMac.
51
52
53 // A helper class to monitor tab hidden and closed notifications. If we receive
54 // such a notification, we stop the animation.
55 class DownloadAnimationTabObserver : public NotificationObserver {
56 public:
57 DownloadAnimationTabObserver(DownloadStartedAnimationMac* owner,
58 TabContents* tab_contents)
59 : owner_(owner),
60 tab_contents_(tab_contents) {
61 registrar_.Add(this,
62 NotificationType::TAB_CONTENTS_HIDDEN,
63 Source<TabContents>(tab_contents_));
64 registrar_.Add(this,
65 NotificationType::TAB_CONTENTS_DESTROYED,
66 Source<TabContents>(tab_contents_));
67 }
68
69 // Runs when a tab is hidden or destroyed. Let our owner know we should end
70 // the animation.
71 void Observe(NotificationType type,
72 const NotificationSource& source,
73 const NotificationDetails& details) {
74 registrar_.Remove(this,
75 NotificationType::TAB_CONTENTS_HIDDEN,
76 Source<TabContents>(tab_contents_));
77 registrar_.Remove(this,
78 NotificationType::TAB_CONTENTS_DESTROYED,
79 Source<TabContents>(tab_contents_));
80 [owner_ animationComplete];
81 }
82
83 private:
84 // The object we need to inform when we get a notification. Weak.
85 DownloadStartedAnimationMac* owner_;
86
87 // The tab we are observing. Weak.
88 TabContents* tab_contents_;
89
90 // Used for registering to receive notifications and automatic clean up.
91 NotificationRegistrar registrar_;
92
93 DISALLOW_COPY_AND_ASSIGN(DownloadAnimationTabObserver);
94 };
95
96
97 @implementation DownloadStartedAnimationMac
98
99 // Load the image of the download arrow.
100 - (id)initWithTabContents:(TabContents*)tabContents {
101 if ((self = [super init])) {
102 SkBitmap* image_bitmap =
103 ResourceBundle::GetSharedInstance().GetBitmapNamed(
104 IDR_DOWNLOAD_ANIMATION_BEGIN);
105 image_.reset(SkCreateCGImageRef(*image_bitmap));
106 tabContents_ = tabContents;
107 view_ = tabContents_->GetContentNativeView();
108 observer_.reset(new DownloadAnimationTabObserver(self, tabContents));
109 isComplete_ = NO;
110 }
111 return self;
112 }
113
114 // Common clean up code.
115 - (void)animationComplete {
116 if (isComplete_)
117 return;
118 isComplete_ = YES;
119 [view_ setWantsLayer:NO];
120 [layer_ removeAllAnimations];
121 [layer_ removeFromSuperlayer];
122 }
123
124 // Set up the animation and let Core Animation do all the hard work.
125 - (void)animate {
126 // Figure out the positioning in the current tab. We try to position ourselves
127 // against the left edge, and three times the download image's height from the
128 // bottom of the tab, assuming there is enough room. If there isn't enough, we
129 // won't show the animation and let the shelf speak for itself.
130 gfx::Rect bounds;
131 tabContents_->GetContainerBounds(&bounds);
132 int imageWidth = CGImageGetWidth(image_);
133 int imageHeight = CGImageGetHeight(image_);
134 CGRect imageBounds = CGRectMake(0, 0, imageWidth, imageHeight);
135
136 // Sanity check the size in case there's no room to display the animation.
137 if (bounds.height() < imageHeight) {
138 [self release];
139 return;
140 }
141
142 int animationHeight = std::min(bounds.height(), 3 * imageHeight);
143 NSPoint start = NSMakePoint(0, animationHeight);
144 NSPoint stop = NSMakePoint(0, 0); // Bottom of the tab.
145
146 // Set for the duration of the animation, or we won't see our layer. We reset
147 // this in the completion callback.
148 [view_ setWantsLayer:YES];
149
150 // CALayer initalization.
151 layer_.reset([[CALayer layer] retain]);
152 [layer_ setNeedsDisplay];
153 [layer_ setContents:(id)image_.get()];
154 [layer_ setAnchorPoint:CGPointMake(0, 0)];
155 [layer_ setFrame:imageBounds];
156 [[view_ layer] addSublayer:layer_];
157
158 // Positional animation.
159 CABasicAnimation *animation =
160 [CABasicAnimation animationWithKeyPath:@"position"];
161 [animation setFromValue:[NSValue valueWithPoint:start]];
162 [animation setToValue:[NSValue valueWithPoint:stop]];
163 [animation setDuration:0.6];
164 CAMediaTimingFunction* mediaFunction =
165 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
166 [animation setTimingFunction:mediaFunction];
167 [animation setDelegate:self];
168 [layer_ addAnimation:animation forKey:@"downloadPosition"];
169
170 // Opacity animation.
171 animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
172 [animation setFromValue:[NSNumber numberWithFloat:1.0]];
173 [animation setToValue:[NSNumber numberWithFloat:0.0]];
174 [animation setDuration:1.5]; // Slightly longer, so it doesn't fade too much.
175 mediaFunction =
176 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
177 [animation setTimingFunction:mediaFunction];
178 [layer_ addAnimation:animation forKey:@"downloadOpacity"];
179 }
180
181 // CAAnimation delegate method called when the animation is complete.
182 - (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
183 [self animationComplete];
184 [self release];
185 }
186
187 @end // implementation DownloadStartedAnimationMac
188
189
190 // static
191 void DownloadStartedAnimation::Show(TabContents* tab_contents) {
192 DCHECK(tab_contents);
193
194 // Will be deleted when the animation is complete.
195 DownloadStartedAnimationMac* downloadArrow =
196 [[DownloadStartedAnimationMac alloc] initWithTabContents:tab_contents];
197
198 // Go!
199 [downloadArrow animate];
200 }
OLDNEW
« no previous file with comments | « chrome/browser/browser.cc ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698