How to draw your own patches in the Composition Editor

smokris's picture

example of draw-your-own patches in Composition EditorWe can override the patch drawing method, using the infamous poseAsClass technique.

  1. Start with a new project, using at least v0.3 of the Xcode Template
  2. Create a new class (right-click on the project icon, click "Add" and then "New File...". Select "Objective-C class". Name it something like "MyPatchActor" (where "MyPatch" is the name of your patch).
  3. Paste the following into the .h file:
    #import <QCPatchActor.h>
     
    @interface MyPatchActor : QCPatchActor
    - (void)drawNode:(QCPatch *)node bounds:(struct _NSRect)rect view:(QCPatchView *)view;
    @end
  4. Paste the following into the .m file:
    #import "MyPatchActor.h"
    #import "MyPatch.h"
     
    @implementation MyPatchActor
    - (void)drawNode:(QCPatch *)node bounds:(struct _NSRect)rect view:(QCPatchView *)view
    {
       [super drawNode:node bounds:rect view:view];
     
       if( [node isMemberOfClass:[MyPatch class]] )
       {
          // do your own Quartz drawing here
       }
    }
    @end
    and modify as desired.
  5. Add the poseAsClass call to MyPatchPrincipal.h, so it ends up looking like this:
    #import "MyPrincipal.h"
    #import "MyPatchActor.h"
    #import "MyPatch.h"
     
    @implementation MyPatchPlugin
    + (void)registerNodesWithManager:(GFNodeManager*)manager
    {
       [MyPatchActor poseAsClass:[QCPatchActor class]];
     
       [manager registerNodeWithClass:[MyPatch class]];
    }
    @end
  6. Enjoy.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

cwright's picture
poseAs isn't free

Careful with excessive use of this method. poseAs essentially inserts your class into the message chain, making it a bit longer with each new class. While it's only a class compare, having hundreds of patches successively poseAs QCPatchActor might increase load noticeably. Some scalability testing might be in order :).

smokris's picture
yes, but negligible, i think.

Yes. I'm guessing the typical user won't have more than a couple dozen custom patches installed (few of which will use the poseAsClass trick)... and a few hundred additional "if" statements / objective c messages per second probably won't be noticeable.

cwright's picture
clean form

Discovered a poseAs-free way to do this, using one of QCPatch's methods, -(QCPatchActor)nodeActorForView:(QCPatchView)view

Just return a MyPatchActor instance from this method, and it works the same way.

Each patch should declare a global patch actor in their .h file, and instantiate only one patch actor (each patch thus shares its actor with identical patches).

example method:

- (id)nodeActorForView:(id)fp8
{
        if(actor == nil)
        {
                actor = [testPatchActor new];
        }
        return actor;
}