1 #import "ITCoreImageWindowEffect.h"
2 #import "ITTransientStatusWindow.h"
3 #import "ITCoreGraphicsHacks.h"
4 #import "ITCoreImageView.h"
6 @interface ITCoreImageWindowEffect (Private)
7 - (void)performAppearFromProgress:(float)progress effectTime:(float)time;
10 - (void)performVanishFromProgress:(float)progress effectTime:(float)time;
17 @implementation ITCoreImageWindowEffect
19 + (NSString *)effectName
21 return @"Core Image - Ripple";
24 + (NSDictionary *)supportedPositions
26 return [NSDictionary dictionaryWithObjectsAndKeys:
27 [NSDictionary dictionaryWithObjectsAndKeys:
28 [NSNumber numberWithBool:YES], @"Left",
29 [NSNumber numberWithBool:YES], @"Center",
30 [NSNumber numberWithBool:YES], @"Right", nil] , @"Top" ,
31 [NSDictionary dictionaryWithObjectsAndKeys:
32 [NSNumber numberWithBool:YES], @"Left",
33 [NSNumber numberWithBool:YES], @"Center",
34 [NSNumber numberWithBool:YES], @"Right", nil] , @"Middle" ,
35 [NSDictionary dictionaryWithObjectsAndKeys:
36 [NSNumber numberWithBool:YES], @"Left",
37 [NSNumber numberWithBool:YES], @"Center",
38 [NSNumber numberWithBool:YES], @"Right", nil] , @"Bottom" , nil];
41 + (unsigned int)listOrder
46 /*************************************************************************/
48 #pragma mark APPEAR METHODS
49 /*************************************************************************/
55 [self setWindowVisibility:ITWindowAppearingState];
56 [self performAppearFromProgress:0.0 effectTime:_effectTime];
59 - (void)performAppearFromProgress:(float)progress effectTime:(float)time
61 [_window setEffectProgress:progress];
62 _effectSpeed = (1.0 / (EFFECT_FPS * time));
64 if ( progress == 0.0 ) {
65 [_window setAlphaValue:0.0];
68 [_window orderFront:self];
70 _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
72 selector:@selector(appearStep)
80 float interFade = 0.0;
81 [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
82 [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
83 interFade = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
84 [_window setAlphaValue:interFade];
86 if ( [_window effectProgress] >= 1.0 ) {
93 [_effectTimer invalidate];
96 [self setWindowVisibility:ITWindowVisibleState];
99 if ( __shouldReleaseWhenIdle ) {
106 [self setWindowVisibility:ITWindowVanishingState];
108 [_effectTimer invalidate];
111 [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
115 /*************************************************************************/
117 #pragma mark VANISH METHODS
118 /*************************************************************************/
120 - (void)performVanish
124 [self setWindowVisibility:ITWindowVanishingState];
125 [self performVanishFromProgress:1.0 effectTime:_effectTime];
128 - (void)performVanishFromProgress:(float)progress effectTime:(float)time
130 [_window setEffectProgress:progress];
131 _effectSpeed = (1.0 / (EFFECT_FPS * time));
132 if ( progress == 1.0 ) {
133 [_window setAlphaValue:1.0];
136 [_window orderFront:self];
138 _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
140 selector:@selector(vanishStep)
148 float interFade = 1.0;
149 [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
150 [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
151 interFade = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
152 [_window setAlphaValue:interFade];
154 if ( [_window effectProgress] <= 0.0 ) {
161 [_effectTimer invalidate];
163 [_window orderOut:self];
164 [_window setAlphaValue:1.0];
166 [self setWindowVisibility:ITWindowHiddenState];
170 if ( __shouldReleaseWhenIdle ) {
177 [self setWindowVisibility:ITWindowVanishingState];
179 [_effectTimer invalidate];
182 [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
185 /*************************************************************************/
187 #pragma mark CORE IMAGE METHODS
188 /*************************************************************************/
192 NSRect rippleRect = [_window frame];
193 NSRect screenRect = [[_window screen] frame];
195 rippleRect.origin.y = - (NSMaxY(rippleRect) - screenRect.size.height);
197 _effectWindow = [[NSWindow alloc] initWithContentRect:NSInsetRect([_window frame], -200, -200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
198 [_effectWindow setBackgroundColor:[NSColor clearColor]];
199 [_effectWindow setAlphaValue:1.0];
200 [_effectWindow setOpaque:NO];
201 [_effectWindow setHasShadow:NO];
202 [_effectWindow setContentView:[[ITCoreImageView alloc] initWithFrame:[_window frame]]];
203 [_effectWindow setLevel:[_window level]];
205 [_effectWindow orderFrontRegardless];
206 [_window orderWindow:NSWindowAbove relativeTo:[_effectWindow windowNumber]];
208 _effectFilter = [[CIFilter filterWithName:@"CIShapedWaterRipple"] retain];
209 [_effectFilter setDefaults];
210 [_effectFilter setValue:[NSNumber numberWithFloat:50.0] forKey:@"inputCornerRadius"];
211 [_effectFilter setValue:[CIVector vectorWithX:rippleRect.origin.x Y:rippleRect.origin.y] forKey:@"inputPoint0"];
212 [_effectFilter setValue:[CIVector vectorWithX:(rippleRect.origin.x + rippleRect.size.width) Y:(rippleRect.origin.y + rippleRect.size.height)] forKey:@"inputPoint1"];
213 [_effectFilter setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputPhase"];
215 _windowFilter = [[CICGSFilter filterWithFilter:_effectFilter connectionID:[NSApp contextID]] retain];
216 [_windowFilter addToWindow:(CGSWindowID)[_effectWindow windowNumber] flags:1];
218 [NSThread detachNewThreadSelector:@selector(runFilterAnimation:) toTarget:self withObject:self];
221 - (void)runFilterAnimation:(id)sender
223 NSAutoreleasePool *pool;
224 CICGSFilter *oldFilter;
225 CFAbsoluteTime startTime, time;
226 CGSWindowID windowNumber = (CGSWindowID)[_effectWindow windowNumber];
228 pool = [[NSAutoreleasePool alloc] init];
230 startTime = CFAbsoluteTimeGetCurrent();
231 time = CFAbsoluteTimeGetCurrent();
233 while (time < (startTime + 2.5) && (time >= startTime)) {
234 oldFilter = _windowFilter;
235 [_effectFilter setValue:[NSNumber numberWithFloat:160*(time - startTime)] forKey:@"inputPhase"];
236 _windowFilter = [[CICGSFilter filterWithFilter:_effectFilter connectionID:[NSApp contextID]] retain];
237 [_windowFilter addToWindow:windowNumber flags:1];
238 [oldFilter removeFromWindow:windowNumber];
240 time = CFAbsoluteTimeGetCurrent();
243 [_windowFilter removeFromWindow:windowNumber];
244 [_windowFilter release];
245 [_effectFilter release];
246 [_effectWindow orderOut:self];
247 [[_effectWindow contentView] release];
248 [_effectWindow release];