Most recent edit on 2007-09-14 18:53:13 by GusMueller
Additions:
Setting up the python plugin for the Filter menu.
To have your python plugin show up in the filter menu, you put some assignments at the top of the script. Check out the Quick Save plugin for it in action. Here's a quick description of what they mean, and valid values.
ACScriptSuperMenuTitle, The supermenu that the plugin should show up in.
ACScriptMenuTitle, The title of the plugin
ACShortcutKey, the shortcut key (a string)
ACShortcutMask, the name of the modifier(s) needed to invoke the plugin (control, option, command shift)
ACIsAction, (True | False). Wether or not the plugin should go in the File/Action menu.
Edited on 2007-09-13 15:09:26 by GusMueller
Additions:
Other UTIs you can use: public.png, public.jpeg, public.tiff, com.compuserve.gif, com.microsoft.bmp, com.apple.icns, and com.adobe.pdf
Edited on 2007-09-12 17:51:15 by GusMueller
Additions:
Python Plugins
Python plugins work a lot like the Objective-C plugins, only they are a lot easier to write since you just put a text file ending with .py in the Plug-Ins folder. Visit the AcornPlugins page for examples written in Python.
Another big advantage of writing a plugin in Python, is that you don't need to stop and restart Acorn to modify an already loaded plugin. Just edit the file, and rerun it from Acorn.
Acorn Additions
Here are some various additions to Objective-C (and also useable from the Python side) that Acorn provides:
Edited on 2007-09-12 17:46:47 by GusMueller
Additions:
So for example, if I wanted to write a quick ObjC plugin to convert the layer to grayscale, my plugin would look something something like this:
%%(Objective-C)
@implementation ACGrayscalePlugin
+ (id) plugin {
return [[[self alloc] init] autorelease];
}
- (void) willRegister:(id<ACPluginManager>)pluginManager {
[pluginManager addFilterMenuTitle:@"Grayscale"
withSuperMenuTitle:@"Color"
target:self
action:@selector(convertToGrayscale:userObject:)
keyEquivalent:@""
keyEquivalentModifierMask:0
userObject:nil];
}
- (CIImage*) convertToGrayscale:(CIImage*)image userObject:(id)uo {
CIFilter *filter = [CIFilter filterWithName: @"
CIColorMonochrome" keysAndValues: @"inputImage", image, nil];
CIColor *color = [CIColor colorWithRed:0.5f green:0.5f blue:0.5f];
[filter setDefaults];
[filter setValue:color forKey:@"inputColor"];
[filter setValue:[NSNumber numberWithFloat:1] forKey:@"inputIntensity"];
return [filter valueForKey: @"outputImage"];
}
If you don't want to return an image because you've got something else you want to do, just return nil.
Deletions:
Here's a portion of the ACPlugin.h file, which helps describe what you can then do with your image.
%%(Objective-C)enum ACLayerType {
} ACLayerType;
@protocol ACPluginManager
- (BOOL) addFilterMenuTitle:(NSString*)menuTitle
withSuperMenuTitle:(NSString*)superMenuTitle
target:(id)target
action:(SEL)selector
keyEquivalent:(NSString*)keyEquivalent
keyEquivalentModifierMask:(unsigned int)mask
userObject:(id)userObject;
- (BOOL) addActionMenuTitle:(NSString*)menuTitle
withSuperMenuTitle:(NSString*)superMenuTitle
target:(id)target
action:(SEL)selector
keyEquivalent:(NSString*)keyEquivalent
keyEquivalentModifierMask:(unsigned int)mask
userObject:(id)userObject;
@protocol ACPlugin
/*
This will create an instance of our plugin. You really shouldn't need to
worry about this at all.
*/
+ (id) plugin;
/*
This gets called right before the plugin manager registers your plugin.
I'm honestly not sure what you would use it for, but it seemed like a good
idea at the time.
*/
- (void) willRegister:(id<ACPluginManager>)thePluginManager;
/*
didRegister is called right after your plugin is all ready to go.
*/
- (void) didRegister;
@protocol ACLayer <NSObject>
/* There are currently two types of layers. "Bitmap" layers which contain pixels,
and "Shape" layers which contain Text. And maybe other things eventually.
Check out the ACLayerType enum for the constants to tell which is which.
*/
- (int) layerType;
@protocol ACShapeLayer <NSObject>
nothing to currently see here.
@protocol ACBitmapLayer <ACLayer>
set a CIImage on the layer, to be a "preview". Make sure to set it to nil when you are
done with whatever it is you are doing.
- (void) setPreviewCIImage:(CIImage*)img;
apply a ciimage to the layer.
- (void) applyCIImageFromFilter:(CIImage*)img;
grab a CIImage representation of the layer.
- (CIImage*)CIImage;
@protocol ACDocument <NSObject>
grab an array of layers in the document.
- (NSArray*) layers;
grab the current layer.
- (id<ACLayer>) currentLayer;
Edited on 2007-09-12 17:40:36 by GusMueller
Additions:
At startup Acorn looks in the ~/Library/Application Support/Acorn/Plug-Ins/ folder for two types of files.
Objective-C bundles, ending with .acplugin. For example "Grayscale.acplugin".
Python files, ending with .py. For example "Grayscale.py"
The ObjC plugins must implement the ACPlugin protocol, and register themselves with Acorn to show up in a menu. (The ACPlugin protocol is defined in the file ACPlugin.h in the examples download). When the plugin is loaded up, you are given an opportunity to say "Hey, I want to go in the XYZ filter menu, and I want you to call this selector when I'm to be used". When your method is called, you are given a CIImage, you perform whatever you want to do to the image, and then you return a CIImage to be replace what you were given.
You can also get a reference to the calling image by asking the document controller what the current document is:
[[NSDocumentController sharedDocumentController] currentDocument]
This returns a subclass of NSDocument (ACDocument), and you can use the various methods that NSDocument provides to find out information about the image. In addition, you can get different representations of the image as NSData like so:
NSDocument *theDoc = [[NSDocumentController sharedDocumentController] currentDocument];
NSData *tiffData = [theDoc dataRepresentationOfType:@"public.tiff"];
Here's a portion of the ACPlugin.h file, which helps describe what you can then do with your image.
enum ACLayerType {
ACBitmapLayer = 1,
ACShapeLayer = 2,
} ACLayerType;
@protocol ACPluginManager
- (BOOL) addFilterMenuTitle:(NSString*)menuTitle
withSuperMenuTitle:(NSString*)superMenuTitle
target:(id)target
action:(SEL)selector
keyEquivalent:(NSString*)keyEquivalent
keyEquivalentModifierMask:(unsigned int)mask
userObject:(id)userObject;
- (BOOL) addActionMenuTitle:(NSString*)menuTitle
withSuperMenuTitle:(NSString*)superMenuTitle
target:(id)target
action:(SEL)selector
keyEquivalent:(NSString*)keyEquivalent
keyEquivalentModifierMask:(unsigned int)mask
userObject:(id)userObject;
@end
@protocol ACPlugin
/*
This will create an instance of our plugin. You really shouldn't need to
worry about this at all.
*/
+ (id) plugin;
/*
This gets called right before the plugin manager registers your plugin.
I'm honestly not sure what you would use it for, but it seemed like a good
idea at the time.
*/
- (void) willRegister:(id<ACPluginManager>)thePluginManager;
/*
didRegister is called right after your plugin is all ready to go.
*/
- (void) didRegister;
@end
@protocol ACLayer <NSObject>
/* There are currently two types of layers. "Bitmap" layers which contain pixels,
and "Shape" layers which contain Text. And maybe other things eventually.
Check out the ACLayerType enum for the constants to tell which is which.
*/
- (int) layerType;
@end
@protocol ACShapeLayer <NSObject>
// nothing to currently see here.
@end
@protocol ACBitmapLayer <ACLayer>
// set a CIImage on the layer, to be a "preview". Make sure to set it to nil when you are
// done with whatever it is you are doing.
- (void) setPreviewCIImage:(CIImage*)img;
// apply a ciimage to the layer.
- (void) applyCIImageFromFilter:(CIImage*)img;
// grab a CIImage representation of the layer.
- (CIImage*)CIImage;
@end
@protocol ACDocument <NSObject>
// grab an array of layers in the document.
- (NSArray*) layers;
// grab the current layer.
- (id<ACLayer>) currentLayer;
@end
Edited on 2007-09-12 17:28:52 by GusMueller
Additions:
You can write your plugins in either Objective-C, or Python. Objective-C plugins are compiled and loaded up from bundles placed in the ~/Library/Application Support/Acorn/Plug-Ins/ folder. Python plugins are text files ending with .py. You can find some examples of Python plugins on the AcornPlugins page. You can also download example Objective-C plugins from here: SampleAcornPlugins.zip∞
Deletions:
Currently you can write your plugins in Objective-C, as a loadable bundle, or as a single Python file.
Edited on 2007-09-12 17:07:21 by GusMueller
Additions:
Acorn provides a simple Cocoa plugin API for you to alter the current bitmap layer, or perform actions with the current image.
Currently you can write your plugins in Objective-C, as a loadable bundle, or as a single Python file.
Edited on 2007-09-11 19:53:20 by GusMueller
Additions:
Additions to NSImage:
- (CIImage *)CIImage;
- (id) newDocumentWithImageData:(NSData*)data; /* takes bitmap data, (PNG, TIFF) */
Deletions:
takes bitmap data, (PNG, TIFF) and makes a new untitled document with it.
- (id) newDocumentWithImageData:(NSData*)data;
Edited on 2007-09-11 19:51:24 by GusMueller
Additions:
- (NSImage *)NSImage;
- (NSImage *)NSImageFromRect:(CGRect)r;
Additions to NSDocumentController:
takes bitmap data, (PNG, TIFF) and makes a new untitled document with it.
- (id) newDocumentWithImageData:(NSData*)data;
Deletions:
Additions to NSDocument:
Edited on 2007-09-11 19:28:23 by GusMueller
Additions:
The different types of plugins:
Edited on 2007-09-11 19:28:01 by GusMueller
Additions:
Back to AcornPlugins
Oldest known version of this page was edited on 2007-09-11 19:27:28 by GusMueller []
Page view:
Acorn Plugin Documentation
How plugins are loaded:
Additions to CIImage:
Additions to NSDocument: