Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 248 lines (188 sloc) 9.442 kb
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
1 /*
2 Not only does this plugin load up the JSTalk Listener, so we can talk to Acorn via JSTalk, it also adds support for JavaScript Plugins, via Acorn's plugin API.
3 */
4
5
ee99867 @ccgus oh geeze
authored
6 #import "JSEnablerPlugIn.h"
7 #import "ACPlugin.h"
db8c761 @ccgus I realized removing the jstalk object after executing a string, won't…
authored
8 #import "JSTalk.h"
977c27f @ccgus Fixed a compile error.
authored
9 #import "JSCocoa.h"
10 #import <JavaScriptCore/JavaScriptCore.h>
ee99867 @ccgus oh geeze
authored
11
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
12 #define ACScriptMenuTitleKey @"ACScriptMenuTitle"
13 #define ACScriptSuperMenuTitleKey @"ACScriptSuperMenuTitle"
14 #define ACShortcutKeyKey @"ACShortcutKey"
15 #define ACShortcutMaskKey @"ACShortcutMask"
d6c2b3c @ccgus New Acorn filter stuff.
authored
16 #define ACIsActionKey @"ACIsAction"
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
17
ee99867 @ccgus oh geeze
authored
18 @interface JSEnablerPlugIn (SuperSecret)
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
19 - (void)findJSCocoaScriptsForPluginManager:(id<ACPluginManager>)pluginManager;
ee99867 @ccgus oh geeze
authored
20 @end
21
22
23 @implementation JSEnablerPlugIn
24
db8c761 @ccgus I realized removing the jstalk object after executing a string, won't…
authored
25 + (id)plugin {
ee99867 @ccgus oh geeze
authored
26 return [[[self alloc] init] autorelease];
27 }
28
29
db8c761 @ccgus I realized removing the jstalk object after executing a string, won't…
authored
30 - (void)didRegister {
ee99867 @ccgus oh geeze
authored
31
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
32 // this guy openes up a Distributed Objects port to listen for outside JSTalk commands commands
ee99867 @ccgus oh geeze
authored
33 [JSTalk listen];
34 }
35
db8c761 @ccgus I realized removing the jstalk object after executing a string, won't…
authored
36 - (void)willRegister:(id<ACPluginManager>)pluginManager {
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
37 [self findJSCocoaScriptsForPluginManager:pluginManager];
38 }
39
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
40 - (NSDictionary*)propertiesFromScriptAtPath:(NSString*)path {
41
42 NSError *err = 0x00;
43 NSMutableString *s = [NSMutableString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&err];
44 if (!s) {
45 NSLog(@"Error reading %@: %@", path, err);
46 return nil;
47 }
48
49 // clean up some line endings.
50 [s replaceOccurrencesOfString:@"\r\n" withString:@"\n" options:0 range:NSMakeRange(0, [s length])];
51 [s replaceOccurrencesOfString:@"\r" withString:@"\n" options:0 range:NSMakeRange(0, [s length])];
52
53 NSMutableDictionary *d = [NSMutableDictionary dictionary];
d6c2b3c @ccgus New Acorn filter stuff.
authored
54 NSString *menuTitle = nil;
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
55 NSString *shortcutKey = @"";
56 NSString *superMenuTitle = nil;
d6c2b3c @ccgus New Acorn filter stuff.
authored
57 int shortcutMask = 0;
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
58 NSEnumerator *enumerator = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
59 NSString *line;
d6c2b3c @ccgus New Acorn filter stuff.
authored
60 BOOL isAction = NO;
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
61
62 while ((line = [enumerator nextObject])) {
63
64 if ([line hasPrefix:@"VPEndConfig"]) {
65 break;
66 }
67 else if ([line hasPrefix:ACScriptMenuTitleKey]) {
68 int eqIdx = [line rangeOfString:@"="].location;
69 if (eqIdx != NSNotFound && [line length] > eqIdx + 1) {
70 menuTitle = [[line substringFromIndex:eqIdx+1]
71 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
72 }
73 }
74 else if ([line hasPrefix:ACScriptSuperMenuTitleKey]) {
75 int eqIdx = [line rangeOfString:@"="].location;
76 if (eqIdx != NSNotFound && [line length] > eqIdx + 1) {
77 superMenuTitle = [[line substringFromIndex:eqIdx+1]
78 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
79 }
80 }
81 else if ([line hasPrefix:ACShortcutKeyKey]) {
82 int eqIdx = [line rangeOfString:@"="].location;
83 if (eqIdx != NSNotFound && [line length] > eqIdx + 1) {
84 shortcutKey = [[line substringFromIndex:eqIdx+1]
85 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
86 }
87 }
d6c2b3c @ccgus New Acorn filter stuff.
authored
88 else if ([line hasPrefix:ACIsActionKey]) {
89 int eqIdx = [line rangeOfString:@"="].location;
90 if (eqIdx != NSNotFound && [line length] > eqIdx + 1) {
91 NSString *val = [[line substringFromIndex:eqIdx+1]
92 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
93 isAction = [val boolValue];
94 }
95 }
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
96 else if ([line hasPrefix:ACShortcutMaskKey]) {
97 int eqIdx = [line rangeOfString:@"="].location;
98 if (eqIdx != NSNotFound && [line length] > eqIdx + 1) {
99 NSString *junk = [[line substringFromIndex:eqIdx+1]
100 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
101
102 junk = [junk lowercaseString];
103
104 if ([junk rangeOfString:@"command"].location != NSNotFound) {
105 shortcutMask = shortcutMask | NSCommandKeyMask;
106 }
107 if ([junk rangeOfString:@"option"].location != NSNotFound) {
108 shortcutMask = shortcutMask | NSAlternateKeyMask;
109 }
110 if ([junk rangeOfString:@"shift"].location != NSNotFound) {
111 shortcutMask = shortcutMask | NSShiftKeyMask;
112 }
113 if ([junk rangeOfString:@"control"].location != NSNotFound) {
114 shortcutMask = shortcutMask | NSControlKeyMask;
115 }
116 }
117 }
118 }
119
120
121 if (menuTitle) {
122 [d setObject:menuTitle forKey:ACScriptMenuTitleKey];
123 }
124
125 if (superMenuTitle) {
126 [d setObject:superMenuTitle forKey:ACScriptSuperMenuTitleKey];
127 }
128
129 if (shortcutKey) {
130 [d setObject:shortcutKey forKey:ACShortcutKeyKey];
131 }
132
133 [d setObject:[NSNumber numberWithInt:shortcutMask] forKey:ACShortcutMaskKey];
d6c2b3c @ccgus New Acorn filter stuff.
authored
134 [d setObject:[NSNumber numberWithBool:isAction] forKey:ACIsActionKey];
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
135
136 return d;
137 }
138
139
db8c761 @ccgus I realized removing the jstalk object after executing a string, won't…
authored
140 - (void)findJSCocoaScriptsForPluginManager:(id<ACPluginManager>)pluginManager {
ee99867 @ccgus oh geeze
authored
141
142 NSString *pluginDir = [@"~/Library/Application Support/Acorn/Plug-Ins/" stringByExpandingTildeInPath];
143 NSFileManager *fm = [NSFileManager defaultManager];
144 BOOL isDir = NO;
145
146 if (!([fm fileExistsAtPath:pluginDir isDirectory:&isDir] && isDir)) {
147 return;
148 }
149
150 for (NSString *fileName in [fm contentsOfDirectoryAtPath:pluginDir error:nil]) {
151
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
152 if (!([fileName hasSuffix:@".js"] || [fileName hasSuffix:@".jscocoa"] || [fileName hasSuffix:@".jstalk"])) {
ee99867 @ccgus oh geeze
authored
153 continue;
154 }
155
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
156 NSDictionary *scriptProperties = [self propertiesFromScriptAtPath:[pluginDir stringByAppendingPathComponent:fileName]];
157
158
159 NSString *menuTitle = [scriptProperties objectForKey:ACScriptMenuTitleKey];
160 menuTitle = menuTitle ? menuTitle : [fileName stringByDeletingPathExtension];
161
162 NSString *shortcutKey = [scriptProperties objectForKey:ACShortcutKeyKey];
163 shortcutKey = shortcutKey ? shortcutKey : @"";
164
165 NSString *superMenuTitle = [scriptProperties objectForKey:ACScriptSuperMenuTitleKey];
166 NSUInteger shortcutMask = [[scriptProperties objectForKey:ACShortcutMaskKey] unsignedIntegerValue];
167
168
d6c2b3c @ccgus New Acorn filter stuff.
authored
169 if ([[scriptProperties objectForKey:ACIsActionKey] boolValue]) {
170 [pluginManager addActionMenuTitle:menuTitle
171 withSuperMenuTitle:superMenuTitle
172 target:self
173 action:@selector(executeScriptForImage:scriptPath:)
174 keyEquivalent:shortcutKey
175 keyEquivalentModifierMask:shortcutMask
176 userObject:[pluginDir stringByAppendingPathComponent:fileName]];
177 }
178 else {
179
180 [pluginManager addFilterMenuTitle:menuTitle
181 withSuperMenuTitle:superMenuTitle
182 target:self
183 action:@selector(executeScriptForImage:scriptPath:)
184 keyEquivalent:shortcutKey
185 keyEquivalentModifierMask:shortcutMask
186 userObject:[pluginDir stringByAppendingPathComponent:fileName]];
187 }
ee99867 @ccgus oh geeze
authored
188 }
189 }
190
191
192
651ad72 @ccgus Updated Acorn plugin.
authored
193 - (CIImage*)executeScriptForImage:(id<ACLayer>)currentLayer scriptPath:(NSString*)scriptPath {
ee99867 @ccgus oh geeze
authored
194
195 NSError *err = 0x00;
196 NSString *theJavaScript = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:&err];
197
198 if (err) {
199 NSBeep();
200 NSLog(@"%@", err);
201 return nil;
202 }
203
651ad72 @ccgus Updated Acorn plugin.
authored
204 CIImage *image = [currentLayer CIImage];
205
ee99867 @ccgus oh geeze
authored
206 JSTalk *jstalk = [[[JSTalk alloc] init] autorelease];
207
208 [jstalk executeString:theJavaScript];
209
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
210 /*
211 Our script should look, at least a little bit like this:
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
212 function main(image, doc, layer) {
cbdc2a9 @ccgus [UPDATES] General code cleanup for the Acorn and VoodooPad sample plu…
authored
213 // do fancy image stuff
214 return image;
215 }
216 */
217
651ad72 @ccgus Updated Acorn plugin.
authored
218 id document = [(id)currentLayer valueForKey:@"document"]; // shh!
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
219
651ad72 @ccgus Updated Acorn plugin.
authored
220 JSValueRef returnValue = [[jstalk jsController] callJSFunctionNamed:@"main" withArguments:image, document, currentLayer, nil];
ee99867 @ccgus oh geeze
authored
221
222 // Hurray?
223 // The main() method should be returning a value at this point, so we're going to
224 // put it back into a cocoa object. If it's not there, then it'll be nil and that's
225 // ok for our purposes.
226 CIImage *acornReturnValue = 0x00;
227
228 if (![JSCocoaFFIArgument unboxJSValueRef:returnValue toObject:&acornReturnValue inContext:[[jstalk jsController] ctx]]) {
229 return nil;
230 }
231
232 // fin.
233 return acornReturnValue;
234 }
235
d980bcc @ccgus You can now set some shortcut keys and such for the JSTalk plugin in …
authored
236 - (NSNumber*)worksOnShapeLayers:(id)userObject {
237 return [NSNumber numberWithBool:YES];
238 }
239
d6c2b3c @ccgus New Acorn filter stuff.
authored
240 - (NSNumber*)validateForLayer:(id)userObject {
241 return [NSNumber numberWithBool:YES];
242 }
243
ee99867 @ccgus oh geeze
authored
244 @end
245
246
247
Something went wrong with that request. Please try again.