Checking in improvements to the effect availability heuristic.
[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     [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
84     [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
85     interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
86     [self setPivot:((interPivot * 45) + 315)];
87     [_window setAlphaValue:interPivot];
88
89     if ( [_window effectProgress] >= 1.0 ) {
90         [self appearFinish];
91     }
92 }
93
94 - (void)appearFinish
95 {
96     [_effectTimer invalidate];
97     _effectTimer = nil;
98     [self setWindowVisibility:ITWindowVisibleState];
99
100     __idle = YES;
101
102     if ( __shouldReleaseWhenIdle ) {
103         [self release];
104     }
105 }
106
107 - (void)cancelAppear
108 {
109     [self setWindowVisibility:ITWindowVanishingState];
110
111     [_effectTimer invalidate];
112     _effectTimer = nil;
113
114     [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
115 }
116
117
118 /*************************************************************************/
119 #pragma mark -
120 #pragma mark VANISH METHODS
121 /*************************************************************************/
122
123 - (void)performVanish
124 {
125     __idle = NO;
126     
127     [self setWindowVisibility:ITWindowVanishingState];
128     [self performVanishFromProgress:1.0 effectTime:_effectTime];
129 }
130
131 - (void)performVanishFromProgress:(float)progress effectTime:(float)time
132 {
133     [_window setEffectProgress:progress];
134     _effectSpeed = (1.0 / (EFFECT_FPS * time));
135     if ( progress == 1.0 ) {
136         [self setPivot:0.0];
137         [_window setAlphaValue:1.0];
138     }
139
140     [_window orderFront:self];
141     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
142                                                     target:self
143                                                   selector:@selector(vanishStep)
144                                                   userInfo:nil
145                                                    repeats:YES];
146 }
147
148 - (void)vanishStep
149 {
150     float interPivot = 1.0;
151     [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
152     [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
153     interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
154     [self setPivot:((interPivot * 45) + 315)];
155     [_window setAlphaValue:interPivot];
156
157     if ( [_window effectProgress] <= 0.0 ) {
158         [self vanishFinish];
159     }
160 }
161
162 - (void)vanishFinish
163 {
164     [_effectTimer invalidate];
165     _effectTimer = nil;
166     [_window orderOut:self];
167     [_window setAlphaValue:1.0];
168     [self setPivot:0.0];
169     [self setWindowVisibility:ITWindowHiddenState];
170
171     __idle = YES;
172
173     if ( __shouldReleaseWhenIdle ) {
174         [self release];
175     }
176 }
177
178 - (void)cancelVanish
179 {
180     [self setWindowVisibility:ITWindowAppearingState];
181
182     [_effectTimer invalidate];
183     _effectTimer = nil;
184
185     [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
186 }
187
188
189 /*************************************************************************/
190 #pragma mark -
191 #pragma mark PRIVATE METHOD IMPLEMENTATIONS
192 /*************************************************************************/
193
194 - (void)setPivot:(float)angle
195 {
196     float degAngle;
197     NSPoint appearPoint;
198     CGAffineTransform transform;
199     
200     if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) {
201         if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) {
202             degAngle = (angle * (pi / 180));
203         } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) {
204             degAngle = (-angle * (pi / 180));
205         }
206     } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) {
207         if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) {
208             degAngle = (angle * (pi / 180));
209         } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) {
210             degAngle = (angle * (pi / 180));
211         }
212     }
213     
214     transform = CGAffineTransformMakeRotation(degAngle);
215     
216  // Set pivot rotation point
217     //transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x );
218     transform.ty = ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y );
219     
220     if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) {
221         appearPoint.x = -( 32.0 + [[_window screen] visibleFrame].origin.x );
222         transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x );
223     } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) {
224         transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x ) + [_window frame].size.width;
225         appearPoint.x = -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 64.0);
226     } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionCenter ) {
227         appearPoint.x = ( [_window frame].size.width - [[_window screen] visibleFrame].size.width ) / 2;
228     }
229     
230     if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) {
231         appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2;
232     } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) {
233         appearPoint.y = -( [[_window screen] frame].size.height - ([_window frame].origin.y) + 32.0 + [[_window screen] visibleFrame].origin.y) ;
234     }/* else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionMiddle ) {
235         appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2;
236     }*/
237     CGSSetWindowTransform([NSApp contextID],
238                           (CGSWindowID)[_window windowNumber],
239                           CGAffineTransformTranslate( transform,
240                                                      appearPoint.x,
241                                                      appearPoint.y ) );
242 }
243
244 @end