Removing the use of private CoreGraphics APIs to draw shadows, and replacing with...
[ITKit.git] / ITPivotWindowEffect.m
1 #import "ITPivotWindowEffect.h"
2 #import "ITCoreGraphicsHacks.h"
3 #import "ITTransientStatusWindow.h"
4
5
6 @interface ITPivotWindowEffect (Private)
7 - (void)setPivot:(float)angle;
8 - (void)performAppearFromProgress:(float)progress effectTime:(float)time;
9 - (void)appearStep;
10 - (void)appearFinish;
11 - (void)performVanishFromProgress:(float)progress effectTime:(float)time;
12 - (void)vanishStep;
13 - (void)vanishFinish;
14 @end
15
16
17 @implementation ITPivotWindowEffect
18
19
20 + (NSString *)effectName
21 {
22     return @"Pivot";
23 }
24
25 + (NSDictionary *)supportedPositions
26 {
27     return [NSDictionary dictionaryWithObjectsAndKeys:
28         [NSDictionary dictionaryWithObjectsAndKeys:
29             [NSNumber numberWithBool:YES], @"Left",
30             [NSNumber numberWithBool:NO], @"Center",
31             [NSNumber numberWithBool:YES], @"Right", nil] , @"Top" ,
32         [NSDictionary dictionaryWithObjectsAndKeys:
33             [NSNumber numberWithBool:NO], @"Left",
34             [NSNumber numberWithBool:NO], @"Center",
35             [NSNumber numberWithBool:NO], @"Right", nil] , @"Middle" ,
36         [NSDictionary dictionaryWithObjectsAndKeys:
37             [NSNumber numberWithBool:YES], @"Left",
38             [NSNumber numberWithBool:NO], @"Center",
39             [NSNumber numberWithBool:YES], @"Right", nil] , @"Bottom" , nil];
40 }
41
42
43 + (unsigned int)listOrder
44 {
45     return 500;
46 }
47
48
49 /*************************************************************************/
50 #pragma mark -
51 #pragma mark APPEAR METHODS
52 /*************************************************************************/
53
54 - (void)performAppear
55 {
56     __idle = NO;
57     
58     [self setWindowVisibility:ITWindowAppearingState];
59     [self performAppearFromProgress:0.0 effectTime:_effectTime];
60 }
61
62 - (void)performAppearFromProgress:(float)progress effectTime:(float)time
63 {
64     [_window setEffectProgress:progress];
65     _effectSpeed = (1.0 / (EFFECT_FPS * time));
66     
67     if ( progress == 0.0 ) {
68         [self setPivot:315.0];
69         [_window setAlphaValue:0.0];
70     }
71     
72     [_window orderFront:self];
73     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
74                                                     target:self
75                                                   selector:@selector(appearStep)
76                                                   userInfo:nil
77                                                    repeats:YES];
78 }
79
80 - (void)appearStep
81 {
82     float interPivot = 0.0;
83     float progress   = ([_window effectProgress] + _effectSpeed);
84     
85     progress = ( (progress < 1.0) ? progress : 1.0 );
86     
87     [_window setEffectProgress:progress];
88     
89     interPivot = (( sin((progress * pi) - (pi / 2)) + 1 ) / 2);
90     [self setPivot:(315 + (interPivot * 45))];
91     [_window setAlphaValue:interPivot];
92     
93     if ( progress >= 1.0 ) {
94         [self appearFinish];
95     }
96 }
97
98 - (void)appearFinish
99 {
100     [_effectTimer invalidate];
101     _effectTimer = nil;
102     [self setWindowVisibility:ITWindowVisibleState];
103     
104     __idle = YES;
105     
106     if ( __shouldReleaseWhenIdle ) {
107         [self release];
108     }
109 }
110
111 - (void)cancelAppear
112 {
113     [self setWindowVisibility:ITWindowVanishingState];
114     
115     [_effectTimer invalidate];
116     _effectTimer = nil;
117     
118     [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
119 }
120
121
122 /*************************************************************************/
123 #pragma mark -
124 #pragma mark VANISH METHODS
125 /*************************************************************************/
126
127 - (void)performVanish
128 {
129     __idle = NO;
130     
131     [self setWindowVisibility:ITWindowVanishingState];
132     [self performVanishFromProgress:1.0 effectTime:_effectTime];
133 }
134
135 - (void)performVanishFromProgress:(float)progress effectTime:(float)time
136 {
137     [_window setEffectProgress:progress];
138     _effectSpeed = (1.0 / (EFFECT_FPS * time));
139     if ( progress == 1.0 ) {
140         [self setPivot:0.0];
141         [_window setAlphaValue:1.0];
142     }
143     
144     [_window orderFront:self];
145     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
146                                                     target:self
147                                                   selector:@selector(vanishStep)
148                                                   userInfo:nil
149                                                    repeats:YES];
150 }
151
152 - (void)vanishStep
153 {
154     float interPivot = 1.0;
155     float progress   = ([_window effectProgress] - _effectSpeed);
156     
157     progress = ( (progress > 0.0) ? progress : 0.0);
158     
159     [_window setEffectProgress:progress];
160     
161     interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
162     [self setPivot:(315 + (interPivot * 45))];
163     [_window setAlphaValue:interPivot];
164     
165     if ( progress <= 0.0 ) {
166         [self vanishFinish];
167     }
168 }
169
170 - (void)vanishFinish
171 {
172     [_effectTimer invalidate];
173     _effectTimer = nil;
174     [_window orderOut:self];
175     [_window setAlphaValue:1.0];
176     [self setPivot:0.0];
177     [self setWindowVisibility:ITWindowHiddenState];
178     
179     __idle = YES;
180     
181     if ( __shouldReleaseWhenIdle ) {
182         [self release];
183     }
184 }
185
186 - (void)cancelVanish
187 {
188     [self setWindowVisibility:ITWindowAppearingState];
189     
190     [_effectTimer invalidate];
191     _effectTimer = nil;
192     
193     [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
194 }
195
196
197 /*************************************************************************/
198 #pragma mark -
199 #pragma mark PRIVATE METHOD IMPLEMENTATIONS
200 /*************************************************************************/
201
202 - (void)setPivot:(float)angle
203 {
204     int hPos = [_window horizontalPosition];
205     int vPos = [_window verticalPosition];
206         NSRect winFrame = [_window frame];
207
208     if ( (hPos == ITWindowPositionCenter) || (vPos == ITWindowPositionMiddle) ) {
209     
210         CGAffineTransform transform;
211         NSPoint translation;
212         
213         translation.x = -winFrame.origin.x;
214         translation.y = winFrame.origin.y + winFrame.size.height - [[NSScreen mainScreen] frame].size.height;
215
216         transform = CGAffineTransformMakeTranslation( translation.x, translation.y );
217         
218         CGSSetWindowTransform([NSApp contextID],
219                               (CGSWindowID)[_window windowNumber],
220                               transform);
221     } else {
222         float  degAngle;
223         CGAffineTransform transform;
224         
225         if ( vPos == ITWindowPositionBottom ) {
226             if ( hPos == ITWindowPositionLeft ) {
227                 angle = angle;
228             } else if ( hPos == ITWindowPositionRight ) {
229                 angle = ( 45 - -(315 - angle) );
230             }
231         } else if ( vPos == ITWindowPositionTop ) {
232             if ( hPos == ITWindowPositionLeft ) {
233                 angle = ( 45 - -(315 - angle) );
234             } else if ( hPos == ITWindowPositionRight ) {
235                 angle = angle;
236             }
237         }
238         
239         degAngle  = (angle * (pi / 180));
240                 transform = CGAffineTransformMakeRotation(degAngle);
241                 
242                 if ( vPos == ITWindowPositionBottom ) {
243             transform.ty = winFrame.size.height;
244         } else if ( vPos == ITWindowPositionTop ) {
245                         transform.ty = 0;
246         }
247         
248         if ( hPos == ITWindowPositionLeft ) {
249             transform.tx = 0;
250         } else if ( hPos == ITWindowPositionRight ) {
251                         transform.tx = winFrame.size.width;
252         }
253                 
254                 transform = CGAffineTransformTranslate(transform, -winFrame.origin.x - transform.tx, winFrame.origin.y + winFrame.size.height - [[NSScreen mainScreen] frame].size.height - transform.ty);
255         CGSSetWindowTransform([NSApp contextID],
256                               (CGSWindowID)[_window windowNumber],
257                                                           transform );
258     }
259 }
260
261
262 @end