1// PXCanvasController.m 2// Pixen 3// 4// Created by Joe Osborn on Sat Sep 13 2003. 5// Copyright (c) 2003 Open Sword Group. All rights reserved. 6// 7 8#import "PXCanvasController.h" 9#import "PXCanvas.h" 10#import "PXCanvasView.h" 11#import "PXImage.h" 12#import "PXImageSizePrompter.h" 13#import "PXCanvasResizePrompter.h" 14#import "PXGridSettingsPrompter.h" 15#import "PXTool.h" 16#import "PXToolPaletteController.h" 17#import "PXInfoPanelController.h" 18#import "PXBackgroundController.h" 19#import "PXPreviewController.h" 20#import "PXLayerController.h" 21#import "PXGrid.h" 22#import "PXColorPaletteController.h" 23#import "PXScaleController.h" 24#import "PXDocument.h" 25#import "PXPanelManager.h" 26 27//Taken from a man calling himself "BROCK BRANDENBERG" who is here to save the day. 28#import "SBCenteringClipView.h" 29 30//Taken from a man calling himself "M. Uli Kusterer", who is totally not saving the day adequately (but we love him anyway). 31#import "UKFeedbackProvider.h" 32 33#ifndef __COCOA__ 34#include "math.h" 35#import "NSArray_DeepMutableCopy.h" 36#endif 37 38@implementation PXCanvasController 39 40- view 41{ 42 return view; 43} 44 45- init 46{ 47 [super initWithWindowNibName:@"PXDocument"]; 48 prompter = [[PXImageSizePrompter alloc] init]; 49 resizePrompter = [[PXCanvasResizePrompter alloc] init]; 50 previewController = [PXPreviewController sharedPreviewController]; 51 backgroundController = [[PXBackgroundController alloc] init]; 52 scaleController = [[PXScaleController alloc] init]; 53 [backgroundController setDelegate:self]; 54 [[NSNotificationCenter defaultCenter] addObserver:self 55 selector:@selector(canvasSizeDidChange:) 56 name:PXCanvasSizeChangedNotificationName 57 object:nil]; 58 59 return self; 60} 61 62- (void)awakeFromNib 63{ 64 toolbar = [[NSToolbar alloc] initWithIdentifier:@"PXDocumentToolbar"]; 65 [toolbar setDelegate:self]; 66 [toolbar setAllowsUserCustomization:YES]; 67 [toolbar setAutosavesConfiguration:YES]; 68#ifndef __COCOA__ 69 [zoomPercentageBox setEditable: YES]; 70 [zoomPercentageBox setEnabled:YES]; 71 [zoomPercentageBox setUsesDataSource:NO]; 72 [zoomPercentageBox setNumberOfVisibleItems:10]; 73 [zoomPercentageBox setCompletes:NO]; 74#endif 75 76 [[self window] setToolbar:toolbar]; 77 [[self window] setAcceptsMouseMovedEvents:YES]; 78} 79 80- (void)dealloc 81{ 82 [[NSNotificationCenter defaultCenter] removeObserver:self]; 83 if([[backgroundController backgroundPanel] isVisible]) 84 { 85 [[backgroundController backgroundPanel] performClose:self]; 86 } 87 [backgroundController release]; 88 if([[prompter window] isVisible]) 89 { 90 [prompter close]; 91 } 92 [prompter release]; 93 [resizePrompter release]; 94 [layerController release]; 95 [toolbar release]; 96 [super dealloc]; 97} 98 99- (IBAction)increaseOpacity:sender 100{ 101 id switcher = [[PXToolPaletteController sharedToolPaletteController] leftSwitcher]; 102 [switcher setColor:[[switcher color] colorWithAlphaComponent:[[switcher color] alphaComponent] + 0.1f]]; 103} 104 105- (IBAction)decreaseOpacity:sender 106{ 107 id switcher = [[PXToolPaletteController sharedToolPaletteController] leftSwitcher]; 108 [switcher setColor:[[switcher color] colorWithAlphaComponent:[[switcher color] alphaComponent] - 0.1f]]; 109} 110 111- (IBAction)duplicateDocument:sender 112{ 113 id newDocument = [[NSDocumentController sharedDocumentController] makeUntitledDocumentOfType:@"Pixen Image"]; 114 id newCanvas = [canvas copy]; 115 [newDocument setValue:newCanvas forKey:@"canvas"]; 116 [newDocument makeWindowControllers]; 117 [[NSDocumentController sharedDocumentController] addDocument:newDocument]; 118} 119 120- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar 121 itemForItemIdentifier:(NSString *)itemIdentifier 122 willBeInsertedIntoToolbar:(BOOL)flag 123{ 124 NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease]; 125 126 if ([itemIdentifier isEqualToString:@"PXBackgroundConfigurator"]) 127 { 128 [item setLabel:NSLocalizedString(@"BACKGROUND_LABEL", @"Background Label")]; 129 [item setPaletteLabel:[item label]]; 130 [item setToolTip:NSLocalizedString(@"BACKGROUND_TOOLTIP", @"Background Tooltip")]; 131 [item setTarget:self]; 132 [item setAction:@selector(showBackgroundInfo:)]; 133 [item setImage:[NSImage imageNamed:@"bgconf"]]; 134 } 135 else if ([itemIdentifier isEqualToString:@"PXLayerDrawer"]) 136 { 137 [item setLabel:NSLocalizedString(@"LAYERS_LABEL", @"Layers Label")]; 138 [item setPaletteLabel:[item label]]; 139 [item setToolTip:NSLocalizedString(@"LAYERS_TOOLTIP", @"Layers Tooltip")]; 140 [item setTarget:self]; 141 [item setAction:@selector(toggleLayersDrawer:)]; 142 [item setImage:[NSImage imageNamed:@"layerdrawer"]]; 143 } 144 else if ([itemIdentifier isEqualToString:@"PXPreview"]) 145 { 146 [item setLabel:NSLocalizedString(@"PREVIEW_LABEL", @"Preview Label")]; 147 [item setPaletteLabel:[item label]]; 148 [item setToolTip:NSLocalizedString(@"PREVIEW_TOOLTIP", @"Preview Tooltip")]; 149 [item setTarget:self]; 150 [item setAction:@selector(togglePreviewWindow:)]; 151 [item setImage:[NSImage imageNamed:@"preview"]]; 152 } 153 else if ([itemIdentifier isEqualToString:@"PXToolProperties"]) 154 { 155 [item setLabel:NSLocalizedString(@"TOOL_PROPERTIES_LABEL", @"Tool Properties Label")]; 156 [item setPaletteLabel:[item label]]; 157 [item setToolTip:NSLocalizedString(@"TOOL_PROPERTIES_TOOLTIP", @"Tool Properties Tooltip")]; 158 [item setTarget:self]; 159 [item setAction:@selector(toggleLeftToolProperties:)]; 160 [item setImage:[NSImage imageNamed:@"toolproperties"]]; 161 } 162 else if ([itemIdentifier isEqualToString:@"PXGrid"]) 163 { 164 [item setLabel:NSLocalizedString(@"GRID_LABEL", @"Grid Label")]; 165 [item setPaletteLabel:[item label]]; 166 [item setToolTip:NSLocalizedString(@"GRID_TOOLTIP", @"Grid Tooltip")]; 167 [item setTarget:self]; 168 [item setAction:@selector(showGridSettingsPrompter:)]; 169 [item setImage:[NSImage imageNamed:@"grid"]]; 170 } 171 else if ([itemIdentifier isEqualToString:@"PXColorPalette"]) 172 { 173 [item setLabel:NSLocalizedString(@"COLOR_PALETTE_LABEL", @"Color Palette Label")]; 174 [item setPaletteLabel:[item label]]; 175 [item setToolTip:NSLocalizedString(@"COLOR_PALETTE_TOOLTIP", @"Color Palette Tooltip")]; 176 [item setTarget:self]; 177 [item setAction:@selector(toggleColorPalette:)]; 178 [item setImage:[NSImage imageNamed:@"colorpalette"]]; 179 } 180 else if ([itemIdentifier isEqualToString:@"PXZoomFit"]) 181 { 182 183 [item setLabel:NSLocalizedString(@"ZOOM_FIT_LABEL", @"Zoom Fit Label")]; 184 [item setPaletteLabel:[item label]]; 185 [item setToolTip:NSLocalizedString(@"ZOOM_FIT_TOOLTIP", @"Zoom Fit Tooltip")]; 186 [item setTarget:self]; 187 [item setAction:@selector(zoomToFit:)]; 188 [item setImage:[NSImage imageNamed:@"zoomfit"]]; 189 } 190 else if ([itemIdentifier isEqualToString:@"PXZoom100"]) 191 { 192 [item setLabel:NSLocalizedString(@"ZOOM_ACTUAL_LABEL", @"Zoom Actual Label")]; 193 [item setPaletteLabel:[item label]]; 194 [item setToolTip:NSLocalizedString(@"ZOOM_ACTUAL_TOOLTIP", @"Zoom Actual Tooltip")]; 195 [item setTarget:self]; 196 [item setAction:@selector(zoomStandard:)]; 197 [item setImage:[NSImage imageNamed:@"zoom100"]]; 198 } 199 else if ([itemIdentifier isEqualToString:@"PXScale"]) 200 { 201 [item setLabel:NSLocalizedString(@"SCALE_LABEL", @"Scale Label")]; 202 [item setPaletteLabel:[item label]]; 203 [item setToolTip:NSLocalizedString(@"SCALE_TOOLTIP", @"Scale Tooltip")]; 204 [item setTarget:self]; 205 [item setAction:@selector(scaleCanvas:)]; 206 [item setImage:[NSImage imageNamed:@"scale"]]; 207 } 208 else if ([itemIdentifier isEqualToString:@"PXResize"]) 209 { 210 [item setLabel:NSLocalizedString(@"RESIZE_LABEL", @"Resize Label")]; 211 [item setPaletteLabel:[item label]]; 212 [item setToolTip:NSLocalizedString(@"RESIZE_TOOLTIP", @"Resize Tooltip")]; 213 [item setTarget:self]; 214 [item setAction:@selector(resizeCanvas:)]; 215 [item setImage:[NSImage imageNamed:@"resize"]]; 216 } 217 else if ([itemIdentifier isEqualToString:@"PXFeedback"]) 218 { 219 [item setLabel:NSLocalizedString(@"FEEDBACK_LABEL", @"Feedback Label")]; 220 [item setPaletteLabel:[item label]]; 221 [item setToolTip:NSLocalizedString(@"FEEDBACK_TOOLTIP", @"Feedback Tooltip")]; 222 [item setTarget:self]; 223 [item setAction:@selector(sendFeedback:)]; 224 [item setImage:[NSImage imageNamed:@"feedback"]]; 225 } 226 else if ([itemIdentifier isEqualToString:@"PXZoom"]) 227 { 228 [item setLabel:NSLocalizedString(@"ZOOM_LABEL", @"Zoom Label")]; 229 [item setPaletteLabel:[item label]]; 230 [item setToolTip:NSLocalizedString(@"ZOOM_TOOLTIP", @"Zoom Tooltip")]; 231 [item setTarget:self]; 232 [item setAction:@selector(togglePreviewWindow:)]; 233 [item setView:zoomView]; 234 [item setMinSize:NSMakeSize(124,NSHeight([zoomView frame]))]; 235 [item setMaxSize:NSMakeSize(0,NSHeight([zoomView frame]))]; 236 } 237 238 return item; 239} 240 241- (NSArray *) toolbarAllowedItemIdentifiers:(NSToolbar *) toolbar 242{ 243 return [NSArray arrayWithObjects:@"PXBackgroundConfigurator", @"PXLayerDrawer", 244 @"PXPreview", @"PXZoom", 245 @"PXZoomFit", @"PXZoom100", 246 @"PXResize", @"PXScale", 247 @"PXFeedback", @"PXGrid", 248 @"PXColorPalette", 249 NSToolbarCustomizeToolbarItemIdentifier, 250 NSToolbarSpaceItemIdentifier, 251 NSToolbarSeparatorItemIdentifier, 252 NSToolbarFlexibleSpaceItemIdentifier, 253 nil]; 254} 255 256- (NSArray *) toolbarDefaultItemIdentifiers:(NSToolbar *) toolbar 257{ 258#ifdef __COCOA__ 259 return [NSArray arrayWithObjects:@"PXBackgroundConfigurator", @"PXGrid", 260 NSToolbarSeparatorItemIdentifier, @"PXLayerDrawer", 261 @"PXColorPalette", @"PXPreview", 262 NSToolbarFlexibleSpaceItemIdentifier, @"PXFeedback", 263 @"PXZoom", 264 nil]; 265#else 266 //Forget Zoom for GNUstep (TDOO) 267 return [NSArray arrayWithObjects:@"PXBackgroundConfigurator", @"PXGrid", 268 NSToolbarSeparatorItemIdentifier, @"PXLayerDrawer", 269 @"PXColorPalette", @"PXPreview", 270 NSToolbarFlexibleSpaceItemIdentifier, 271 @"PXFeedback", 272 nil]; 273#endif 274} 275 276- (IBAction) sendFeedback:(id) sender 277{ 278 [[PXPanelManager sharedManager] showFeedback:sender]; 279} 280 281- (IBAction) toggleLeftToolProperties:(id) sender 282{ 283 [[PXPanelManager sharedManager] toggleLeftToolProperties:sender]; 284} 285 286- (IBAction)toggleRightToolProperties:(id) sender 287{ 288 [[PXPanelManager sharedManager] toggleRightToolProperties:sender]; 289} 290 291- (IBAction)toggleColorPalette:(id) sender 292{ 293 [[PXPanelManager sharedManager] toggleColorPalette:sender]; 294} 295 296- (IBAction)mergeDown:(id) sender 297{ 298 [layerController mergeDown]; 299} 300 301- (IBAction)promoteSelection:(id) sender 302{ 303 [canvas promoteSelection]; 304} 305 306- (IBAction)newLayer:(id) sender 307{ 308 [layerController addLayer:sender]; 309} 310 311- (IBAction)deleteLayer:sender 312{ 313 [layerController removeLayer:sender]; 314} 315 316- (void)layerSelectionDidChange:(NSNotification *) aNotification 317{ 318 [canvas deselect]; 319 [canvas activateLayer:[aNotification userInfo]]; 320} 321 322- (void)setMainBackground:(id) aBackground 323{ 324 [view setMainBackground:aBackground]; 325 [canvas setMainBackgroundName:[aBackground name]]; 326} 327 328- (void)setAlternateBackground:(id) aBackground 329{ 330 [view setAlternateBackground:aBackground]; 331 [canvas setAlternateBackgroundName:[aBackground name]]; 332} 333 334- (void)backgroundChanged: (NSNotification *) aNotification 335{ 336 [view setNeedsDisplayInRect:[view visibleRect]]; 337} 338 339- (IBAction)flipLayerHorizontally:(id) sender 340{ 341 [[self undoManager] beginUndoGrouping]; 342 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers]]; 343 [[self undoManager] setActionName:@"Flip Layer Horizontally"]; 344 [[self undoManager] endUndoGrouping]; 345 [[canvas activeLayer] flipHorizontally]; 346 [canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 347} 348 349- (IBAction)flipLayerVertically:(id) sender 350{ 351 [[self undoManager] beginUndoGrouping]; 352 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers]]; 353 [[self undoManager] setActionName:@"Flip Layer Vertically"]; 354 [[self undoManager] endUndoGrouping]; 355 [[canvas activeLayer] flipVertically]; 356 [canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 357} 358 359- (IBAction)duplicateLayer:(id) sender 360{ 361 [layerController duplicateLayer:sender]; 362} 363 364- (IBAction)nextLayer:(id) sender 365{ 366 [layerController nextLayer:sender]; 367} 368 369- (IBAction)previousLayer:(id) sender 370{ 371 [layerController previousLayer:sender]; 372} 373 374- (void)promptForImageSize 375{ 376 [prompter setDelegate:self]; 377 [prompter promptInWindow:[self window]]; 378} 379 380//Should be PXCanvas as returned type ? 381- (id) canvas 382{ 383 return canvas; 384} 385//Should be PXCanvas as returned type? 386- (void)setCanvas:(id) aCanvas 387{ 388 [[NSNotificationCenter defaultCenter] removeObserver:self name:PXCanvasChangedNotificationName object:canvas]; 389 390 canvas = aCanvas; 391 if(NSEqualSizes([canvas size], NSZeroSize)) 392 { 393 [self promptForImageSize]; 394 [prompter setDefaultSize:NSMakeSize(64,64)]; 395 } 396 397 [[NSNotificationCenter defaultCenter] addObserver:self 398 selector:@selector(canvasDidChange:) 399 name:PXCanvasChangedNotificationName 400 object:canvas]; 401 402 [view setCanvas:aCanvas]; 403 [layerController setCanvas:aCanvas]; 404 [[PXColorPaletteController sharedPaletteController] reloadDataForCanvas:canvas]; 405 406 [[NSNotificationCenter defaultCenter] postNotificationName:PXCanvasLayersChangedNotificationName 407 object:canvas]; 408 409 [canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 410} 411 412- (void)setColor:(NSColor *) aColor 413{ 414 [[PXToolPaletteController sharedToolPaletteController] setColor:aColor]; 415} 416 417- (void)canvasDidChange:(NSNotification *) aNotification 418{ 419 NSRect rect = [[[aNotification userInfo] objectForKey:@"changedRect"] rectValue]; 420 [view setNeedsDisplayInCanvasRect:rect]; 421} 422 423- (void)canvasSizeDidChange:(NSNotification *) aNotification 424{ 425 [view sizeToCanvas]; 426 [self updatePreview]; 427 //[self zoomToFit:self]; 428} 429 430- (void)updatePreview 431{ 432 [previewController setCanvas:canvas]; 433 [previewController window]; 434} 435 436- (NSUndoManager *) undoManager 437{ 438 return [[[NSDocumentController sharedDocumentController] currentDocument] undoManager]; 439} 440 441- (void)setLayers:layers fromLayers:oldLayers 442{ 443 [[[self undoManager] prepareWithInvocationTarget:self] setLayers:oldLayers fromLayers:layers]; 444 [canvas setLayers:layers]; 445 //beginHack: it is probably bad to rely on the fact that all layers are the same size for now. However, it is late and I want this to work and this is unlikely to change, so I will ignore this for now. __joe 446 [canvas setSize:[[layers objectAtIndex:0] size]]; 447 //endHack 448 [self canvasSizeDidChange:nil]; 449} 450 451- (IBAction)resizeCanvas:(id) sender 452{ 453 [[self undoManager] beginUndoGrouping]; 454 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers]]; 455 [[self undoManager] setActionName:@"Resize Canvas"]; 456 [[self undoManager] endUndoGrouping]; 457 [resizePrompter setDelegate:self]; 458 NSLog(@"resizePrompter %@",resizePrompter); 459 [resizePrompter promptInWindow:[self window]]; 460 [resizePrompter setCurrentSize:[canvas size]]; 461 462 NSImage *canvasImage = [[[NSImage alloc] initWithSize:[canvas size]] autorelease]; 463 [canvasImage lockFocus]; 464 [canvas drawRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height) fixBug:YES]; 465 [canvasImage unlockFocus]; 466 [resizePrompter setCachedImage:canvasImage]; 467} 468 469- (IBAction)scaleCanvas:(id) sender 470{ 471 [[self undoManager] beginUndoGrouping]; 472 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers]]; 473 [[self undoManager] setActionName:@"Scale Canvas"]; 474 [[self undoManager] endUndoGrouping]; 475 [scaleController scaleCanvasFromController:self modalForWindow:[self window]]; 476} 477 478- (void)windowDidBecomeMain:(NSNotification *) aNotification 479{ 480 if([aNotification object] == [self window]) 481 { 482 [self updatePreview]; 483 [[PXColorPaletteController sharedPaletteController] reloadDataForCanvas:canvas]; 484 [[PXInfoPanelController sharedInfoPanelController] setCanvasSize:[canvas size]]; 485 } 486} 487 488- (void)windowDidLoad 489{ 490 [view setDelegate:self]; 491 [zoomPercentageBox removeAllItems]; 492 [zoomPercentageBox addItemsWithObjectValues:[NSArray arrayWithObjects:[NSNumber numberWithInt:3000], 493 [NSNumber numberWithInt:2000], 494 [NSNumber numberWithInt:1000], 495 [NSNumber numberWithInt:800], 496 [NSNumber numberWithInt:500], 497 [NSNumber numberWithInt:400], 498 [NSNumber numberWithInt:200], 499 [NSNumber numberWithInt:100], 500 [NSNumber numberWithInt:50], nil]]; 501 // If you're looking for randomly hard-coded percentages, they're right here! 502 [zoomPercentageBox selectItemAtIndex:7]; 503 [zoomStepper setIntValue:7]; 504 NSLog(@"window %@ delegate %@",[self window], [[self window] delegate]); 505 //[window setDelegate: self ] 506 NSLog(@"scrollView %@",NSStringFromRect([[scrollView contentView] frame])); 507 508 509 // Programmatically create our scrollview and canvas view 510 id clip = [[[SBCenteringClipView alloc] initWithFrame:[[scrollView contentView] frame]] autorelease]; 511 [clip setBackgroundColor:[NSColor lightGrayColor]]; 512 [clip setCopiesOnScroll:NO]; 513 NSLog(@"clip^frame %@",NSStringFromRect([clip frame])); 514 515#ifdef __COCOA__ 516 [(NSScrollView *)scrollView setContentView:clip]; 517#endif 518 [scrollView setDocumentView:view]; 519 [view setCanvas:canvas]; 520 521 [backgroundController useBackgroundsOf:canvas]; 522 //[clip centerDocument]; 523 layerController = [[PXLayerController alloc] initWithCanvas:canvas]; 524 [[NSNotificationCenter defaultCenter] addObserver:self 525 selector:@selector(layerSelectionDidChange:) 526 name:PXLayerSelectionDidChangeName 527 object:layerController]; 528 [layerController setWindow:[self window]]; 529 [layerController setNextResponder:self]; 530 [[NSNotificationCenter defaultCenter] postNotificationName:PXCanvasLayersChangedNotificationName object:canvas]; 531 [self zoomToFit:self]; 532 [[PXColorPaletteController sharedPaletteController] reloadDataForCanvas:canvas]; 533 [[PXColorPaletteController sharedPaletteController] 534 selectPaletteNamed:NSLocalizedString(@"GENERATED_PALETTE", @"Generated Palette")]; 535 536 [[self window] useOptimizedDrawing:YES]; 537 [[self window] makeKeyAndOrderFront:self]; 538 //[canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 539 //[self updatePreview]; 540} 541 542- (void)updateCanvasSize 543{ 544 [[PXInfoPanelController sharedInfoPanelController] setCanvasSize:[canvas size]]; 545 [view sizeToCanvas]; 546 [self updatePreview]; 547 [self zoomToFit:self]; 548} 549 550- (void)prompter:aPrompter didFinishWithSize:(NSSize)aSize 551{ 552 [canvas setSize:aSize]; 553 554 [self updateCanvasSize]; 555 [[PXColorPaletteController sharedPaletteController] reloadDataForCanvas:canvas]; 556 [[PXColorPaletteController sharedPaletteController] selectDefaultPalette]; 557 [(PXImage *)[[[canvas layers] objectAtIndex:0] image] replacePixelsOfColor:nil withColor:[NSColor clearColor]]; 558 559} 560 561- (void)prompter:aPrompter didFinishWithSize:(NSSize)aSize position:(NSPoint)position backgroundColor:(NSColor *)color 562{ 563 [canvas setSize:aSize withOrigin:position backgroundColor:color]; 564 [self updateCanvasSize]; 565} 566 567//What is this coding Style ? 568BOOL isTiling; 569- (IBAction) shouldTileToggled: (id) sender 570{ 571 isTiling = !isTiling; 572 [sender setState:(isTiling) ? NSOffState : NSOnState]; 573 id defaults = [NSUserDefaults standardUserDefaults]; 574 [defaults setBool:isTiling forKey:@"PXShouldTile"]; 575 [defaults synchronize]; 576 [view setShouldTile:isTiling]; 577} 578 579- (void)gridSettingsPrompter:aPrompter updatedWithSize:(NSSize)aSize color:color shouldDraw:(BOOL)shouldDraw 580{ 581 [[view grid] setUnitSize:aSize]; 582 [[view grid] setColor:color]; 583 [[view grid] setShouldDraw:shouldDraw]; 584 [canvas setGridUnitSize:aSize]; 585 [canvas setGridColor:color]; 586 [canvas setGridShouldDraw:shouldDraw]; 587 [canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 588} 589 590- (void)mouseDown:event forTool:aTool 591{ 592 NSLog(@"mouse Down forTool %@",aTool); 593 if(downEventOccurred) { return; } // avoid the case where the right mouse can be pressed while the left is dragging, and vice-versa. there should really be separate booleans for left-mouse-is-being-used and right-mouse-is-being-used, since right now if the right mouse is pressed and unpressed while the left mouse is pressed, the result will be that the left, too, becomes unpressed. fortunately, there are seemingly no unfortunate side effects from this situation, only the more obvious bug. 594 downEventOccurred = YES; 595 [[NSNotificationCenter defaultCenter] postNotificationName:@"PXLockToolSwitcher" object:aTool]; 596 if(! [aTool respondsToSelector:@selector(mouseDownAt:fromCanvasController:)]) 597 return; 598 599 initialPoint = [event locationInWindow]; 600 NSLog(@"go %@",NSStringFromPoint([view convertFromWindowToCanvasPoint:initialPoint])); 601 [aTool mouseDownAt:[view convertFromWindowToCanvasPoint:initialPoint] fromCanvasController:self]; 602} 603 604- (void)mouseDragged:event forTool:aTool 605{ 606 if(!downEventOccurred) { return; } 607 if(![aTool respondsToSelector:@selector(mouseDraggedFrom:to:fromCanvasController:)]) { return; } 608 NSPoint endPoint = [event locationInWindow]; 609 [aTool mouseDraggedFrom:[view convertFromWindowToCanvasPoint:initialPoint] to:[view convertFromWindowToCanvasPoint:endPoint] fromCanvasController:self]; 610 initialPoint = endPoint; 611} 612 613- (void)mouseUp:event forTool:aTool 614{ 615 if(!downEventOccurred) { return; } 616 downEventOccurred = NO; 617 [[NSNotificationCenter defaultCenter] postNotificationName:@"PXUnlockToolSwitcher" object:aTool]; 618 if(![aTool respondsToSelector:@selector(mouseUpAt:fromCanvasController:)]) { return; } 619 [aTool mouseUpAt:[view convertFromWindowToCanvasPoint:[event locationInWindow]] fromCanvasController:self]; 620} 621 622- (void)mouseDown:(NSEvent *)event 623{ 624 NSLog(@"mouseDown PXCanvasController"); 625 //users expect ctrl-left to == right 626 usingControlKey = (([event modifierFlags] & NSControlKeyMask) == NSControlKeyMask); 627 628 if (usingControlKey) 629 { 630 [self rightMouseDown:event]; return; 631 } 632 [self mouseDown:event forTool:[[PXToolPaletteController sharedToolPaletteController] leftTool]]; 633} 634 635- (void)mouseDragged:(NSEvent *) event 636{ 637 if (usingControlKey) 638 { 639 [self rightMouseDragged:event]; return; 640 } 641 [self mouseDragged:event forTool:[[PXToolPaletteController sharedToolPaletteController] leftTool]]; 642} 643 644- (void)mouseMoved:(NSEvent *) event 645{ 646 [view mouseMoved:event]; 647} 648 649- (void)mouseUp:(NSEvent *) event 650{ 651 if (usingControlKey) 652 { 653 [self rightMouseUp:event]; return; 654 } 655 [self mouseUp:event forTool:[[PXToolPaletteController sharedToolPaletteController] leftTool]]; 656} 657 658- (void)rightMouseDown:(NSEvent *) event 659{ 660 [self mouseDown:event forTool:[[PXToolPaletteController sharedToolPaletteController] rightTool]]; 661} 662 663- (void)rightMouseDragged:(NSEvent *) event 664{ 665 [self mouseDragged:event forTool:[[PXToolPaletteController sharedToolPaletteController] rightTool]]; 666} 667 668- (void)rightMouseUp:(NSEvent *) event 669{ 670 [self mouseUp:event forTool:[[PXToolPaletteController sharedToolPaletteController] rightTool]]; 671} 672 673- (void)keyDown:(NSEvent *)event 674{ 675 // [FIXME] Should we scroll the view or move the active layer here? Hmm... 676 if (downEventOccurred) { return; } 677 int scrollAmount = 1; 678 if(([event modifierFlags] & NSShiftKeyMask) == NSShiftKeyMask) 679 { 680 scrollAmount = 10; 681 } 682 if([[event characters] characterAtIndex:0] == NSUpArrowFunctionKey) 683 { 684 [view scrollUpBy:scrollAmount]; 685 } 686 else if([[event characters] characterAtIndex:0] == NSRightArrowFunctionKey) 687 { 688 [view scrollRightBy:scrollAmount]; 689 } 690 else if([[event characters] characterAtIndex:0] == NSDownArrowFunctionKey) 691 { 692 [view scrollDownBy:scrollAmount]; 693 } 694 else if([[event characters] characterAtIndex:0] == NSLeftArrowFunctionKey) 695 { 696 [view scrollLeftBy:scrollAmount]; 697 } 698 else if([[event characters] characterAtIndex:0] == NSDeleteFunctionKey) 699 { 700 [[[NSDocumentController sharedDocumentController] currentDocument] delete:self]; 701 //[canvas deleteSelection]; 702 //[canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 703 } 704 else 705 { 706 [[PXToolPaletteController sharedToolPaletteController] keyDown:event]; 707 [[PXColorPaletteController sharedPaletteController] keyDown:event]; 708 } 709} 710 711- (void)flagsChanged:(NSEvent *) event 712{ 713 [[PXToolPaletteController sharedToolPaletteController] flagsChanged:event]; 714} 715 716- (IBAction)showPreviewWindow:(NSEvent *) sender 717{ 718 [previewController showWindow:self]; 719} 720 721- (IBAction)togglePreviewWindow: (id) sender 722{ 723 if ([[previewController window] isVisible]) 724 { 725 [[previewController window] performClose:self]; 726 } 727 else 728 { 729 [previewController showWindow:self]; 730 } 731} 732 733- (IBAction)showBackgroundInfo:(id) sender 734{ 735 NSLog(@"showBackgroundInfo %@",[backgroundController backgroundPanel]); 736 [[backgroundController backgroundPanel] makeKeyAndOrderFront: self]; 737} 738 739- (IBAction)showGridSettingsPrompter:(id) sender 740{ 741 if (gridSettingsPrompter) 742 [gridSettingsPrompter release]; 743 744 gridSettingsPrompter = [[PXGridSettingsPrompter alloc] initWithSize:[[view grid] unitSize] 745 color:[[view grid] color] 746 shouldDraw:[[view grid] shouldDraw] ? YES : NO]; 747 [gridSettingsPrompter setDelegate:self]; 748 [(PXGridSettingsPrompter *)gridSettingsPrompter prompt]; 749} 750 751- (void)zoomToIndex:(float)index 752{ 753 if(index < 0 || index >= [zoomPercentageBox numberOfItems]) { 754#ifdef __COCOA__ 755 NSBeep(); 756#endif 757 return; 758 } 759 760 [zoomPercentageBox selectItemAtIndex:index]; 761 [zoomStepper setIntValue:index]; 762 [view setZoomPercentage:[zoomPercentageBox intValue]]; 763} 764 765- (void)zoomToPercentage:(NSNumber *)percentage 766{ 767 if( percentage == nil 768 || [percentage isEqual:[NSNumber numberWithInt:0]] 769 || [[[percentage description] lowercaseString] isEqualToString:@"inf"] 770 || [[[percentage description] lowercaseString] isEqualToString:@"nan"]) 771 { 772 [self zoomToPercentage:[NSNumber numberWithFloat:100]]; 773 return; 774 } 775 // Kind of a HACK, could change if the description changes to display something other than inf or nan on such numbers. 776 //Probably not an issue, but I'll mark it so it's easy to find if it breaks later. 777 778 779 if( ! [[zoomPercentageBox objectValues] containsObject:percentage]) 780 { 781 id values = [NSMutableArray arrayWithArray:[zoomPercentageBox objectValues]]; 782 [values addObject:percentage]; 783 [values sortUsingSelector:@selector(compare:)]; 784 [zoomPercentageBox removeAllItems]; 785 [zoomPercentageBox addItemsWithObjectValues:[[values reverseObjectEnumerator] allObjects]]; 786 } 787 788 [zoomPercentageBox selectItemWithObjectValue:percentage]; 789 [self zoomToIndex:[zoomPercentageBox indexOfSelectedItem]]; 790} 791 792- (IBAction)zoomIn: (id) sender 793{ 794 [self zoomToIndex:[zoomStepper intValue]-1]; 795} 796 797- (IBAction)zoomOut: (id) sender 798{ 799 [self zoomToIndex:[zoomStepper intValue]+1]; 800} 801 802- (IBAction)zoomStandard: (id) sender 803{ 804 [self zoomToIndex:[zoomPercentageBox indexOfItemWithObjectValue:[NSNumber numberWithInt:100]]]; 805} 806 807- (IBAction)zoomPercentageChanged:sender 808{ 809 [self zoomToPercentage:[zoomPercentageBox objectValue]]; 810} 811 812- (IBAction)zoomStepperStepped:(id) sender 813{ 814 if([zoomStepper intValue] >= [zoomPercentageBox numberOfItems]) 815 { 816#ifdef __COCOA__ 817 NSBeep(); 818#endif 819 [zoomStepper setIntValue:[zoomPercentageBox numberOfItems]-1]; 820 return; 821 } 822 [self zoomToIndex:[zoomStepper intValue]]; 823} 824 825- (IBAction)zoomToFit:(id) sender 826{ 827 float xRatio = [[scrollView contentView] frame].size.width/[canvas size].width; 828 float yRatio = [[scrollView contentView] frame].size.height/[canvas size].height; 829 830 [self zoomToPercentage:([[scrollView contentView] frame].size.width > [canvas size].width || 831 [[scrollView contentView] frame].size.width > [canvas size].width) ? 832 [NSNumber numberWithFloat:(floorf(xRatio < yRatio ? xRatio : yRatio))*100] : 833 [NSNumber numberWithFloat:100.0f]]; 834} 835 836- (void)zoomInOnCanvasPoint:(NSPoint)point 837{ 838 [self zoomIn:self]; 839 [view centerOn:[view convertFromCanvasToViewPoint:point]]; 840} 841 842- (void)zoomOutOnCanvasPoint:(NSPoint)point 843{ 844 [self zoomOut:self]; 845 [view centerOn:[view convertFromCanvasToViewPoint:point]]; 846} 847 848- (IBAction)toggleLayersDrawer:(id) sender 849{ 850 [layerController toggle:sender]; 851} 852 853@end 854