1// 2// PXMagicWandTool.m 3// Pixen-XCode 4// 5// Created by Andy Matuschak on Sat Jun 12 2004. 6// Copyright (c) 2004 Open Sword Group. All rights reserved. 7// 8 9#import "PXMagicWandTool.h" 10#import "PXCanvas.h" 11#import "PXCanvasController.h" 12#import "PXTool.h" 13#import "PXLayer.h" 14#import "PXImage.h" 15#import "PXToolSwitcher.h" 16#import "PXPoint.h" 17 18@implementation PXMagicWandTool 19 20- (NSString *)name 21{ 22 return NSLocalizedString(@"MAGICWAND_NAME", @"Magic Wand Tool"); 23} 24 25- (BOOL)shiftKeyDown 26{ 27 isAdding = YES; 28 [switcher setIcon:[NSImage imageNamed:@"magicadd"] forTool:self]; 29 return YES; 30} 31 32- (BOOL)shiftKeyUp 33{ 34 isAdding = NO; 35 [switcher setIcon:[NSImage imageNamed:@"magic"] forTool:self]; 36 return YES; 37} 38 39- (BOOL)optionKeyDown 40{ 41 isSubtracting = YES; 42 [switcher setIcon:[NSImage imageNamed:@"magicsubtract"] forTool:self]; 43 return YES; 44} 45 46- init 47{ 48 [super init]; 49 selectedPoints = [[NSMutableArray alloc] init]; 50 return self; 51} 52 53- (void)dealloc 54{ 55 [selectedPoints release]; 56 [super dealloc]; 57} 58 59- (BOOL)optionKeyUp 60{ 61 isSubtracting = NO; 62 [switcher setIcon:[NSImage imageNamed:@"magic"] forTool:self]; 63 return YES; 64} 65 66- actionName 67{ 68 return NSLocalizedString(@"MAGICWAND_ACTION", @"Selection"); 69} 70 71- movingActionName 72{ 73 return NSLocalizedString(@"MOVE_ACTION", @"Moving"); 74} 75 76- (void)startMovingCanvas:canvas 77{ 78 [[self undoManager] setActionName:[self movingActionName]]; 79 isMoving = YES; 80} 81 82- (void)stopMovingCanvas:canvas 83{ 84 isMoving = NO; 85 selectedRect = lastSelectedRect; 86 [[canvas activeLayer] finalizeMotion]; 87} 88 89- (BOOL)shouldAbandonFillingAtPoint:(NSPoint)aPoint fromCanvasController:controller 90{ 91 return NO; 92} 93 94- (void)setLayers:layers fromLayers:oldLayers ofCanvas:canvas 95{ 96 [[[self undoManager] prepareWithInvocationTarget:self] setLayers:oldLayers fromLayers:layers ofCanvas:canvas]; 97 [canvas setLayers:layers]; 98} 99 100- (void)mouseDownAt:(NSPoint)aPoint fromCanvasController:controller 101{ 102 [[self undoManager] beginUndoGrouping]; 103 [self setLayers:[[[controller canvas] layers] deepMutableCopy] fromLayers:[[controller canvas] layers] ofCanvas:[controller canvas]]; 104 105 if([[controller canvas] pointIsSelected:aPoint] && !isSubtracting) 106 { 107 lastSelectedRect = [[controller canvas] selectedRect]; 108 [self startMovingCanvas:[controller canvas]]; 109 } 110 else 111 { 112 if (!isAdding && !isSubtracting) 113 { 114 oldLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] activeLayer]]; 115 oldLastLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] lastActiveLayer]]; 116 selectedRect = NSZeroRect; 117 if ([[controller canvas] hasSelection]) 118 { 119 NSRect deselectRect = [[controller canvas] selectedRect]; 120 [[controller canvas] deselect]; 121 [[controller canvas] changedInRect:NSMakeRect(deselectRect.origin.x-2, deselectRect.origin.y-2, deselectRect.size.width+4, deselectRect.size.height+4)]; 122 } 123 } 124 if (isAdding) 125 { 126 if (oldLastLayerIndex < [[[controller canvas] layers] count]) 127 { 128 [[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:[[[controller canvas] layers] objectAtIndex:oldLastLayerIndex]]; 129 } 130 else 131 { 132 [[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:nil]; 133 } 134 } 135 [super mouseDownAt:aPoint fromCanvasController:controller]; 136 } 137 [[self undoManager] endUndoGrouping]; 138} 139 140- (void)mouseDraggedFrom:(NSPoint)initialPoint to:(NSPoint)finalPoint fromCanvasController:controller 141{ 142 if(isMoving) 143 { 144 [[[controller canvas] activeLayer] translateXBy:(finalPoint.x - initialPoint.x) yBy:(finalPoint.y - initialPoint.y)]; 145 [[controller canvas] changedInRect:NSMakeRect(0,0,[[controller canvas] size].width,[[controller canvas] size].height)]; 146 } 147} 148 149- (void)mouseUpAt:(NSPoint)aPoint fromCanvasController:controller 150{ 151 if(isMoving) 152 { 153 [self stopMovingCanvas:[controller canvas]]; 154 } 155 else 156 { 157 NSEnumerator *enumerator = [selectedPoints objectEnumerator]; 158 id current; 159 while ( (current = [enumerator nextObject] ) ) 160 { 161 if (isSubtracting) 162 { 163 NSPoint currentPoint = [current pointValue]; 164 [[controller canvas] deselectPixelAtPoint:currentPoint]; 165 if ([[controller canvas] pointIsSelected:currentPoint]) 166 { 167 [[[controller canvas] lastActiveLayer] setColor:[[[[controller canvas] layers] lastObject] colorAtPoint:currentPoint] atPoint:currentPoint]; 168 } 169 [[[[controller canvas] layers] lastObject] setColor:nil atPoint:currentPoint]; 170 } else { 171 [[controller canvas] selectPixelAtPoint:[current pointValue]]; 172 } 173 } 174 if (isSubtracting && NSEqualRects([[controller canvas] selectedRect], NSZeroRect)) 175 { 176 [[controller canvas] deselect]; 177 } 178 [[controller canvas] changedInRect:NSMakeRect(selectedRect.origin.x-2, selectedRect.origin.y-2, selectedRect.size.width+4, selectedRect.size.height+4)]; 179 selectedRect = NSZeroRect; 180 [selectedPoints removeAllObjects]; 181 [[controller canvas] finalizeSelection]; 182 } 183} 184 185- (BOOL)point:(NSPoint)aPoint isUsefulForReplacing:oldColor inCanvas:aCanvas shouldCheckToTheLeft:(BOOL)check 186{ 187 return (([[NSUserDefaults standardUserDefaults] boolForKey:@"PXShouldTile"] ? YES : (aPoint.y < [aCanvas size].height)) && 188 ([[NSUserDefaults standardUserDefaults] boolForKey:@"PXShouldTile"] ? YES : (aPoint.y >= 0)) && 189 ([[aCanvas colorAtPoint:aPoint] isEqual:oldColor] && 190 (check ? ![[aCanvas colorAtPoint:NSMakePoint(aPoint.x-1, aPoint.y)] isEqual:oldColor] : YES)) && 191 (isSubtracting ? [aCanvas pointIsSelected:aPoint] : ![aCanvas pointIsSelected:aPoint]) && 192 ![selectedPoints containsObject:[PXPoint withNSPoint:aPoint]]); 193} 194 195- (void)activatePointWithOldColor:oldColor newColor:newColor atPoints:thisTimeFilled ofCanvas:aCanvas 196{ 197 id enumerator = [thisTimeFilled objectEnumerator], current; 198 [selectedPoints addObjectsFromArray:thisTimeFilled]; 199 while ( (current = [enumerator nextObject]) ) 200 { 201 selectedRect = NSUnionRect(selectedRect, NSMakeRect([current pointValue].x, [current pointValue].y, 1, 1)); 202 lastSelectedRect = selectedRect; 203 } 204} 205 206@end 207