Fix build.
[WebKit-https.git] / Source / WebCore / platform / mac / WebWindowAnimation.mm
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "config.h"
27
28 #import "WebWindowAnimation.h"
29
30 #import "FloatConversion.h"
31 #import "WebCoreSystemInterface.h"
32 #import <wtf/Assertions.h>
33 #import <wtf/MathExtras.h>
34
35 using namespace WebCore;
36
37 static const CGFloat slowMotionFactor = 10;
38
39 static NSTimeInterval WebWindowAnimationDurationFromDuration(NSTimeInterval duration)
40 {
41 #pragma clang diagnostic push
42 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
43     return ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) ? duration * slowMotionFactor : duration;
44 #pragma clang diagnostic pop
45 }
46
47 static NSRect scaledRect(NSRect _initialFrame, NSRect _finalFrame, CGFloat factor)
48 {
49     NSRect currentRect = _initialFrame;
50     currentRect.origin.x += (NSMinX(_finalFrame) - NSMinX(_initialFrame)) * factor;
51     currentRect.origin.y += (NSMinY(_finalFrame) - NSMinY(_initialFrame)) * factor;
52     currentRect.size.width += (NSWidth(_finalFrame) - NSWidth(_initialFrame)) * factor;
53     currentRect.size.height += (NSHeight(_finalFrame) - NSHeight(_initialFrame)) * factor;
54     return currentRect;
55 }
56
57 static CGFloat squaredDistance(NSPoint point1, NSPoint point2)
58 {
59     CGFloat deltaX = point1.x - point2.x;
60     CGFloat deltaY = point1.y - point2.y;
61     return deltaX * deltaX + deltaY * deltaY;
62 }
63
64 @implementation WebWindowScaleAnimation
65
66 - (id)init
67 {
68     self = [super init];
69     if (!self)
70         return nil;
71     [self setAnimationBlockingMode:NSAnimationNonblockingThreaded];
72     [self setFrameRate:60];
73     return self;
74 }
75
76 - (id)initWithHintedDuration:(NSTimeInterval)duration window:(NSWindow *)window initalFrame:(NSRect)initialFrame finalFrame:(NSRect)finalFrame
77 {
78     self = [self init];
79     if (!self)
80         return nil;
81     _hintedDuration = duration;
82     _window = window;
83     _initialFrame = initialFrame;
84     _finalFrame = finalFrame;
85     _realFrame = [window frame];
86     return self;
87 }
88
89 - (void) dealloc
90 {
91     [_subAnimation release];
92     [super dealloc];
93 }
94
95 - (void)setDuration:(NSTimeInterval)duration
96 {
97     [super setDuration:WebWindowAnimationDurationFromDuration(duration)];
98 }
99
100 - (void)setWindow:(NSWindow *)window
101 {
102     _window = window;
103 }
104
105 - (float)currentValue
106 {
107     return narrowPrecisionToFloat(0.5 - 0.5 * cos(piDouble * (1 - [self currentProgress])));
108 }
109
110 - (NSRect)currentFrame
111 {
112     return scaledRect(_finalFrame, _initialFrame, [self currentValue]);
113 }
114
115 - (void)setCurrentProgress:(NSAnimationProgress)progress
116 {
117     if (!_window)
118         return;
119
120     [super setCurrentProgress:progress];
121
122     NSRect currentRect = [self currentFrame];
123     wkWindowSetScaledFrame(_window, currentRect, _realFrame);
124     [_subAnimation setCurrentProgress:progress];
125 }
126
127 - (void)setSubAnimation:(NSAnimation *)animation
128 {
129     id oldAnimation = _subAnimation;
130     _subAnimation = [animation retain];
131     [oldAnimation release];
132 }
133
134 - (NSTimeInterval)additionalDurationNeededToReachFinalFrame
135 {
136     static const CGFloat maxAdditionalDuration = 1;
137     static const CGFloat speedFactor = 0.0001f;
138     
139     CGFloat maxDist = squaredDistance(_initialFrame.origin, _finalFrame.origin);
140     CGFloat dist;
141     
142     dist = squaredDistance(NSMakePoint(NSMaxX(_initialFrame), NSMinY(_initialFrame)), NSMakePoint(NSMaxX(_finalFrame), NSMinY(_finalFrame)));
143     if (dist > maxDist)
144         maxDist = dist;
145     
146     dist = squaredDistance(NSMakePoint(NSMaxX(_initialFrame), NSMaxY(_initialFrame)), NSMakePoint(NSMaxX(_finalFrame), NSMaxY(_finalFrame)));
147     if (dist > maxDist)
148         maxDist = dist;
149     
150     dist = squaredDistance(NSMakePoint(NSMinX(_initialFrame), NSMinY(_initialFrame)), NSMakePoint(NSMinX(_finalFrame), NSMinY(_finalFrame)));
151     if (dist > maxDist)
152         maxDist = dist;
153     
154     return MIN(sqrt(maxDist) * speedFactor, maxAdditionalDuration);    
155 }
156
157 - (void)startAnimation
158 {
159     // Compute extra time
160     if (_hintedDuration)
161         [self setDuration:_hintedDuration + [self additionalDurationNeededToReachFinalFrame]];
162     [super startAnimation];
163 }
164
165 - (void)stopAnimation
166 {
167     _window = nil;
168     [super stopAnimation];
169     [_subAnimation stopAnimation];
170 }
171
172 @end
173
174 @implementation WebWindowFadeAnimation
175
176 - (id)init
177 {
178     self = [super init];
179     if (!self)
180         return nil;
181     [self setAnimationBlockingMode:NSAnimationNonblockingThreaded];
182     [self setFrameRate:60];
183     [self setAnimationCurve:NSAnimationEaseInOut];
184     return self;
185 }
186
187 - (id)initWithDuration:(NSTimeInterval)duration window:(NSWindow *)window initialAlpha:(CGFloat)initialAlpha finalAlpha:(CGFloat)finalAlpha
188 {
189     self = [self init];
190     if (!self)
191         return nil;    
192     _window = window;
193     _initialAlpha = initialAlpha;
194     _finalAlpha = finalAlpha;
195     [self setDuration:duration];
196     return self;
197 }
198
199 - (void)setDuration:(NSTimeInterval)duration
200 {
201     [super setDuration:WebWindowAnimationDurationFromDuration(duration)];
202 }
203
204 - (CGFloat)currentAlpha
205 {
206     return MAX(0, MIN(1, _initialAlpha + [self currentValue] * (_finalAlpha - _initialAlpha)));
207 }
208
209 - (void)setCurrentProgress:(NSAnimationProgress)progress
210 {
211     if (_isStopped)
212         return;
213
214     ASSERT(_window);
215     [super setCurrentProgress:progress];
216
217     wkWindowSetAlpha(_window, [self currentAlpha]);
218 }
219
220 - (void)setWindow:(NSWindow*)window
221 {
222     _window = window;
223 }
224
225 - (void)stopAnimation
226 {
227     // This is relevant when we are a sub animation of a scale animation.
228     // In this case we are hosted in the animated thread of the parent
229     // and even after [super stopAnimation], the parent might call
230     // setCurrrentProgress.
231     _isStopped = YES;
232
233     [super stopAnimation];
234 }
235
236 @end
237