Live preview - the Gobe Productive way

Here is a description by Scott Lindsey of how Gobe Productive implements live preview with LibImageManip.

The add-on advertises support with:


  ioCapability->AddInt32("preview_invoker", B_POINTER_TYPE);

as well as


  ioCapability->AddInt32("cancel_queue", B_POINTER_TYPE);

It uses it by calling


  BInvoker* preview;

  ioExtension->FindPointer("preview_invoker", (void**) &preview);

Then, simply invoke the preview invoker (from the config view code) to tell the application to update its preview based on the settings. To implement a checkbox which turns preview on and off, I added a boolean:


  BMessage msg(mPreviewInvoker->Message());

  msg.AddBool("preview", prefs.preview);

  mPreviewInvoker->Invoke(&msg);

This allows the add-on to tell the application that preview has been turned off, and that the image should be refreshed back to its unmodified bits. Gobe Productive will check its message queue for multiple preview messages, only using the most recent. This allows sliders to work fairly reasonably, not queuing up thousands of previews.

I also added some more structure to the progress mechanism:


  ioCapability->AddInt32("cancel_queue", B_POINTER_TYPE);

and


  BMessageQueue* CancelQueue;

  ioExtension->FindPointer("cancel_queue", (void**) &CancelQueue);

Then, on a regular basis (such as when you call the progress invoker),


  if (CancelQueue && NULL != CancelQueue->FindMessage(B_CANCEL, 0))

  {

    CancelQueue->RemoveMessage(CancelQueue->FindMessage(B_CANCEL, 0));

    // Handle cancelation

  }

checks to see if the app has asked the plugin to abort, at which point it should clean up and return B_CANCELED.

Note that supporting preview without supporting the cancel queue means that you can get stuck waiting for a preview with the configuration dialog still up, and the cancel button doing nothing.