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