1// 2// PXLassoTool.m 3// Pixen-XCode 4// 5// Created by Joe Osborn on Sat Jun 12 2004. 6// Copyright (c) 2004 Open Sword Group. All rights reserved. 7// 8 9#import "PXLassoTool.h" 10#import "PXCanvasController.h" 11#import "PXCanvas.h" 12#import "PXSelectionLayer.h" 13#import "PXToolSwitcher.h" 14 15#ifndef __COCOA__ 16#import "NSArray_DeepMutableCopy.h" 17#endif 18 19@implementation PXLassoTool 20 21- (NSString *)name 22{ 23 return NSLocalizedString(@"LASSO_NAME", @"Lasso Tool"); 24} 25 26- init 27{ 28 [super init]; 29 selected = [[NSMutableArray alloc] initWithCapacity:128*128]; 30 isClicking = NO; 31 return self; 32} 33 34- actionName 35{ 36 return NSLocalizedString(@"LASSO_ACTION", @"Selection"); 37} 38 39- movingActionName 40{ 41 return NSLocalizedString(@"MOVE_ACTION", @"Moving"); 42} 43 44- (BOOL)shiftKeyDown 45{ 46 if (!isClicking) 47 { 48 isAdding = YES; 49 [switcher setIcon:[NSImage imageNamed:@"lassoadd"] forTool:self]; 50 } 51 return YES; 52} 53 54- (BOOL)shiftKeyUp 55{ 56 if (!isClicking) 57 { 58 isAdding = NO; 59 [switcher setIcon:[NSImage imageNamed:@"lasso"] forTool:self]; 60 } 61 return YES; 62} 63 64- (BOOL)optionKeyDown 65{ 66 if (!isClicking) 67 { 68 isSubtracting = YES; 69 [switcher setIcon:[NSImage imageNamed:@"lassosubtract"] forTool:self]; 70 } 71 return YES; 72} 73 74- (BOOL)optionKeyUp 75{ 76 if (!isClicking) 77 { 78 isSubtracting = NO; 79 [switcher setIcon:[NSImage imageNamed:@"lasso"] forTool:self]; 80 } 81 return YES; 82} 83 84- (void)mouseDownAt:(NSPoint)aPoint fromCanvasController:controller 85{ 86 if (isSubtracting && ![[controller canvas] hasSelection]) { return; } 87 88 [selected removeAllObjects]; 89 isClicking = YES; 90 origin = aPoint; 91 leftMost = origin.x; 92 rightMost = origin.x; 93 bottomMost = origin.y; 94 topMost = origin.y; 95 [path release]; 96 path = [[NSBezierPath bezierPath] retain]; 97 [path moveToPoint:origin]; 98 [self setLayers:[[[controller canvas] layers] deepMutableCopy] fromLayers:[[controller canvas] layers] ofCanvas:[controller canvas]]; 99 100 if([[controller canvas] pointIsSelected:aPoint] && (!isAdding && !isSubtracting)) 101 { 102 [self startMovingCanvas:[controller canvas]]; 103 } 104 else 105 { 106 if (!isAdding && !isSubtracting) 107 { 108 [[controller canvas] deselect]; 109 oldLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] activeLayer]]; 110 oldLastLayerIndex = [[[controller canvas] layers] indexOfObject:[[controller canvas] lastActiveLayer]]; 111 } 112 else 113 { 114 if (oldLastLayerIndex != NSNotFound) 115 { 116 [[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:[[[controller canvas] layers] objectAtIndex:oldLastLayerIndex]]; 117 } 118 else 119 { 120 [[controller canvas] restoreActivateLayer:[[[controller canvas] layers] objectAtIndex:oldLayerIndex] lastActiveLayer:nil]; 121 } 122 } 123 [super mouseDownAt:aPoint fromCanvasController:controller]; 124 [[controller canvas] changedInRect:NSMakeRect(leftMost-2, bottomMost-2, rightMost-leftMost-2, topMost-bottomMost-2)]; 125 } 126 127 if (isSubtracting) 128 { 129 [[[[controller canvas] layers] lastObject] setIsSubtracting:YES]; 130 } 131} 132 133- (void)setLayers:layers fromLayers:oldLayers ofCanvas:canvas 134{ 135 [[[self undoManager] prepareWithInvocationTarget:self] setLayers:oldLayers fromLayers:layers ofCanvas:canvas]; 136 [canvas setLayers:layers]; 137} 138 139- (void)startMovingCanvas:canvas 140{ 141 [[self undoManager] setActionName:[self movingActionName]]; 142 isMoving = YES; 143} 144 145- (void)stopMovingCanvas:canvas 146{ 147 isMoving = NO; 148 [[canvas activeLayer] finalizeMotion]; 149} 150 151- (void)mouseDraggedFrom:(NSPoint)initialPoint to:(NSPoint)finalPoint fromCanvasController:controller 152{ 153 if (isSubtracting && ![[controller canvas] hasSelection]) { return; } 154 155 if(isMoving) 156 { 157 [[[controller canvas] activeLayer] translateXBy:(finalPoint.x - initialPoint.x) yBy:(finalPoint.y - initialPoint.y)]; 158 [[controller canvas] changedInRect:NSMakeRect(0,0,[[controller canvas] size].width,[[controller canvas] size].height)]; 159 } 160 else 161 { 162 [[self undoManager] setActionName:[self actionName]]; 163 [super mouseDraggedFrom:initialPoint to:finalPoint fromCanvasController:controller]; 164 } 165} 166 167- (void)mouseUpAt:(NSPoint)aPoint fromCanvasController:controller 168{ 169 if (isSubtracting && ![[controller canvas] hasSelection]) { return; } 170 171 isClicking = NO; 172 if(isMoving) 173 { 174 [self stopMovingCanvas:[controller canvas]]; 175 } 176 else if(NSEqualPoints(origin, aPoint) && ([selected count] <= 1)) 177 { 178 NSRect deselectRect = [[controller canvas] selectedRect]; 179 [[controller canvas] deselect]; 180 [[controller canvas] changedInRect:NSMakeRect(deselectRect.origin.x-2, deselectRect.origin.y-2, deselectRect.size.width+4, deselectRect.size.height+4)]; 181 } 182 else 183 { 184 [path lineToPoint:aPoint]; 185 id enumerator = [selected objectEnumerator]; 186 id current; 187 while ( ( current = [enumerator nextObject] ) ) 188 { 189 [[controller canvas] deselectPixelAtPoint:NSPointFromString(current)]; 190 } 191 int i, j; 192 //go from left to right 193 for(i = leftMost; i <= rightMost; i++) 194 { 195 //go from bottom to top 196 for(j = bottomMost; j <= topMost; j++) 197 { 198 NSPoint point = NSMakePoint(i, j); 199 if([path containsPoint:point]) 200 { 201 if(isSubtracting) 202 { 203 if ([[controller canvas] pointIsSelected:point] && [[[[controller canvas] layers] lastObject] colorAtPoint:point] != nil) 204 { 205 [[controller canvas] deselectPixelAtPoint:point]; 206 [[controller canvas] setColor:[[[[controller canvas] layers] lastObject] colorAtPoint:point] atPoint:point]; 207 [[[[controller canvas] layers] lastObject] setColor:nil atPoint:point]; 208 } 209 } 210 else 211 { 212 [[controller canvas] selectPixelAtPoint:point]; 213 } 214 } 215 } 216 } 217 if (isSubtracting) 218 { 219 [[[[controller canvas] layers] lastObject] setIsSubtracting:NO]; 220 } 221 [[controller canvas] finalizeSelection]; 222 [super mouseUpAt:aPoint fromCanvasController:controller]; 223 } 224 225 if([[self undoManager] groupingLevel] != 0) 226 { 227 [[self undoManager] endUndoGrouping]; 228 } 229 [[controller canvas] changedInRect:NSMakeRect(leftMost-8, bottomMost-8, rightMost-leftMost+16, topMost-bottomMost+16)]; 230} 231 232 233- (void)drawPixelAtPoint:(NSPoint)point inCanvas:canvas 234{ 235 leftMost = MIN(point.x, leftMost); 236 rightMost = MAX(point.x, rightMost); 237 bottomMost = MIN(point.y, bottomMost); 238 topMost = MAX(point.y, topMost); 239 [canvas selectPixelAtPoint:point]; 240 [selected addObject:NSStringFromPoint(point)]; 241 [canvas changedInRect:NSMakeRect(point.x-8, point.y-8, 16, 16)]; 242 [path lineToPoint:point]; 243} 244 245@end 246