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