Skip to main content
Inspiring
January 20, 2010
Answered

Parameter groups and Debug to Release

  • January 20, 2010
  • 3 replies
  • 9992 views

Hello,

I have created a plugin and I am facing two issues right now. Firstly, my UI is a bit cluttered. I read all the SDK but couldn't find enough information on how to create Parameter Groups.  Secondly, can anyone tell me how to convert the plugin from Debug to Release in Xcode and on Windows? Also everytime I change the Outflags, AE throws an error saying that theere is a mismatch with PiPL. How is that PiPL number calculated? Is that just a hex number?

Thank you very much in advance.

This topic has been closed for replies.
Correct answer shachar carmi

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.
:-)

3 replies

Inspiring
December 13, 2010

Hi gutsblow,

I understand you know how to implement a dialog on the Mac platform of the AE CS5 SDK? I am a newbie with OSX programming and I simply want to port my Windows plugin which implements a dialog when the user clicks the Options button. I was wondering if you wouldn't mind posting a description on how to do this or point me in the right direction.

Thanks!

gutsblowAuthor
Inspiring
December 13, 2010

Hey,

To have a Modal Window Dialog for options button, the best way is to create a window using Interface builder. But its not the easiest way, since you have to deal with Obj-C. But, if you want something basic, like string input and 1-2 text fields, you can use the CFUserNotification API, which is C-Based.

To use CFUserNotification API have a look at


http://developer.apple.com/mac/library/documentation/CoreFoundation/Reference/CFUserNotificationRef/Reference/reference.html

(Apple's Documentation)

http://developer.apple.com/mac/library/samplecode/X11CallCarbonAndCocoa/Introduction/Intro.html#//apple_ref/doc/uid/DTS10000729

Now, if you are willing to fiddle around with Obj-C/Interface Builder, here are the details in the video I created a while ago.

http://vimeo.com/17206258

Hope that helps.

Inspiring
December 13, 2010

Thanks so much, I will take a look. It's good to know there are those willing to share!

Participating Frequently
February 24, 2010

you are crazy guys.... as qutsblow wrote, you should write a book or some articles, there are so much information. I am just abusing this post, but i had to say that, its really informative.

thanks

Inspiring
January 20, 2010

Use PF_ADD_TOPIC and PF_END_TOPIC

I have a parameter group set up like this...

in my .h file...

enum

{

LUMINANCE_DISK_ID = 1

,TOPIC_FEEDBACK_ID

,SHOW_HISTOGRAM_DISK_ID

,HIST_CORNER_ID

,HIST_SIZE_ID

,END_TOPIC_FEEDBACK_ID

,My_NUM_PARAMS

};

and in my .cpp file...

//

// ---------- Histogram group

//

AEFX_CLR_STRUCT(def);

PF_ADD_TOPIC(

"Histogram Overlay", TOPIC_FEEDBACK_ID);

AEFX_CLR_STRUCT(def);

def.flags = PF_ParamFlag_CANNOT_TIME_VARY;

PF_ADD_CHECKBOX(STR(StrID_ShowHist_Name), STR(StrID_ShowHist_Description), FALSE, 0, SHOW_HISTOGRAM_DISK_ID);

AEFX_CLR_STRUCT(def);

def.flags = PF_ParamFlag_SUPERVISE;

PF_ADD_POINT(

"Histogram location", HIST_LOCATION_X, HIST_LOCATION_Y, RESTRICT_BOUNDS, HIST_CORNER_ID);

AEFX_CLR_STRUCT(def);

def.flags = PF_ParamFlag_SUPERVISE;

PF_ADD_PERCENT(

"Histogram width", HIST_PCT_DFLT, HIST_SIZE_ID);

//PF_ADD_FIXED("Histogram width", HIST_SIZE_MIN, HIST_SIZE_MAX, HIST_SIZE_MIN, HIST_SIZE_MAX, HIST_SIZE_DFLT, 0,0,0, HIST_SIZE_ID);

AEFX_CLR_STRUCT(def);

PF_END_TOPIC(END_TOPIC_FEEDBACK_ID);

Regarding the Debug/Release question:

In XCODE I just duplicated the Debug configuration and named it Release. Then I removed the preprocessor macro that defined "_DEBUG" in my debug verison. I also checked "Strip debug symbols during copy". There may be other changes to make the release version smaller.

Regarding the PiPL mismatch. I just change the PiPL setting to match what AE says in the error, but it is possible to figure it out.

-Mike

gutsblowAuthor
Inspiring
January 20, 2010

Thanks for the info. Also, is there a way to compile them in universal

architecture instead of choosing either i386 or ppc?

Thank you!

Community Expert
January 21, 2010

i doubt this would make an improvement on your quality of life,

but here's some info regarding the resource version.

the resource version is actually calculated using a macro defined in the SDK.

you can see it in the global setup function of your plug-in:

out_data->my_version = PF_VERSION( MAJOR_VERSION,

MINOR_VERSION,

BUG_VERSION,

STAGE_VERSION,

BUILD_VERSION);

it uses bit shifting to calculate the value.

however, translated to human it reads:

RESOURCE_VERSION =

MAJOR_VERSION * 524288 +

MINOR_VERSION * 32768 +

BUG_VERSION * 2048 +

STAGE_VERSION * 512 +

BUILD_VERSION

i tried to force this calculation as an enum, to make the resource version update automatically,
and it worked on visual studio, but failed on xcode...
alas, on visual studio, if you hover over  the enum of the RESOURCE_VERSION it will tell you it's value, and you can copy it to the resource file, without manually calculating it.
and don't forget that on windows you have to delete the .rc file or the build will not generate a new one even if changes were made in the resource file.
:-)