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];
197 rippleRect.origin.y = - (NSMaxY(rippleRect) - screenRect.size.height);
199 _effectWindow = [[NSWindow alloc] initWithContentRect:_ripple ? NSInsetRect([_window frame], -200, -200) : [_window frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
200 [_effectWindow setBackgroundColor:[NSColor clearColor]];
201 [_effectWindow setAlphaValue:1.0];
202 [_effectWindow setOpaque:NO];
203 [_effectWindow setHasShadow:NO];
204 [_effectWindow setContentView:[[ITCoreImageView alloc] initWithFrame:[_window frame]]];
205 [_effectWindow setLevel:[_window level]];
207 [_effectWindow orderFrontRegardless];
208 [_window orderWindow:NSWindowAbove relativeTo:[_effectWindow windowNumber]];
211 _effectFilter = [[CIFilter filterWithName:@"CIShapedWaterRipple"] retain];
212 [_effectFilter setDefaults];
213 [_effectFilter setValue:[NSNumber numberWithFloat:50.0] forKey:@"inputCornerRadius"];
214 [_effectFilter setValue:[CIVector vectorWithX:rippleRect.origin.x Y:rippleRect.origin.y] forKey:@"inputPoint0"];
215 [_effectFilter setValue:[CIVector vectorWithX:(rippleRect.origin.x + rippleRect.size.width) Y:(rippleRect.origin.y + rippleRect.size.height)] forKey:@"inputPoint1"];
216 [_effectFilter setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputPhase"];
218 _effectFilter = [[CIFilter filterWithName:@"CIZoomBlur"] retain];
219 [_effectFilter setDefaults];
220 [_effectFilter setValue:[CIVector vectorWithX:(rippleRect.origin.x + rippleRect.size.width / 2) Y:(rippleRect.origin.y + rippleRect.size.height / 2)] forKey:@"inputCenter"];
223 _windowFilter = [[CICGSFilter filterWithFilter:_effectFilter connectionID:[NSApp contextID]] retain];
224 [_windowFilter addToWindow:(CGSWindowID)[_effectWindow windowNumber] flags:1];
226 [NSThread detachNewThreadSelector:@selector(runFilterAnimation:) toTarget:self withObject:self];
229 - (void)runFilterAnimation:(id)sender
231 NSAutoreleasePool *pool;
232 CICGSFilter *oldFilter;
233 CFAbsoluteTime startTime, time;
234 CGSWindowID windowNumber = (CGSWindowID)[_effectWindow windowNumber];
236 pool = [[NSAutoreleasePool alloc] init];
238 startTime = CFAbsoluteTimeGetCurrent();
239 time = CFAbsoluteTimeGetCurrent();
241 while (time < (startTime + 2.5) && (time >= startTime)) {
242 oldFilter = _windowFilter;
244 [_effectFilter setValue:[NSNumber numberWithFloat:160*(time - startTime)] forKey:@"inputPhase"];
246 [_effectFilter setValue:[NSNumber numberWithFloat:5 * (time - startTime)] forKey:@"inputAmount"];
248 _windowFilter = [[CICGSFilter filterWithFilter:_effectFilter connectionID:[NSApp contextID]] retain];
249 [_windowFilter addToWindow:windowNumber flags:1];
250 [oldFilter removeFromWindow:windowNumber];
252 time = CFAbsoluteTimeGetCurrent();
255 [_windowFilter removeFromWindow:windowNumber];
256 [_windowFilter release];
257 [_effectFilter release];
258 [_effectWindow orderOut:self];
259 [[_effectWindow contentView] release];
260 [_effectWindow release];