Hello Shachar,
Here comes the usual annoying questions about 'serialization'/ 'string
input'. Excuse me if they sound stupid.
So I found a command to add "Options" dialog in top of the window, but how
do I implement a window using native os api calls? I built an interface
using Interface Builder and I want to display it there. I wish there was
atleast one sample in the sdk, addressing this.
Now, how do i store the 'string' input in the plugin permanently? is it the
weird .rsrc file? Not that I want to serialize my basic plugins, but good
to know how.
Hope you don't mind! Thank you very much.
once upon a time, there was an API call ADM (adobe dialog manager).
it allowed plug-in programmers to create windows with various controls, including text boxes.
i don't know why, but that is no longer supported.
anyways,
since you mentioned using interface builder, i'm guessing we're talking mac.
i must tell you my friend, you've hit the spot with this question.
there are many small problems in this process that have left me frustrated for days on end.
so now you have a .nib file and you wonder, "now what?"
first, open the .nib file in interface builder.
set the window's class type to "movable modal".
this will ensure the window being in front of AE, and prevent interactions with AE until the window is released.
the second step would be to add the .nib file to the xcode project.
obviously, you add the file like any other file, and it appears in the project.
you should see that it also appears on the last folder on the project, called "NIB Files".
we're not done adding.
now twirl down the "targets" category, and twirl down your plug-in's name.
you can now see the build stages.
now add a new build stage, "copy bundle resources", and add the .nib file into it as well.
now compile your plug-in, and go to the generated file.
open the package and check that the nib file is indeed there.
included successfully?
we're still adding stuff.
now add two objects of "existing frameworks" type.
"IOKit.framework" and "CoreFoundation.framework"
we move on.
go to the "mac" folder inside the project folder and locate a file called "YourPlugName.plugin-info.plist".
open it with property list editor.
we're interested mostly in the CFBundleIdentifier string.
it's most probably "com.adobe.AfterEffects.YourPlugName"
you can keep it like that, or change it to whatever you want.
just make sure it's unique, so no other bundle in the world would use the same name.
copy that name. we'll need it for later.
and this is how it's all implemented:
//some declarations
CFBundleRef bundleRef = NULL;
IBNibRef theNibRef = NULL;
OSStatus theErr = NULL;
const EventTypeSpec kEvents[] = { { kEventClassCommand, kEventCommandProcess } };
WindowRef ActivationWindow = NULL;
// Create a nib reference
bundleRef = CFBundleGetBundleWithIdentifier( CFSTR("replace this text with the bindle name from earlier"));
theErr = CreateNibReferenceWithCFBundle( bundleRef, CFSTR("replace this text with the .nib file name, without the .nib extension"), &theNibRef );
//an optioanl check for errors.
//you should put this after almost every step.
//it's up to you.
//require_noerr( theErr, CantGetNibRef );
// Create a window.
//it's still not visible at this stage.
theErr = CreateWindowFromNib( theNibRef, CFSTR( "Window" ), &ActivationWindow );
// We don't need the nib reference anymore.
DisposeNibReference( theNibRef );
// making sure the window will show somewhere on screen.
RepositionWindow( ActivationWindow, NULL, kWindowCascadeOnMainScreen );
// The window was created hidden so show it.
ShowWindow( ActivationWindow );
// Install event handlers
theErr = InstallWindowEventHandler( ActivationWindow, EventHandlerFunction,
GetEventTypeCount( kEvents ), kEvents, (void*)ActivationWindow, NULL );
// Call the event loop
RunApplicationEventLoop();
this is it. you're now stuck in the event loop, until you terminate it.
here's the basic code for event handling:
#define OkCommand 'ok '
#define CancelCommand 'not!'
OSStatus ActivationFormEventHandler(
EventHandlerCallRef inHandlerCallRef,
EventRef inEvent,
void *inData )
{
OSStatus theErr = eventNotHandledErr;
HICommand theHICommand;
WindowRef theWindow = ( WindowRef ) inData;
GetEventParameter(
inEvent, kEventParamDirectObject, typeHICommand, NULL,
sizeof( HICommand ), NULL, &theHICommand );
switch ( theHICommand.commandID )
{
case OkCommand:
//do whatever you want to do when the user presses "ok"
//terminating the window, and releasing the process back to the effect.
DisposeWindow( theWindow );
QuitApplicationEventLoop();
break;
case CancelCommand:
//and the same for when the user clicks "cancel"
QuitApplicationEventLoop();
theErr = noErr;
break;
}
return theErr;
}
that's it.
this should get you up and running.
:-)