1#import "PXToolSwitcher.h"
2#import "PXPencilTool.h"
3#import "PXEraserTool.h"
4#import "PXEyedropperTool.h"
5#import "PXZoomTool.h"
6#import "PXFillTool.h"
7#import "PXLineTool.h"
8#import "PXRectangularSelectionTool.h"
9#import "PXMoveTool.h"
10#import "PXRectangleTool.h"
11#import "PXEllipseTool.h"
12#import "PXMagicWandTool.h"
13#import "PXLassoTool.h"
14
15NSString *PXToolDidChangeNotificationName = @"PXToolDidChangeNotification";
16NSMutableArray * toolNames;
17
18@implementation PXToolSwitcher
19
20+(NSArray *) toolClasses
21{
22	return [NSArray arrayWithObjects:[PXPencilTool class], [PXEraserTool class], [PXEyedropperTool class], [PXZoomTool class], [PXFillTool class], [PXLineTool class], [PXRectangularSelectionTool class], [PXMoveTool class], [PXRectangleTool class], [PXEllipseTool class], [PXMagicWandTool class], [PXLassoTool class], nil];
23}
24
25+(id) toolNames
26{
27    return [[self toolClasses] valueForKey:@"description"];
28}
29
30- (void)lock:(NSNotification *)aNotification
31{
32    _locked = YES;
33}
34
35- (void)unlock:(NSNotification *)aNotification
36{
37    _locked = NO;
38}
39
40-(id) init
41{
42	[super init];
43	tools = [[NSMutableArray alloc] initWithCapacity:[[[self class] toolClasses] count]];
44	id enumerator = [[[self class] toolClasses] objectEnumerator];
45	id current;
46	while (( current = [enumerator nextObject] ) )
47    {
48		[tools addObject:[[current alloc] init]];
49    }
50	[tools makeObjectsPerformSelector:@selector(setSwitcher:) withObject:self];
51	[self setColor:[NSColor blackColor]];
52	[self useToolTagged:PXPencilToolTag];
53	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(lock:) name:@"PXLockToolSwitcher" object:nil];
54	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(unlock:) name:@"PXUnlockToolSwitcher" object:nil];
55	_locked = NO;
56	[self checkUserDefaults];
57	return self;
58}
59
60- (void)checkUserDefaults
61{
62  //should find a way to factor this into the tools' classes.
63  id defaults = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"p", @"e", @"d", @"z", @"f", @"l", @"s", @"m", @"r", @"o", @"w", @"a", nil]
64			      forKeys:[NSArray arrayWithObjects:[NSNumber numberWithInt:PXPencilToolTag], [NSNumber numberWithInt:PXEraserToolTag], [NSNumber numberWithInt:PXEyedropperToolTag], [NSNumber numberWithInt:PXZoomToolTag], [NSNumber numberWithInt:PXFillToolTag], [NSNumber numberWithInt:PXLineToolTag], [NSNumber numberWithInt:PXRectangularSelectionToolTag], [NSNumber numberWithInt:PXMoveToolTag], [NSNumber numberWithInt:PXRectangleToolTag], [NSNumber numberWithInt:PXEllipseToolTag], [NSNumber numberWithInt:PXMagicWandToolTag], [NSNumber numberWithInt:PXLassoToolTag], nil]];
65  id enumerator = [defaults keyEnumerator], current;
66  while ( ( current = [enumerator nextObject] ) )
67    {
68      if ([[NSUserDefaults standardUserDefaults] objectForKey:[[[self class] toolNames] objectAtIndex:[current intValue]]] == nil)
69	[[NSUserDefaults standardUserDefaults] setObject:[defaults objectForKey:current] forKey:[[[self class] toolNames] objectAtIndex:[current intValue]]];
70    }
71}
72
73- (void)dealloc
74{
75    [tools release];
76    [[NSNotificationCenter defaultCenter] removeObserver:self];
77    [super dealloc];
78}
79
80- (id) tool
81{
82    return _tool;
83}
84
85-(id) toolWithTag:(PXToolTag)tag
86{
87    return [tools objectAtIndex:tag];
88}
89
90- (PXToolTag)tagForTool:(id) aTool
91{
92    return [tools indexOfObject:aTool];
93}
94
95- (void)setIcon:(NSImage *)anImage forTool:(id)aTool
96{
97    [[toolsMatrix cellWithTag:[self tagForTool:aTool]] setImage:anImage];
98}
99
100- (void)useTool:(id) aTool
101{
102    [self useToolTagged:[self tagForTool:aTool]];
103}
104
105- (void)useToolTagged:(PXToolTag)tag
106{
107    if ( _locked )
108		return;
109
110    _lastTool = _tool;
111    _tool = [self toolWithTag:tag];
112    [toolsMatrix selectCellWithTag:tag];
113    [[NSNotificationCenter defaultCenter] postNotificationName:PXToolDidChangeNotificationName
114														object:self
115													  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:_tool, @"newTool",nil]];
116}
117
118- (void)requestToolChangeNotification
119{
120	[[NSNotificationCenter defaultCenter] postNotificationName:PXToolDidChangeNotificationName
121														object:self
122													  userInfo:[NSDictionary dictionaryWithObjectsAndKeys:_tool, @"newTool",nil]];
123}
124
125- (NSColor *) color
126{
127    return _color;
128}
129
130- (void)setColor:(NSColor *)aColor
131{
132    id enumerator = [tools objectEnumerator];
133    id current;
134    [aColor retain];
135    [_color release];
136    _color = aColor;
137
138    while ( (current = [enumerator nextObject] )  )
139    {
140        if([current respondsToSelector:@selector(setColor:)]) { [current setColor:_color]; }
141    }
142    [colorWell setColor:aColor];
143}
144
145- (IBAction)colorChanged:(id)sender
146{
147    [self setColor:[colorWell color]];
148}
149
150- (IBAction)toolClicked:(id)sender
151{
152    [self useToolTagged:[[toolsMatrix selectedCell] tag]];
153}
154
155- (IBAction)toolDoubleClicked:(id)sender
156{
157	[[NSNotificationCenter defaultCenter] postNotificationName:@"PXToolDoubleClicked" object:self];
158}
159
160- (void)keyDown:(NSEvent *)event
161{
162	NSString * chars = [[event charactersIgnoringModifiers] lowercaseString];
163	id enumerator = [[PXToolSwitcher toolNames] objectEnumerator], current;
164	while  ( ( current = [enumerator nextObject] ) )
165    {
166		if ([chars characterAtIndex:0] == [[[NSUserDefaults standardUserDefaults] objectForKey:current] characterAtIndex:0])
167		{
168			[self useToolTagged:[[PXToolSwitcher toolNames] indexOfObject:current]];
169			break;
170		}
171    }
172}
173
174- (void)optionKeyDown
175{
176    if( ! [_tool optionKeyDown] ) {
177		[self useToolTagged:PXEyedropperToolTag];
178    }
179}
180
181- (void)optionKeyUp
182{
183    if( ! [_tool optionKeyUp] ) {
184		[self useTool:_lastTool];
185    }
186}
187- (void)shiftKeyDown
188{
189    [_tool shiftKeyDown];
190}
191
192- (void)shiftKeyUp
193{
194    [_tool shiftKeyUp];
195}
196
197@end
198