| Index | Submit class | Submit snippet | Submission feed | List |

NSWindow (UKFlipWindow)

Language: Objective-C, Author: Uli Kusterer
License: MIT/X11

An NSWindow category which replicates Dashboard's "flip over a window to see its back side" effect. I'm doing all of this manually (NSAffineTransform seems to only let you rotate and scale stuff), so it isn't blazingly fast, but maybe it's of use to someone.

NSWindow (UKFlipWindow) source preview

//
//  NSWindow_UKFlipWindow.m
//  WindowFlipper
//
//  Created by Uli Kusterer on 29.03.05.
//  Copyright 2005 M. Uli Kusterer. All rights reserved.
//  MIT Licensed

#import "NSWindow+UKFlipWindow.h"
#import <math.h>


#define NUM_FRAMES      8
#define SLICE_WIDTH     4
#define FRAME_INTERVAL  0.05

@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

NSWindow (UKFlipWindow) header preview

//
//  NSWindow_UKFlipWindow.h
//  WindowFlipper
//
//  Created by Uli Kusterer on 29.03.05.
//  Copyright 2005 M. Uli Kusterer. All rights reserved.
//  MIT Licensed

#import <Cocoa/Cocoa.h>

@interface NSWindow (UKFlipWindow)

-(void) flipWindowTransitionWithHalfwayMessage: (SEL)sel target: (id)targ;

// private:
-(void) takeSnapshot;
-(void) nextFlipAnimationFrame: (NSTimer*)sender;

@end
Download Archive

Compatible with:


Comments

Name

Website

Do you hate spammers? (Answer "Yes")