1// 2// PXLayerController.m 3// Pixen-XCode 4// 5// Created by Joe Osborn on Thu Feb 05 2004. 6// Copyright (c) 2004 Open Sword Group. All rights reserved. 7// 8 9#import "PXLayerController.h" 10#import "PXLayerDetailsView.h" 11#import "PXCanvas.h" 12#import "PXLayer.h" 13#import "PXSelectionLayer.h" 14#import "SubviewTableViewController.h" 15 16NSString * PXLayerSelectionDidChangeName = @"PXLayerNotificationDidChange"; 17NSString * PXCanvasLayerSelectionDidChangeName = @"PXCanvasLayerNotificationDidChange"; 18 19@implementation PXLayerController 20 21- initWithCanvas:aCanvas 22{ 23 [super init]; 24 [NSBundle loadNibNamed:@"PXLayerController" owner:self]; 25 views = [[NSMutableArray alloc] initWithCapacity:8]; 26 [self selectRow:-1]; 27 [self setCanvas:aCanvas]; 28 [tableView registerForDraggedTypes:[NSArray arrayWithObject:@"PXLayerRowPasteType"]]; 29 return self; 30} 31 32- (void)setNextResponder:responder 33{ 34 [super setNextResponder:responder]; 35 [drawer setNextResponder:self]; 36 [tableView setNextResponder:self]; 37} 38 39- (void)mouseMoved:(NSEvent *)event 40{ 41 NSPoint location = [event locationInWindow]; 42 location.x -= ([drawer contentSize].width + 11); 43 location.y += 15; 44 id newEvent = [NSEvent mouseEventWithType:[event type] location:location modifierFlags:[event modifierFlags] timestamp:[event timestamp] windowNumber:[event windowNumber] context:[event context] eventNumber:[event eventNumber]+1 clickCount:0 pressure:0]; 45 [[self nextResponder] mouseMoved:newEvent]; 46} 47 48- (void)setCanvas:aCanvas 49{ 50 [[NSNotificationCenter defaultCenter] removeObserver:self]; 51 [aCanvas retain]; 52 [canvas release]; 53 canvas = aCanvas; 54 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadData:) name:PXCanvasLayersChangedNotificationName object:canvas]; 55 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(canvasLayerChanged:) name:PXCanvasLayerSelectionDidChangeName object:canvas]; 56 [self reloadData:nil]; 57} 58 59- (void)dealloc 60{ 61 [views release]; 62 [canvas release]; 63 [tableViewController release]; 64 [super dealloc]; 65} 66 67- (void)awakeFromNib 68{ 69 [tableView setIntercellSpacing:NSMakeSize(0,1)]; 70 tableViewController = [[SubviewTableViewController controllerWithViewColumn:[tableView tableColumnWithIdentifier:@"details"]] retain]; 71 [tableViewController setDelegate:self]; 72} 73 74- undoManager 75{ 76 return [[[NSDocumentController sharedDocumentController] currentDocument] undoManager]; // NOTE: this may not work in all cases 77} 78 79- (void)resetViewHiddenStatus 80{ 81 BOOL shouldBeHidden = (([drawer state] == NSDrawerClosedState) || ([drawer state] == NSDrawerClosingState)); 82 id enumerator = [views objectEnumerator]; 83 id current; 84 while ( (current = [enumerator nextObject] ) ) 85 { 86 [current setHidden:shouldBeHidden]; 87 } 88} 89 90- (NSView *) tableView:(NSTableView *)tableView viewForRow:(int)row 91{ 92 return [views objectAtIndex:[self invertLayerIndex:row]]; 93} 94 95- (int)numberOfRowsInTableView:view 96{ 97 return [[canvas layers] count]; 98} 99 100- (void)reloadData:aNotification 101{ 102 int i, selectedRow; 103 [views makeObjectsPerformSelector:@selector(invalidateTimer)]; 104 if ([tableView selectedRow] == -1) { [self selectRow:0]; } 105 selectedRow = [self invertLayerIndex:[tableView selectedRow]]; 106 for(i = 0; i < [[canvas layers] count]; i++) 107 { 108 id layer = [[canvas layers] objectAtIndex:i]; 109 NSLog(@"ploplppoplpop "); 110 if([views count] > i) 111 { 112 [[views objectAtIndex:i] setLayer:layer]; 113 } 114 else 115 { 116 NSLog(@"before NewView"); 117 id newView = [[[PXLayerDetailsView alloc] initWithLayer:layer] autorelease]; 118 NSLog(@"newView %@",newView); 119 [views addObject:newView]; 120 } 121 } 122 [views removeObjectsInRange:NSMakeRange(i, [views count] - i)]; 123 [tableViewController reloadTableView]; 124 [self selectRow:[self invertLayerIndex:selectedRow]]; 125 [self resetViewHiddenStatus]; 126 [[canvas layers] makeObjectsPerformSelector:@selector(setLayerController:) withObject:self]; 127} 128 129- (IBAction)nextLayer:sender 130{ 131 [self selectRow:[tableView selectedRow]+1]; 132 [self selectLayer:[[canvas layers] objectAtIndex:[self invertLayerIndex:[tableView selectedRow]]]]; 133} 134 135- (IBAction)previousLayer:sender 136{ 137 [self selectRow:[tableView selectedRow]-1]; 138 [self selectLayer:[[canvas layers] objectAtIndex:[self invertLayerIndex:[tableView selectedRow]]]]; 139} 140 141- (void)selectRow:(int)index 142{ 143 if ([tableView respondsToSelector:@selector(selectRowIndexes:byExtendingSelection:)]) 144 { 145#ifdef __COCOA__ 146 [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO]; 147#else 148 if ( index > 0 ) 149 { 150 // NSLog(@"respondsToSelector selectRowIndexes: byExtendingSelection"); 151 [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO]; 152 } 153#endif 154 } 155 else 156 { 157 [tableView selectRow:index byExtendingSelection:NO]; 158 } 159 [self updateRemoveButtonStatus]; 160} 161 162- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex 163{ 164 NSLog(@" NUMBEROFROWSINTABLEVIEW %@",[NSNumber numberWithBool:[[[canvas layers] objectAtIndex:[self invertLayerIndex:rowIndex]] visible]]); 165 if([[aTableColumn identifier] isEqualToString:@"visible"]) 166 { 167 NSLog(@" NUMBEROFROWSINTABLEVIEW %@",[NSNumber numberWithBool:[[[canvas layers] objectAtIndex:[self invertLayerIndex:rowIndex]] visible]]); 168 return [NSNumber numberWithBool:[[[canvas layers] objectAtIndex:[self invertLayerIndex:rowIndex]] visible]]; 169 } 170 return nil; 171} 172 173- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex 174{ 175 if([[aTableColumn identifier] isEqualToString:@"visible"]) 176 { 177 [[[canvas layers] objectAtIndex:[self invertLayerIndex:rowIndex]] setVisible:[anObject boolValue]]; 178 [canvas changedInRect:NSMakeRect(0,0,[canvas size].width, [canvas size].height)]; 179 } 180} 181 182- (void)toggle:sender 183{ 184 [drawer toggle:sender]; 185 [drawer setContentSize:NSMakeSize(233, [drawer contentSize].height)]; 186 [self resetViewHiddenStatus]; 187} 188 189- (void)setWindow:aWindow 190{ 191 window = aWindow; 192 [drawer setParentWindow:window]; 193} 194 195- (void)setLayers:layers fromLayers:oldLayers resetSelection:(BOOL)resetSelection 196{ 197 [[[self undoManager] prepareWithInvocationTarget:self] setLayers:oldLayers fromLayers:layers resetSelection:YES]; 198 [canvas setLayers:layers]; 199 if (resetSelection) 200 { 201 [self selectRow:0]; 202 [self selectLayer:nil]; 203 } 204} 205 206- (IBAction)addLayer:sender 207{ 208 [[self undoManager] beginUndoGrouping]; 209 [[self undoManager] setActionName:@"Add Layer"]; 210 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers] resetSelection:YES]; 211 [canvas deselect]; 212 213 PXLayer *layer = [[PXLayer alloc] initWithName:@"New Layer" size:[canvas size]]; 214 [layer setLayerController:self]; 215 [canvas addLayer:layer]; 216 [self selectRow:0]; 217 [self selectLayer:nil]; 218 [[self undoManager] endUndoGrouping]; 219} 220 221- (void)removeLayerAtCanvasLayersIndex:(unsigned)index 222{ 223 [[self undoManager] beginUndoGrouping]; 224 [[self undoManager] setActionName:@"Remove Layer"]; 225 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers] resetSelection:NO]; 226 [canvas deselect]; 227 [canvas removeLayerAtIndex:index]; 228 [self selectRow:[self invertLayerIndex:0]]; 229 [self selectLayer:nil]; 230 [[self undoManager] endUndoGrouping]; 231} 232 233- (IBAction)duplicateLayerAtCanvasLayersIndex:(unsigned)index 234{ 235 [[self undoManager] beginUndoGrouping]; 236 [[self undoManager] setActionName:@"Duplicate Layer"]; 237 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers] resetSelection:NO]; 238 [canvas insertLayer:[[[[canvas layers] objectAtIndex:index] copy] autorelease] atIndex:index]; 239 [canvas changedInRect:NSMakeRect(0, 0, [canvas size].width, [canvas size].height)]; 240 [[self undoManager] endUndoGrouping]; 241} 242 243 244- (void)duplicateLayerObject:layer 245{ 246 [self duplicateLayerAtCanvasLayersIndex:[[canvas layers] indexOfObject:layer]]; 247} 248 249- (IBAction)duplicateLayer:sender 250{ 251 if ([tableView selectedRow] == -1) { return; } 252 [self duplicateLayerAtCanvasLayersIndex:[self invertLayerIndex:[tableView selectedRow]]]; 253} 254 255- (void)removeLayerObject:layer 256{ 257 [self removeLayerAtCanvasLayersIndex:[[canvas layers] indexOfObject:layer]]; 258} 259 260- (IBAction)removeLayer:sender 261{ 262 if ([tableView selectedRow] == -1) { return; } 263 [self removeLayerAtCanvasLayersIndex:[self invertLayerIndex:[tableView selectedRow]]]; 264} 265 266- (IBAction)selectLayer:sender 267{ 268 if ([tableView selectedRow] == -1) { [self selectRow:0]; } 269 int row = [self invertLayerIndex:[tableView selectedRow]]; 270 if (![[[canvas layers] lastObject] isKindOfClass:[PXSelectionLayer class]]) 271 { 272 [canvas deselect]; 273 } 274 [self selectRow:[self invertLayerIndex:row]]; 275 [[NSNotificationCenter defaultCenter] postNotificationName:PXLayerSelectionDidChangeName object:self userInfo:[[canvas layers] objectAtIndex:row]]; 276} 277 278- (void)updateRemoveButtonStatus 279{ 280 if ([self invertLayerIndex:[tableView selectedRow]] == 0) { [removeButton setEnabled:NO]; } 281 else { [removeButton setEnabled:YES]; } 282} 283 284- (int)invertLayerIndex:(int)anIndex 285{ 286 return [[canvas layers] count] - anIndex - 1; 287} 288 289- (void)canvasLayerChanged:notification 290{ 291 [self selectRow:[self invertLayerIndex:[[canvas layers] indexOfObject:[canvas activeLayer]]]]; 292} 293 294- (void)mergeDownLayerAtCanvasLayersIndex:(unsigned)index 295{ 296 if ([[[canvas layers] objectAtIndex:index] isKindOfClass:[PXSelectionLayer class]]) { [canvas deselect]; return; } 297 [[self undoManager] beginUndoGrouping]; 298 [[self undoManager] setActionName:@"Merge Down"]; 299 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers] resetSelection:YES]; 300 if (index == 0) { return; } 301 [[[canvas layers] objectAtIndex:index-1] compositeUnder:[[canvas layers] objectAtIndex:index] flattenOpacity:YES]; 302 [canvas removeLayerAtIndex:index]; 303 if (index >= [[canvas layers] count]) { 304 index = 0; 305 } 306 [self selectRow:[self invertLayerIndex:index]]; 307 [self selectLayer:[[canvas layers] objectAtIndex:index]]; 308 [[self undoManager] endUndoGrouping]; 309} 310 311- (void)mergeDownLayerObject:layer 312{ 313 [self mergeDownLayerAtCanvasLayersIndex:[[canvas layers] indexOfObject:layer]]; 314} 315 316- (void)mergeDown 317{ 318 [self mergeDownLayerAtCanvasLayersIndex:[self invertLayerIndex:[tableView selectedRow]]]; 319} 320 321- (BOOL)tableView:(NSTableView *)aTableView writeRows:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard 322{ 323 if ([[[canvas layers] objectAtIndex:[self invertLayerIndex:[tableView selectedRow]]] isKindOfClass:[PXSelectionLayer class]]) { return NO; } 324 [pboard declareTypes:[NSArray arrayWithObject:@"PXLayerRowPasteType"] owner:self]; 325 [pboard setString:[NSString stringWithFormat:@"%d", [self invertLayerIndex:[[rows objectAtIndex:0] intValue]]] forType:@"PXLayerRowPasteType"]; 326 //[pboard setData:[NSKeyedArchiver archivedDataWithRootObject:[[canvas layers] objectAtIndex:[self invertLayerIndex:[tableView selectedRow]]]] forType:@"PXLayerRowPasteType"]; 327 return YES; 328} 329 330- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)operation 331{ 332 if (![[[info draggingPasteboard] types] containsObject:@"PXLayerRowPasteType"]) { return NSDragOperationNone; } 333 if (operation == NSTableViewDropOn) { [aTableView setDropRow:row dropOperation:NSTableViewDropAbove]; } 334 return NSDragOperationMove; 335} 336 337- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation 338{ 339 [[self undoManager] beginUndoGrouping]; 340 [[self undoManager] setActionName:@"Reorder Layer"]; 341 [self setLayers:[[canvas layers] deepMutableCopy] fromLayers:[canvas layers] resetSelection:YES]; 342 if (row == [[canvas layers] count]) { row--; } 343 [canvas moveLayer:[[canvas layers] objectAtIndex:[[[info draggingPasteboard] stringForType:@"PXLayerRowPasteType"] intValue]] toIndex:[self invertLayerIndex:row]]; 344 //[canvas moveLayer:[[info draggingPasteboard] dataForType:@"PXLayerRowPasteType"] toIndex:[self invertLayerIndex:row]]; 345 [self selectRow:[self invertLayerIndex:[[canvas layers] indexOfObject:[canvas activeLayer]]]]; 346 [[self undoManager] endUndoGrouping]; 347 return YES; 348} 349 350@end 351