1#import "PXPreviewController.h" 2#import "PXCanvas.h" 3#import "PXCanvasView.h" 4#import "PXDocument.h" 5#import "PXGrid.h" 6#import "PXMonotoneBackground.h" 7#import "PXCrosshair.h" 8#import "PXPreviewResizeSizeView.h" 9 10#ifndef __COCOA__ 11#include <math.h> 12#endif 13 14@implementation PXPreviewController 15 16+ sharedPreviewController 17{ 18 static id instance = nil; 19 if(instance == nil) { instance = [[self alloc] init]; } 20 return instance; 21} 22 23- (void)windowWillClose:notification 24{ 25 if (!temporarilyHiding) { 26 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PXPreviewWindowIsOpen"]; 27 } 28} 29 30- (void)documentClosed:(NSNotification *)notification 31{ 32 if ([[notification object] canvas] == canvas) { 33 [self setCanvas:nil]; 34 } 35} 36 37- init 38{ 39 [super initWithWindowNibName:@"PXPreview"]; 40 [NSTimer scheduledTimerWithTimeInterval:0.5 41 target:self selector:@selector(shouldRedraw:) 42 userInfo:nil 43 repeats:YES]; 44 updateRect = NSMakeRect(0,0,0,0); 45 46 [[self window] setFrameAutosaveName:@"PXPreviewFrame"]; 47 resizeSizeWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 60, 27) 48 styleMask:NSBorderlessWindowMask 49 backing:NSBackingStoreBuffered 50 defer:YES]; 51 [resizeSizeWindow setOpaque:NO]; 52 [resizeSizeWindow setContentView:[[[PXPreviewResizeSizeView alloc] 53 initWithFrame:NSMakeRect(0, 0, 60, 27)] 54 autorelease]]; 55 56 [resizeSizeWindow setLevel:NSPopUpMenuWindowLevel]; 57 [[NSNotificationCenter defaultCenter] addObserver:self 58 selector:@selector(documentClosed:) 59 name:PXDocumentClosed 60 object:nil]; 61 temporarilyHiding = NO; 62 63 [(NSPanel *)[self window] setBecomesKeyOnlyIfNeeded:YES]; 64 65 return self; 66} 67 68- (void)dealloc 69{ 70 [fadeOutTimer invalidate]; 71 [fadeOutTimer dealloc]; 72 73 [resizeSizeWindow release]; 74 [[NSUserDefaults standardUserDefaults] setBool:([[self window] isVisible] || temporarilyHiding) forKey:@"PXPreviewWindowIsOpen"]; 75 76 [[NSNotificationCenter defaultCenter] removeObserver:self]; 77 78 [super dealloc]; 79} 80 81- (void)shouldRedraw:timer 82{ 83 if (NSIsEmptyRect(updateRect)) 84 { 85 NSLog(@"plop plop"); 86 return; 87 } 88 89 if ([[self window] isVisible]) 90 { 91 [view setNeedsDisplayInCanvasRect:updateRect]; 92 updateRect = NSZeroRect; 93 } 94} 95 96- (void)windowDidLoad 97{ 98 [[self window] setBackgroundColor:[NSColor lightGrayColor]]; 99 [view setMainBackground:[[[PXMonotoneBackground alloc] init] autorelease]]; 100 [view setAlternateBackground:[[[PXMonotoneBackground alloc] init] autorelease]]; 101 [view setCrosshair:nil]; 102 [[view grid] setShouldDraw:NO]; 103 if([[NSUserDefaults standardUserDefaults] boolForKey:@"PXPreviewWindowIsOpen"]) 104 { 105 [[self window] display]; 106 } 107 else 108 { 109 [[self window] close]; 110 } 111} 112 113- (void)sizeToCanvas 114{ 115 if (canvas == nil) 116 { 117 [view setFrame:NSMakeRect(0,0,64,64)]; 118 return; 119 } 120 121 NSSize newSize = [[[self window] contentView] frame].size; 122 NSPoint newOrigin = [view frame].origin; 123 124 if ([canvas previewSize].width > 64) 125 { 126 newSize.width = [canvas previewSize].width; 127 newOrigin.x = 0; 128 } 129 else 130 { 131 newSize.width = 64; 132 newOrigin.x = (64 - [canvas previewSize].width) / 2; 133 } 134 if ([canvas previewSize].height > 64) 135 { 136 newSize.height = [canvas previewSize].height; 137 newOrigin.y = 0; 138 } 139 else 140 { 141 newSize.height = 64; 142 newOrigin.y = (64 - [canvas previewSize].height) / 2; 143 } 144 145 NSPoint topLeft = [[self window] frame].origin; 146 topLeft.y += [[self window] frame].size.height; 147 [[self window] setContentSize:newSize]; 148 [[self window] setFrameTopLeftPoint:topLeft]; 149 [view setFrameOrigin:newOrigin]; 150 [view setFrameSize:[canvas previewSize]]; 151 152 if ([canvas size].height > 0 153 && [canvas size].width > 0) { 154 float ratio = MIN([canvas previewSize].height / [canvas size].height, 155 [canvas previewSize].width / [canvas size].width); 156 if (ratio != 0) { 157 [view setZoomPercentage:ratio * 100.0f]; 158 } 159 } 160 [[[self window] contentView] setNeedsDisplay:YES]; 161} 162 163- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize 164{ 165 if (canvas == nil || !([[[NSApplication sharedApplication] currentEvent] modifierFlags] & NSShiftKeyMask)) 166 { 167 return proposedFrameSize; 168 } 169 170 float titleBarSize = [sender frame].size.height - [[sender contentView] frame].size.height; // ewww hack 171 float scaleFactor = roundf((proposedFrameSize.height - titleBarSize) / [canvas size].height); 172 if (scaleFactor == 0) 173 { 174 scaleFactor = 1; 175 } 176 177 NSSize newSize = [canvas size]; 178 newSize.height *= scaleFactor; 179 newSize.width *= scaleFactor; 180 newSize.height += titleBarSize; 181 return newSize; 182} 183 184- (void)updateResizeSizeViewScale 185{ 186 if (canvas == nil) 187 { 188 return; 189 } 190 191/*[[[self window] contentView] frame].size.height / [canvas size].height*/ 192 193#ifdef __COCOA__ 194 [[resizeSizeWindow contentView] updateScale:[view zoomPercentage]/100]; 195#else 196 NSLog(@"resizeSizeWindow %@",resizeSizeWindow); 197 [[resizeSizeWindow contentView] updateScale:6.0]; 198#endif 199 200 201 202 203 [resizeSizeWindow setContentSize:[[resizeSizeWindow contentView] scaleStringSize]]; 204 205 NSPoint newOrigin = [[self window] frame].origin; 206 newOrigin.x += ([[[self window] contentView] frame].size.width - [resizeSizeWindow frame].size.width) / 2.0; 207 newOrigin.y += ([[[self window] contentView] frame].size.height - [resizeSizeWindow frame].size.height) / 2.0; 208 [resizeSizeWindow setFrameOrigin:newOrigin]; 209 210 [resizeSizeWindow setAlphaValue:1]; 211 [resizeSizeWindow orderFront:self]; 212 213 [fadeOutTimer invalidate]; 214 [fadeOutTimer release]; 215 fadeOutTimer = [[NSTimer scheduledTimerWithTimeInterval:1 216 target:self 217 selector:@selector(fadeOutSize:) 218 userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:.95] forKey:@"opacity"] repeats:NO] retain]; 219 220 221 222} 223 224- (void)fadeOutSize:(NSTimer *)timer 225{ 226 float alphaValue = [[[timer userInfo] objectForKey:@"opacity"] floatValue]; 227 [resizeSizeWindow setAlphaValue:alphaValue]; 228 [fadeOutTimer invalidate]; 229 [fadeOutTimer release]; 230 if (alphaValue > 0) 231 { 232 fadeOutTimer = [[NSTimer scheduledTimerWithTimeInterval:.05 233 target:self 234 selector:@selector(fadeOutSize:) 235 userInfo:[NSDictionary dictionaryWithObject: 236 [NSNumber numberWithFloat:alphaValue-.1] forKey:@"opacity"] repeats:NO] retain]; 237 } 238 else 239 { 240 fadeOutTimer = nil; 241 } 242} 243 244- (void)windowDidResize:(NSNotification *)aNotification 245{ 246 NSLog(@"windowDidResize canvas %@",canvas); 247 if (canvas == nil) 248 return; 249 250 NSLog(@"==========> Size %@",NSStringFromSize( [[[self window] contentView] frame].size) ); 251 [canvas setPreviewSize:[[[self window] contentView] frame].size]; 252 [self sizeToCanvas]; 253 [self updateResizeSizeViewScale]; 254} 255 256- (void)initializeWindow 257{ 258#ifdef __COCOA__ 259 [[self window] setContentAspectRatio:[canvas size]]; 260#else 261 [[self window] setResizeIncrements:NSMakeSize(1.0,1.0)]; 262#endif 263 [self sizeToCanvas]; 264 [view setCanvas:canvas]; 265 [[view grid] setShouldDraw:NO]; 266 float titleBarSize = [[self window] frame].size.height - [[[self window] contentView] frame].size.height; 267 [[self window] setMinSize:NSMakeSize(64, 64 + titleBarSize)]; 268} 269 270- (IBAction)showWindow:sender 271{ 272 [super showWindow:sender]; 273 [self initializeWindow]; 274 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PXPreviewWindowIsOpen"]; 275} 276 277- (void)setCanvas:aCanvas 278{ 279 //we have to do all this no matter what so there aren't inconsistency-bugs 280 [view setCanvas:nil]; 281 [view display]; 282 [[NSNotificationCenter defaultCenter] removeObserver:self 283 name:PXCanvasChangedNotificationName 284 object:canvas]; 285 canvas = aCanvas; 286 if (aCanvas == nil) 287 { 288 if ([[self window] isVisible]) 289 { 290 temporarilyHiding = YES; 291 [[self window] close]; 292 } 293 } 294 else 295 { 296 [[NSNotificationCenter defaultCenter] addObserver:self 297 selector:@selector(canvasDidChange:) 298 name:PXCanvasChangedNotificationName 299 object:canvas]; 300 } 301 if ((temporarilyHiding && aCanvas != nil) 302 || [[self window] isVisible]) 303 { 304 temporarilyHiding = NO; 305 [self showWindow:self]; 306 //[[self window] display]; 307 [self updateResizeSizeViewScale]; 308 } 309} 310 311- (void)canvasDidChange:aNotification 312{ 313 if ([[self window] isVisible]) 314 { 315 updateRect = NSUnionRect(updateRect, [[[aNotification userInfo] objectForKey:@"changedRect"] rectValue]); 316 } 317} 318 319@end 320