Posts in Category "C++"

Using EVE for UI layout

The Adobe Express View Engine (EVE) is the recommended method of laying out UI widgets in InDesign dialogs. The main benefit of using EVE is that widget geometry is calculated for you, so that when you add or remove widgets to a dialog all of the other widgets are shifted automatically without you having to recalculate sizes etc.

Benefits of using EVE

  • Updating dialogs by adding and removing widgets is made easier because the layout of all widgets is adjusted for you.
  • Where text is different sizes on different operating systems you don’t have to worry about calculating extra whitespace.
  • English dialogs can be smaller because you don’t need to leave room for anticipated localised text, so your dialogs look good in all languages.
  • EVE automatically resizes text, buttons, checkboxes, radio buttons and drop-down lists so you needn’t worry about text being clipped.

A quick introduction to EVE

In order to use EVE widgets in your dialog definitions you’ll need to add an include to your FR file.

#include "EveInfo.fh"

This file is a very useful resource since it lists all of the EVE widgets which are available out of the box, so do have a look inside.

In order to have your dialog use EVE you’ll need to add WidgetEveInfo to its type definition.


type BscDlgDialogBoss(kViewRsrcType) : DialogBoss(ClassID = kBscDlgDialogBoss)
{
   WidgetEveInfo;
};

Finally you can change your dialog definition to use EVE by changing it to use EVE widgets and by adding the necessary EVE layout constants to the dialog itself (since you’ve now made the dialog an EVE dialog by adding WidgetEveInfo to its type definition).

Since all dialogs have an OK and Cancel button and some other content, here’s a complete dialog definition that uses EVE to layout an OK and Cancel button.


resource BscDlgDialogBoss (kSDKDefDialogResourceID + index_enUS)
{
   __FILE__, __LINE__,
   kBscDlgDialogWidgetID, // WidgetID
   kPMRsrcID_None, // RsrcID
   kBindNone, // Binding
   Frame(0,0,388,112) // Frame (l,t,r,b)
   kTrue, kTrue, // Visible, Enabled
   kBscDlgDialogTitleKey, // Dialog name
   {
      // Add dialog content here (like EVEStaticTextWidget..)

      EVEGenericPanelWidget
      (
         kInvalidWidgetID, // WidgetId
         0 // RsrcId
         0,
         kBindNone, // Frame binding
         Frame(0,0,0,0) // Frame is 0 for auto-sizing
         kTrue, // Visible
         kTrue, // Enabled
         kEVEAlignLeft | kEVELargeSpaceAfter | kEVEArrangeChildrenInColumn,
         {
            EVEDefaultButtonWidget
            (
               kOKButtonWidgetID, // WidgetID
               kSysButtonPMRsrcId, // RsrcID
               kBindNone, // Binding
               Frame(0,0,0,0) // Frame (l,t,r,b)
               kTrue, kTrue, // Visible, Enabled
               kSDKDefOKButtonApplicationKey, // Button text

               kEVELargeSpaceAfter,
            ),
            EVECancelButtonWidget
            (
               kCancelButton_WidgetID, // WidgetID
               kSysButtonPMRsrcId, // RsrcID
               kBindNone, // Binding
               Frame(0,0,0,0) // Frame (l,t,r,b)
               kTrue, kTrue, // Visible, Enabled
               kSDKDefCancelButtonApplicationKey, // Button name
               kTrue, // Change to Reset on option-click.
               
               kEVELargeSpaceAfter,
            ),
         } // End of EVE Generic panel child widgets
      ), // End of EVE Generic panel widget definition

   },
   
   kEVEArrangeChildrenInRow | kEVESmallMargin,
};

If you are familiar with InDesign plug-in development you’ll notice that the general format of the dialog definition is the same as usual except for some EVE layout additions and the use of widget names prefixed with EVE.

How do I convert my existing dialogs to use EVE?

The InDesign plug-in SDK includes an EVEConverter tool which enables you to very quickly EVE-ize your dialog definitions however it’s output is less than optimal. Be aware that the tool will also convert any panel definitions to use EVE so you should keep a backup copy of your original FR file so that you can replace the EVE-ized panel definition with your original non-EVE panel definition. The EVEConverter tool is a great first step to get a feel for EVE and how to use it.

