// // UKWindowFlipperAppDelegate.m // WindowFlipper // // Created by Uli Kusterer on 29.03.05. // Copyright 2005 M. Uli Kusterer. All rights reserved. // #import "UKWindowFlipperAppDelegate.h" #import <math.h> #define NUM_FRAMES 8 #define SLICE_WIDTH 4 #define FRAME_INTERVAL 0.05 @implementation UKWindowFlipperAppDelegate -(void) resetAnimationFrame: (id)sender { [win flipWindowTransitionWithHalfwayMessage: @selector(pageSwitch:) target: self]; } -(void) pageSwitch: (id)sender { [tv selectTabViewItemAtIndex: ![tv indexOfTabViewItem: [tv selectedTabViewItem]]]; } @end @implementation NSWindow (UKFlipWindow) NSImage* gVirginImage = nil; NSImageView* gAnimationImageView = nil; NSTimer* gAnimationTimer = nil; int gCurrAnimationFrame = 0; SEL gHalfwayMessage = 0; id gHalfwayMsgTarget = nil; -(void) flipWindowTransitionWithHalfwayMessage: (SEL)sel target: (id)targ { NSRect cRect = [self contentRectForFrameRect: [self frame]]; NSWindow* overlay = [[NSWindow alloc] initWithContentRect: cRect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: YES]; [overlay setHasShadow: NO]; [overlay setOpaque: NO]; [overlay setBackgroundColor: [NSColor clearColor]]; gHalfwayMsgTarget = targ; gHalfwayMessage = sel; cRect.origin = NSZeroPoint; gAnimationImageView = [[[NSImageView alloc] initWithFrame: cRect] autorelease]; [gAnimationImageView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [[overlay contentView] addSubview: gAnimationImageView]; [self takeSnapshot]; gAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval: FRAME_INTERVAL target: self selector:@selector(nextFlipAnimationFrame:) userInfo: nil repeats: YES] retain]; } -(void) takeSnapshot { NSView* borderView = [[self contentView] superview]; NSData* pdfData = [borderView dataWithPDFInsideRect: [borderView frame]]; gVirginImage = [[NSImage alloc] initWithData: pdfData]; [gAnimationImageView setImage: gVirginImage]; NSRect box = NSInsetRect([self frame], -18, -18 ); [[gAnimationImageView window] setFrame: box display: NO]; [[gAnimationImageView window] orderFront: nil]; [self orderOut: nil]; } -(void) nextFlipAnimationFrame: (NSTimer*)sender { NSImage* destImg = gVirginImage; NSRect vSrcStrip = { { 0, 0 }, { 0, 0 } }, vDstStrip, vFillStrip; NSSize wdSize = [gVirginImage size]; float x = 0; float stepSize = wdSize.height / wdSize.width; if( gCurrAnimationFrame < NUM_FRAMES ) { destImg = [[[NSImage alloc] initWithSize: wdSize] autorelease]; stepSize -= stepSize / 20 * (20 -gCurrAnimationFrame); [destImg lockFocus]; for( x = 0; x < wdSize.width; x += SLICE_WIDTH ) { vSrcStrip.origin.x = x; vSrcStrip.size.height = wdSize.height; vSrcStrip.size.width = SLICE_WIDTH; vDstStrip = vSrcStrip; vDstStrip.origin.x = x; vDstStrip.size.height -= (wdSize.width -x) * stepSize; vDstStrip.origin.y += (wdSize.height -vDstStrip.size.height) / 2; [gVirginImage drawInRect: vDstStrip fromRect: vSrcStrip operation: NSCompositeCopy fraction:1.0]; } [destImg unlockFocus]; [destImg setScalesWhenResized: YES]; [destImg setSize: NSMakeSize( fmaxf(1,(wdSize.width / NUM_FRAMES) * (NUM_FRAMES -1 -gCurrAnimationFrame)), wdSize.height)]; gCurrAnimationFrame++; } else if( gCurrAnimationFrame < (NUM_FRAMES *2) ) { float cf = gCurrAnimationFrame -NUM_FRAMES; destImg = [[[NSImage alloc] initWithSize: wdSize] autorelease]; if( gCurrAnimationFrame == NUM_FRAMES ) { [gHalfwayMsgTarget performSelector: gHalfwayMessage withObject: self]; [self takeSnapshot]; } stepSize -= stepSize / NUM_FRAMES * (cf +1); [destImg lockFocus]; for( x = 0; x < wdSize.width; x += SLICE_WIDTH ) { vSrcStrip.origin.x = (wdSize.width) -x; vSrcStrip.size.height = wdSize.height; vSrcStrip.size.width = SLICE_WIDTH; vDstStrip = vSrcStrip; vDstStrip.origin.x = (wdSize.width) -x; vDstStrip.size.height -= (wdSize.width -x) * stepSize; vDstStrip.origin.y += (wdSize.height -vDstStrip.size.height) / 2; [gVirginImage drawInRect: vDstStrip fromRect: vSrcStrip operation: NSCompositeCopy fraction:1.0]; } [destImg unlockFocus]; [destImg setScalesWhenResized: YES]; [destImg setSize: NSMakeSize( fmaxf(1,(wdSize.width / NUM_FRAMES) * cf), wdSize.height)]; gCurrAnimationFrame++; } else if( gCurrAnimationFrame == (NUM_FRAMES *2) ) { [gAnimationImageView setImage: gVirginImage]; [self makeKeyAndOrderFront: nil]; [[gAnimationImageView window] orderOut: nil]; [gAnimationTimer autorelease]; [gAnimationTimer invalidate]; gAnimationTimer = nil; [gVirginImage release]; gVirginImage = nil; [[gAnimationImageView window] release]; gAnimationImageView = nil; gCurrAnimationFrame = 0; } if( destImg != gVirginImage && gAnimationImageView != nil ) { wdSize = [destImg size]; wdSize.height += 32; wdSize.width += 32; NSImage* shadedImg = [[[NSImage alloc] initWithSize: wdSize] autorelease]; NSShadow* shad = [[[NSShadow alloc] init] autorelease]; NSPoint paintPoint = { 16, 16 }; [shadedImg lockFocus]; [NSGraphicsContext saveGraphicsState]; [shad setShadowOffset: NSMakeSize(0,-8)]; [shad setShadowBlurRadius: 16]; [shad setShadowColor: [NSColor colorWithCalibratedWhite: 0 alpha: 0.8]]; [shad set]; [destImg compositeToPoint: paintPoint operation: NSCompositeSourceOver]; [NSGraphicsContext restoreGraphicsState]; [destImg compositeToPoint: paintPoint operation: NSCompositeSourceOver]; [shadedImg unlockFocus]; [gAnimationImageView setImage: shadedImg]; } } @end |