1// 2// PXAboutController.m 3// Pixen-XCode 4// 5// Created by Andy Matuschak on Sun Aug 01 2004. 6// Copyright (c) 2004 Open Sword Group. All rights reserved. 7// 8 9#import "PXAboutController.h" 10#import "PXAboutPanel.h" 11 12#import <Foundation/NSArray.h> 13#import <Foundation/NSBundle.h> 14#import <Foundation/NSData.h> 15#import <Foundation/NSDictionary.h> 16#import <Foundation/NSNotification.h> 17#import <Foundation/NSTimer.h> 18#import <Foundation/NSValue.h> 19 20#import <AppKit/NSApplication.h> 21#import <AppKit/NSTextStorage.h> 22#import <AppKit/NSTextView.h> 23 24static PXAboutController *singleInstance = nil; 25 26@implementation PXAboutController 27 28-(id) init 29{ 30 if ( singleInstance ) 31 { 32 [self dealloc]; 33 return singleInstance; 34 } 35 36 37 if ( ! ( self = [super init] ) ) 38 return nil; 39 40 if ( ! [NSBundle loadNibNamed :@"PXAbout" owner:self] ) 41 NSLog(@"Warm the user"); 42 43 singleInstance = self; 44 45 return singleInstance; 46} 47 48+(id) sharedAboutController 49{ 50 if ( ! singleInstance ) 51 singleInstance = [[self alloc] init]; 52 53 return singleInstance; 54} 55 56 57- (void)loadCreditsText 58{ 59 id linkString = [NSString stringWithFormat:@"<a href=\"http://www.opensword.org/license.php\">MIT License</a>"]; 60 61 id plainString = [[[NSMutableString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Credits" ofType:@"html"]] autorelease]; 62 63 [plainString replaceOccurrencesOfString:@"<PXLICENSE>" 64 withString:linkString 65 options:nil 66 range:NSMakeRange(0,[(NSString *)plainString length])]; 67 68 69#ifdef __COCOA__ 70 NSData *htmlData = [NSData dataWithBytes:[plainString cString] length:[(NSString *)plainString length]]; 71 NSDictionary *attributedOptions = [NSDictionary dictionaryWithObject:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]] forKey:@"BaseURL"]; 72 NSAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithHTML:htmlData options:attributedOptions documentAttributes:nil] autorelease]; 73 [[credits textStorage] setAttributedString:attributedString]; 74#else 75 [credits setString :plainString]; 76#endif 77} 78 79 80 81- (void)createPanel 82{ 83 id content; 84 aboutPanel = [[PXAboutPanel alloc] 85 initWithContentRect:[[panelInNib contentView] frame] 86 styleMask:NSBorderlessWindowMask 87 backing:[panelInNib backingType] 88 defer:NO]; 89 90 [aboutPanel setBackgroundColor: [NSColor whiteColor]]; 91 [aboutPanel setHasShadow: YES]; 92 [aboutPanel setNextResponder: self]; 93 [aboutPanel setBecomesKeyOnlyIfNeeded: NO]; 94 [aboutPanel setDelegate: self]; 95 [aboutPanel setLevel:NSModalPanelWindowLevel]; 96 97 98 content = [[panelInNib contentView] retain]; 99 [content removeFromSuperview]; 100 [(PXAboutPanel *)aboutPanel setContentView:content]; 101 [content release]; 102} 103 104// Watch for notifications that the application is no longer active, or that 105// another window has replaced the About panel as the main window, and hide 106// on either of these notifications. 107- (void) watchForNotificationsWhichShouldHidePanel 108{ 109 // This works better than just making the panel hide when the app 110 // deactivates (setHidesOnDeactivate:YES), because if we use that 111 // then the panel will return when the app reactivates. 112 [[NSNotificationCenter defaultCenter] addObserver: self 113 selector: @selector(hidePanel) 114 name: NSApplicationDidResignActiveNotification 115 object: nil]; 116 117 // If the panel is no longer main, hide it. 118 // (We could also use the delegate notification for this.) 119 [[NSNotificationCenter defaultCenter] addObserver: self 120 selector: @selector(hidePanel) 121 name: NSWindowDidResignMainNotification 122 object: aboutPanel]; 123 124 [[NSNotificationCenter defaultCenter] addObserver: self 125 selector: @selector(hidePanel) 126 name: NSWindowDidResignKeyNotification 127 object: aboutPanel]; 128} 129 130- (void)dealloc 131{ 132 [aboutPanel release]; 133 [[NSNotificationCenter defaultCenter] removeObserver:self]; 134 [super dealloc]; 135} 136 137- (void)setupPanel 138{ 139 [self createPanel]; 140 [self loadCreditsText]; 141 [aboutPanel center]; 142 [self watchForNotificationsWhichShouldHidePanel]; 143} 144 145- (void)showPanel:(id) sender 146{ 147 if (!aboutPanel) 148 { 149 [self setupPanel]; 150 } 151 [aboutPanel setAlphaValue:0.0]; 152 [aboutPanel makeKeyAndOrderFront:nil]; 153 [fadeTimer invalidate]; 154 [fadeTimer release]; 155 fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.05 156 target:self 157 selector:@selector(fade:) 158 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:0.0], @"opacity", 159 [NSNumber numberWithFloat:.1], @"direction", 160 nil] repeats:NO] retain]; 161} 162 163 164- (void)hidePanel 165{ 166 [fadeTimer invalidate]; 167 [fadeTimer release]; 168 169 fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.05 170 target:self 171 selector:@selector(fade:) 172 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:1.0], @"opacity", 173 [NSNumber numberWithFloat:-.1],@"direction", 174 nil] repeats:NO] retain]; 175 //[aboutPanel orderOut:nil]; 176} 177 178 179- (void)fade:(NSTimer *)timer 180{ 181 float alphaValue = [[[timer userInfo] objectForKey:@"opacity"] floatValue]; 182 float fadeDirection = [[[timer userInfo] objectForKey:@"direction"] floatValue]; 183 [aboutPanel setAlphaValue:alphaValue]; 184 [fadeTimer invalidate]; 185 [fadeTimer release]; 186 187 if ( ( (alphaValue > 0 ) && ( fadeDirection < 0 ) ) 188 || ( (alphaValue < 1) && (fadeDirection > 0 ) ) ) 189 { 190 fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.02 191 target:self 192 selector:@selector(fade:) 193 userInfo:[NSDictionary dictionaryWithObjectsAndKeys: 194 [NSNumber numberWithFloat:alphaValue+fadeDirection], @"opacity", 195 [NSNumber numberWithFloat:fadeDirection], @"direction", 196 nil] repeats:NO] retain]; 197 } 198 else 199 { 200 fadeTimer = nil; 201 //[aboutPanel setAlphaValue:1.0 - alphaValue]; 202 if (alphaValue <= 0) { 203 [aboutPanel orderOut:nil]; 204 } 205 } 206} 207 208- (void)mouseDown:(NSEvent *) event 209{ 210 [self hidePanel]; 211} 212 213@end 214