Once you are better acquainted with EVE it becomes easier to hand craft your conversions or do some of them by hand. It all depends on how complex your dialogs are and if you are using any custom widgets. As a rule of thumb you might use the EVE converter first, then go over the output by hand to remove any excess spacer widgets or superfluous generic panel definitions.

The plug-in SDK also includes a porting guide which includes a chapter on using EVE. You can obtain the plug-in SDK from here http://www.adobe.com/devnet/indesign/sdk.html.

Running a script from an InDesign plug-in

Perhaps you’ve come to native plug-in development from a more script-based background, or perhaps you have some existing script code you want to reuse in a new plug-in project. Whatever your background, it’s really handy to be able to run a script from a native plug-in, and it’s also surprisingly easy.

The code below works out of the box so you can copy and paste as much as you please.

#include "IScriptManager.h"
#include "IScriptEngine.h"
#include "IScriptRunner.h"
#include "IScriptUtils.h"
#include "JavaScriptID.h"

InterfacePtr<IScriptManager> scriptManager(Utils<IScriptUtils>()->QueryScriptManager(kJavaScriptMgrBoss));
if (!scriptManager)
{
   return;
}

InterfacePtr<IScriptEngine> scriptEngine(scriptManager->QueryDefaultEngine());
if (!scriptEngine)
{
   return;
}

InterfacePtr<IScriptRunner> scriptRunner(scriptEngine, UseDefaultIID());
if (!scriptRunner)
{
   return;
}

RunScriptParams params(scriptRunner);
scriptRunner->RunScript("alert('hello, world!');", params);

The above code uses JavaScript but you may use any script manager you like, including kAppleScriptMgrBoss for AppleScript and kOLEAutomationMgrBoss for Visual Basic. For a complete list of available scripting managers see ‘Script managers’ in chapter 10 ‘Scriptable Plug-in Fundamentals’ of the Programming Guide Volume 1 included in the plug-in SDK (available at http://www.adobe.com/devnet/indesign/sdk.html).

Flash UIs with InDesign CS4

InDesign user-interface development can be expensive. It takes a lot of effort to implement a dialog or panel in ODFRC. Things should improve in future versions, with the possibility of using Flash-based user-interface tools like Flex and FlexBuilder. While this represents the future direction of InDesign user-interface development, there is a present reality in InDesign CS4. With an understanding of the current situation, you can implement Flash-based user-interfaces for InDesign CS4.

Continue reading…

InDesign Flash Export with C++

InDesign CS4 adds the ability to export pages to Flash (SWF and XFL files).

The following is a 10 page InDesign CS4 document exported to SWF (Flash). 

You can turn the pages by clicking the text “Next”.  This text was converted to a button in InDesign.  After the first page you will also see a “Previous” button.

More interesting, you can use drag and drop to turn the pages as if you’re turning the pages of of a book or a magazine.  To turn the pages using drag and drop do the following: 

  1. Hover the mouse cursor over the top right corner of the blue rectangle and drag it to the left.  You should see the page curl.
  2. Click and drag to the left.
  3. Release the mouse button when the page appears close to having turned.

If you need to export SWF from a plug-in, take a look at the ExportDynamicDocument code snippet in the InDesign CS4 Products SDK.  The above SWF was exported using that code snippet.

Note: We added a few enhancements (XFL export, and output file selection) in the 6.0.1 update.

The source file lives in the following location in the InDesign CS4 Products SDK.

  SDK/source/sdksamples/codesnippets/SnpExportDynamicDocument.cpp

The code snippet does the following in C++.

  1. Creates a 10 page document.
    • The pages dimensions are small to create the desired SWF size.
    • At 100% scale this is 72 pixels per inch
  2. Creates two text frames on the master pages and converts them both to buttons.
  3. Adds appropriate events (back and next) to these two buttons.
  4. Exports to SWF or XFL.

This last step demonstrates processing the kSWFExportCommandBoss and kXFLExportCommandBoss commands.

It’s more likely you would use scripting to build and export SWFs.  I anticipate adding an equivalent scripting sample in the near future.