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

NSWindow (UKFade)

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

This is a little extension to NSWindow in the form of a category that adds a few methods for fading in/out a window.

NSWindow (UKFade) source preview

//
//  NSWindow+UKFade.m
//  TalkingMoose
//
//  Created by Uli Kusterer on 22.06.05.
//  Copyright 2005 M. Uli Kusterer. All rights reserved.
//

#import "NSWindow+UKFade.h"

static NSMutableDictionary*     pendingFades = nil;


@implementation NSWindow (UKFade)

-(void)     fadeInWithDuration: (NSTimeInterval)duration
{
    if( !pendingFades )
        pendingFades = [[NSMutableDictionary alloc] init];
    
    NSString*       key = [NSString stringWithFormat: @"%lx", self];
    NSDictionary*   fade = [pendingFades objectForKey: key];
    
    if( fade )      // Currently fading that window? Abort that fade:
        [[fade objectForKey: @"timer"] invalidate];  // No need to remove from pendingFades, we'll replace it in a moment.
    
    [self setAlphaValue: 0];
    [self orderFront: nil];
    
    NSTimeInterval  interval = duration / 0.1;
    float           stepSize = 1 / interval;
    NSTimer*        timer = [NSTimer scheduledTimerWithTimeInterval: 0.1        // scheduled since we also want "normal" run loop mode.
                                target: self selector: @selector(fadeInOneStep:)
                                userInfo: nil repeats: YES];
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSModalPanelRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode];
    [pendingFades setObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: timer, @"timer",
                                                [NSNumber numberWithFloat: stepSize], @"stepSize",
                                                nil] forKey: key];    // Releases of any old fades.
}


-(void) fadeInOneStep: (NSTimer*)timer
{
    NSString*   key = [NSString stringWithFormat: @"%lx", self];
    float       newAlpha = [self alphaValue] + [[[pendingFades objectForKey: key] objectForKey: @"stepSize"] floatValue];
    
    if( newAlpha >= 1.0 )
    {
        newAlpha = 1;
        [timer invalidate];
        [pendingFades removeObjectForKey: key];
    }
    
    //NSLog(@"Fading in: %f", newAlpha);    // DEBUG ONLY!
    [self setAlphaValue: newAlpha];
}


-(void)     fadeOutWithDuration: (NSTimeInterval)duration
{
    if( !pendingFades )
        pendingFades = [[NSMutableDictionary alloc] init];
    
    NSString*       key = [NSString stringWithFormat: @"%lx", self];
    NSDictionary*   fade = [pendingFades objectForKey: key];
    
    if( fade )      // Currently fading that window? Abort that fade:
        [[fade objectForKey: @"timer"] invalidate];  // No need to remove from pendingFades, we'll replace it in a moment.
    
    [self setAlphaValue: 1.0];
    
    NSTimeInterval  interval = duration / 0.1;
    float           stepSize = 1 / interval;
    NSTimer*        timer = [NSTimer scheduledTimerWithTimeInterval: 0.1        // scheduled since we also want "normal" run loop mode.
                                target: self selector: @selector(fadeOutOneStep:)
                                userInfo: nil repeats: YES];
    [pendingFades setObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: timer, @"timer",
                                                [NSNumber numberWithFloat: stepSize], @"stepSize",
                                                nil] forKey: key];    // Releases of any old fades.
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSModalPanelRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode];
}

-(void) fadeOutOneStep: (NSTimer*)timer
{
    NSString*        key = [NSString stringWithFormat: @"%lx", self];
  NSMutableDictionary*  currFadeDict = [[[pendingFades objectForKey: key] retain] autorelease];  // Make sure it doesn't go away in case we're cross-fading layers.
    float          newAlpha = [self alphaValue] - [[currFadeDict objectForKey: @"stepSize"] floatValue];
    
    if( newAlpha <= 0 )
    {
        [timer invalidate];
    
    [pendingFades removeObjectForKey: key];
    
    NSNumber*  newLevel = [currFadeDict objectForKey: @"newLevel"];
    if( newLevel )
    {
      NSTimer*        timer = [NSTimer scheduledTimerWithTimeInterval: 0.1        // scheduled since we also want "normal" run loop mode.
                                target: self selector: @selector(fadeInOneStep:)
                                userInfo: nil repeats: YES];
      [currFadeDict setObject: timer forKey: @"timer"];
      [pendingFades setObject: currFadeDict forKey: key];
      [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSModalPanelRunLoopMode];
      [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode];
      
      [self setLevel: [newLevel intValue]];
      //NSLog(@"Changing level to %u", [newLevel unsignedIntValue]);    // DEBUG ONLY!
      
      newAlpha = 0;
    }
    else
    {
      newAlpha = 1;           // Make opaque again so non-fading showing of window doesn't look unsuccessful.
      [self orderOut: nil];   // Hide so setAlphaValue below doesn't cause window to fade out, then pop in again.
    }
    }

  //NSLog(@"Fading out: %f", newAlpha);    // DEBUG ONLY!
  [self setAlphaValue: newAlpha];
}


-(void)  fadeToLevel: (int)lev withDuration: (NSTimeInterval)duration
{
    if( !pendingFades )
        pendingFades = [[NSMutableDictionary alloc] init];
    
    NSString*       key = [NSString stringWithFormat: @"%lx", self];
    NSDictionary*   fade = [pendingFades objectForKey: key];
    
    if( fade )      // Currently fading that window? Abort that fade:
        [[fade objectForKey: @"timer"] invalidate];  // No need to remove from pendingFades, we'll replace it in a moment.
    
    [self setAlphaValue: 1.0];
    
    NSTimeInterval  interval = (duration /2) / 0.1;
    float           stepSize = 1 / interval;
    NSTimer*        timer = [NSTimer scheduledTimerWithTimeInterval: 0.1        // scheduled since we also want "normal" run loop mode.
                                target: self selector: @selector(fadeOutOneStep:)
                                userInfo: nil repeats: YES];
    [pendingFades setObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: timer, @"timer",
                                                [NSNumber numberWithFloat: stepSize], @"stepSize",
                                                [NSNumber numberWithInt: lev], @"newLevel",
                                                nil] forKey: key];    // Releases of any old fades.
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSModalPanelRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode];
}


@end

NSWindow (UKFade) header preview

//
//  NSWindow+UKFade.h
//  TalkingMoose
//
//  Created by Uli Kusterer on 22.06.05.
//  Copyright 2005 M. Uli Kusterer. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface NSWindow (UKFade)

-(void)     fadeInWithDuration: (NSTimeInterval)duration;
-(void)     fadeOutWithDuration: (NSTimeInterval)duration;
-(void)    fadeToLevel: (int)lev withDuration: (NSTimeInterval)duration;

// Private:
-(void)     fadeInOneStep: (NSTimer*)timer;
-(void)     fadeOutOneStep: (NSTimer*)timer;

@end
Download Archive

Compatible with:


Comments

Name

Website

Do you hate spammers? (Answer "Yes")