Fixed multi-monitorness except with Pivot, which is only half fixed.
[ITKit.git] / ITSlideHorizontallyWindowEffect.m
1 #import "ITSlideHorizontallyWindowEffect.h"
2 #import "ITCoreGraphicsHacks.h"
3 #import "ITTransientStatusWindow.h"
4
5
6 @interface ITSlideHorizontallyWindowEffect (Private)
7 - (void)performAppearFromProgress:(float)progress effectTime:(float)time;
8 - (void)appearStep;
9 - (void)appearFinish;
10 - (void)performVanishFromProgress:(float)progress effectTime:(float)time;
11 - (void)vanishStep;
12 - (void)vanishFinish;
13 - (void)setSlide:(float)distance;
14 @end
15
16
17 @implementation ITSlideHorizontallyWindowEffect
18
19
20 + (NSString *)effectName
21 {
22     return @"Slide Horizontally";
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:YES], @"Left",
34             [NSNumber numberWithBool:NO], @"Center",
35             [NSNumber numberWithBool:YES], @"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 400;
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         [_window setAlphaValue:0.0];
69     }
70
71     [_window orderFront:self];
72     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
73                                                     target:self
74                                                   selector:@selector(appearStep)
75                                                   userInfo:nil
76                                                    repeats:YES];
77 }
78
79 - (void)appearStep
80 {
81     float interSlide = 0.0;
82     [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
83     [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
84     interSlide = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
85     [self setSlide:( [_window frame].size.width - (interSlide * [_window frame].size.width) )];
86     [_window setAlphaValue:interSlide];
87
88     if ( [_window effectProgress] >= 1.0 ) {
89         [self appearFinish];
90     }
91 }
92
93 - (void)appearFinish
94 {
95     [_effectTimer invalidate];
96     _effectTimer = nil;
97     [self setWindowVisibility:ITWindowVisibleState];
98
99     __idle = YES;
100
101     if ( __shouldReleaseWhenIdle ) {
102         [self release];
103     }
104 }
105
106 - (void)cancelAppear
107 {
108     [self setWindowVisibility:ITWindowVanishingState];
109
110     [_effectTimer invalidate];
111     _effectTimer = nil;
112
113     [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 4.0)];
114 }
115
116
117 /*************************************************************************/
118 #pragma mark -
119 #pragma mark VANISH METHODS
120 /*************************************************************************/
121
122 - (void)performVanish
123 {
124     __idle = NO;
125
126     [self setWindowVisibility:ITWindowVanishingState];
127     [self performVanishFromProgress:1.0 effectTime:_effectTime];
128 }
129
130 - (void)performVanishFromProgress:(float)progress effectTime:(float)time
131 {
132     [_window setEffectProgress:progress];
133     _effectSpeed = (1.0 / (EFFECT_FPS * time));
134     if ( progress == 1.0 ) {
135         [_window setAlphaValue:1.0];
136     }
137
138     [_window orderFront:self];
139     _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
140                                                     target:self
141                                                   selector:@selector(vanishStep)
142                                                   userInfo:nil
143                                                    repeats:YES];
144 }
145
146 - (void)vanishStep
147 {
148     float interSlide = 1.0;
149     [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
150     [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
151     interSlide = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
152     [self setSlide:( [_window frame].size.width - (interSlide * [_window frame].size.width) )];
153     [_window setAlphaValue:interSlide];
154
155     if ( [_window effectProgress] <= 0.0 ) {
156         [self vanishFinish];
157     }
158 }
159
160 - (void)vanishFinish
161 {
162     [_effectTimer invalidate];
163     _effectTimer = nil;
164     [_window orderOut:self];
165     [_window setAlphaValue:1.0];
166     [self setSlide:0.0];
167     [self setWindowVisibility:ITWindowHiddenState];
168
169     __idle = YES;
170     
171     if ( __shouldReleaseWhenIdle ) {
172         [self release];
173     }
174 }
175
176 - (void)cancelVanish
177 {
178     [self setWindowVisibility:ITWindowAppearingState];
179
180     [_effectTimer invalidate];
181     _effectTimer = nil;
182
183     [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 4.0)];
184 }
185
186 - (void)setSlide:(float)distance
187 {
188     CGAffineTransform transform;
189     NSPoint translation;
190     NSRect winFrame = [_window frame];
191         
192     if ( [_window horizontalPosition] == ITWindowPositionLeft ) {
193         translation.x = ( -(winFrame.origin.x) + distance ) ;
194     } else if ( [_window horizontalPosition] == ITWindowPositionRight ) {
195         translation.x = ( -(winFrame.origin.x) - distance ) ;
196     } else {
197         translation.x = ( -(winFrame.origin.x) ) ;
198     }
199     
200         translation.y = winFrame.origin.y + winFrame.size.height - [[NSScreen mainScreen] frame].size.height;
201     
202     transform = CGAffineTransformMakeTranslation( translation.x, translation.y );
203     
204     CGSSetWindowTransform([NSApp contextID],
205                           (CGSWindowID)[_window windowNumber],
206                           transform);
207 }
208
209
210 @end