File: programming/cocoa/WindowFlipper.zip/WindowFlipper/UKWindowFlipperAppDelegate.m


//
//  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

This code uses the PclZip Zip File reading code, which is subject to the GNU LGPL. It also uses the GeSHi syntax highlighter, subject to the GPL. Ask if you want this for your own web site, it's free.