HUGE ITTSW Checkin. For those only interested in the short version, it is as
[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 /*************************************************************************/
21 #pragma mark -
22 #pragma mark APPEAR METHODS
23 /*************************************************************************/
24
25 - (void)performAppear
26 {
27     __idle = NO;
28     
29     [self setWindowVisibility:ITWindowAppearingState];
30     [self performAppearFromProgress:0.0 effectTime:_effectTime];
31 }
32
33 - (void)performAppearFromProgress:(float)progress effectTime:(float)time
34 {
35     [_window setEffectProgress:progress];
36     _effectSpeed = (1.0 / (EFFECT_FPS * time));
37     
38     if ( progress == 0.0 ) {
39         [self setPivot:315.0];
40         [_window setAlphaValue:0.0];
41     }
42
43     [_window orderFront:self];
44     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
45                                                     target:self
46                                                   selector:@selector(appearStep)
47                                                   userInfo:nil
48                                                    repeats:YES];
49 }
50
51 - (void)appearStep
52 {
53     float interPivot = 0.0;
54     [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
55     [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
56     interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
57     [self setPivot:((interPivot * 45) + 315)];
58     [_window setAlphaValue:interPivot];
59
60     if ( [_window effectProgress] >= 1.0 ) {
61         [self appearFinish];
62     }
63 }
64
65 - (void)appearFinish
66 {
67     [_effectTimer invalidate];
68     _effectTimer = nil;
69     [self setWindowVisibility:ITWindowVisibleState];
70
71     __idle = YES;
72
73     if ( __shouldReleaseWhenIdle ) {
74         [self release];
75     }
76 }
77
78 - (void)cancelAppear
79 {
80     [self setWindowVisibility:ITWindowVanishingState];
81
82     [_effectTimer invalidate];
83     _effectTimer = nil;
84
85     [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
86 }
87
88
89 /*************************************************************************/
90 #pragma mark -
91 #pragma mark VANISH METHODS
92 /*************************************************************************/
93
94 - (void)performVanish
95 {
96     __idle = NO;
97     
98     [self setWindowVisibility:ITWindowVanishingState];
99     [self performVanishFromProgress:1.0 effectTime:_effectTime];
100 }
101
102 - (void)performVanishFromProgress:(float)progress effectTime:(float)time
103 {
104     [_window setEffectProgress:progress];
105     _effectSpeed = (1.0 / (EFFECT_FPS * time));
106     if ( progress == 1.0 ) {
107         [self setPivot:0.0];
108         [_window setAlphaValue:1.0];
109     }
110
111     [_window orderFront:self];
112     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
113                                                     target:self
114                                                   selector:@selector(vanishStep)
115                                                   userInfo:nil
116                                                    repeats:YES];
117 }
118
119 - (void)vanishStep
120 {
121     float interPivot = 1.0;
122     [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
123     [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
124     interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
125     [self setPivot:((interPivot * 45) + 315)];
126     [_window setAlphaValue:interPivot];
127
128     if ( [_window effectProgress] <= 0.0 ) {
129         [self vanishFinish];
130     }
131 }
132
133 - (void)vanishFinish
134 {
135     [_effectTimer invalidate];
136     _effectTimer = nil;
137     [_window orderOut:self];
138     [_window setAlphaValue:1.0];
139     [self setPivot:0.0];
140     [self setWindowVisibility:ITWindowHiddenState];
141
142     __idle = YES;
143
144     if ( __shouldReleaseWhenIdle ) {
145         [self release];
146     }
147 }
148
149 - (void)cancelVanish
150 {
151     [self setWindowVisibility:ITWindowAppearingState];
152
153     [_effectTimer invalidate];
154     _effectTimer = nil;
155
156     [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
157 }
158
159
160 /*************************************************************************/
161 #pragma mark -
162 #pragma mark PRIVATE METHOD IMPLEMENTATIONS
163 /*************************************************************************/
164
165 - (void)setPivot:(float)angle
166 {
167     float degAngle = (angle * (pi / 180));
168
169     CGAffineTransform transform = CGAffineTransformMakeRotation(degAngle);
170     
171  // Set pivot rotation point
172     transform.tx = -32.0;
173     transform.ty = [_window frame].size.height + 32.0;
174
175     CGSSetWindowTransform([NSApp contextID],
176                           (CGSWindowID)[_window windowNumber],
177                           CGAffineTransformTranslate(transform,
178                                                      (([_window frame].origin.x - 32.0) * -1),
179                                                      (([[_window screen] frame].size.height - ([_window frame].origin.y) + 32.0) * -1) ));
180 }
181
182
183 @end