October 20, 2010

Flex based widgets

Have you ever used Adobe Captivate widgets? Widgets can enhance the type of content you can create with Adobe Captivate. You can leverage the complete capabilities of Adobe Flash via widgets. Once created, widgets can be used any number of times just like any other Captivate object. This really helps in creating engaging rapid elearning content. Captivate ships with a number of useful widgets. Captivate widgets are basically swf files which follow certain rules. One rule being (the blog is about this rule), the widget swf should register certain callbacks via External Interface. These callbacks should be made in the first frame of the swf.

Most of the widgets created for Captivate are Adobe Flash based widgets. Creating widgets using Adobe Flex/Flash builder is a little tricky. But once you get to know that, creating really powerful widgets takes no time. With Flex, you can leverage the vast set of inbuilt components which are powered by Flex framework to create rich and engaging Captivate widgets.

If you had ever tried creating a Captivate widget in Flex, I guess most of you wouldn’t have succeeded. You might have tried adding the External Interface callbacks either in applicationComplete or creationComplete handlers of the Application class in Flex. This method doesn’t work because Flex creates the Application in its second frame, where as Captivate expects the callbacks to be added in the first frame.

So, here we are providing a hassle free way to create Flex based widgets for Captivate. Follow these four simple steps and you can create your Flex based Captivate widgets in no time.

Step 1: Include the two ActionScript files provided below, in your Flex project.

Step 2: In your main mxml file, Change the mxml application start tag from

<s:Application  to  <cp_widget:CPWidgetApplicationBase xmlns:cp_widget="*"

And the end tag from

</s:Application>  to  </cp_widget:CPWidgetApplicationBase>

Step 3: Open CPWidgetSystemManagerBase.as and set the properties marked in TO BE SET BY WIDGET DEVELOPER section, according to your requirement.

  • mWaitForSnapshot:
    • Set this to true, if you are overriding IsReadyForSnapShot function in your main application, else keep it false
  • mWidgetType :
    • To create a static widget, set mWidgetType to 0
    • To create an interactive widget, set mWidgetType to 1
    • To create a question widget, set mWidgetType to 2
  • m_EditModeWidth:
    • If you want a specific Edit Mode width, set this parameter, else set it to -1
  • m_EditModeHeight
    • If you want a specific Edit Mode height, set this parameter, else set it to -1

Step 4: Override the widget specific methods provided in CPWidgetApplicationBase.as file in your main mxml file. For example, if you are trying to create a static widget, add these methods in your main mxml file and build the logic.

  • override public function getInspectorParameters():Object
  • override public function setInspectorParameters(inParam:Object):void
  • override public function setParameters(inParam:Object):void
  • override public function cpSetValue(inVariable:String, inValue):void
  • override public function IsReadyForSnapShot():Boolean

Overriding all the functions is not a must. Choose which functionality you want in your widget and proceed accordingly.

That’s it!! It’s not difficult at all.

Optionally, if you want to mute further calls from Captivate, which might be required when you do state changes in Flex, call setCanDelegateCall(false) in your application class. When you want to unmute, call setCanDelegateCall(true).

If you are using mx:application, then you need to do these changes in CPWidgetApplicationBase.as: Uncomment, Import mx.core.Application; and comment out import spark.components.Application;

In case you are having issues with getting the flex widget to work, you need to merge the Flex framework into the swf. To do so, Goto Project > Properties > Flex Build Path > Library Path > Select the Flex SDK and choose ‘Merged into Code’ as the linkage type.

Provided below are sample flex based widgets for Adobe Captivate 5 created in Flex along with the source.

MyFlexWidget is a static widget, which displays whatever is entered into it in widget properties.

MyInteractiveWidget is an interactive widget; you can select which button is the correct one among the given two, and that one will act as the correct answer

MyQuestionWidget is a question widget; which has similar functionality as that of the interactive widget.

Try them for yourself!

Flex & Widgets

Update: To compile the samples, you need to update the class path.To update the path, Goto Project > Properties > Flex Build Path > Source Path > Edit.

Just update the path to the following.
[Adobe Captivate Installation Directory]\ActionScript\export\as3

[Adobe Captivate Installation Directory] is the directory where captivate is installed. Typically it will be C:\Program Files\Adobe\Adobe Captivate 5

Posted by Ravi Kishore12:16 PM
  • Brian Duck

    Upon further review: I extracted the ZIP files and imported them to the Flash Builder workspace and EACH project generates two errors!

    Someone linked to a file on their D drive:
    “unable to open ‘D:\RoboDemo\hulk\dev\extras\xplat\mul\[INSTALLDIR]\ActionScript\export\as3′ “

    When can we get an updated ZIP file?

    • http://www.facebook.com/dave.feasey Dave Feasey

      Brian Duck,

      You need to edit the source path in your project to point to the Captivate as3 folder as described in the article above.

      Project->Properties->Flex Build Path ->Source path tab

    • http://www.facebook.com/dave.feasey Dave Feasey

      … unfortunately, using this library in Captivate 6 causes a nasty runtime error in the onEnterFrame function:

      TypeError: Error
      #1034: Type Coercion failed: cannot convert
      mx.managers.systemClasses::ChildManager@728b041 to mx.core.IUIComponent.

      at
      mx.managers::SystemManager/get application()

      at
      CPWidgetSystemManagerBase/onEnterFrame()

  • Ravi Kishore

    Hi Brian,
    Please see the update section in the post.
    Hope this helps.

  • Pingback: Flex learner | Blog | Flex based widgets « The Adobe Captivate Blog

  • Pingback: insert html files inline in adobe captivate courses using widgets – a start « The Adobe Captivate Blog

  • Todd Kuehnl

    Just getting familiar with this. How would one retrieve the current frame number utilizing this flex framework?

    • Todd Kuehnl

      Scratch that. Slide number not frame number. What is the proper way to subscribe to the CPSlideEnterEvent basically?

      • Ravi Kishore

        Hi Todd,

        You need to do this in cpSetValue in your main mxml file. I’m writing the function for you.

        override public function cpSetValue(inVariable:String, inValue):void
        {
        if(inVariable == 'movieHandle')
        {
        var movieHandle:CPMovieHandle = inValue as CPMovieHandle;
        if(movieHandle)
        {
        var movieProps:CPMovieProperties = movieHandle.getMovieProps();
        if(movieProps)
        {
        var eventHandle:IEventDispatcher = movieProps.eventDispatcher;
        if(eventHandle)
        {
        eventHandle.addEventListener(CPSlideEnterEvent.CPSLIDEENTEREVENT, slideEnterCallBack);
        }
        }
        }
        }
        }

  • Mark

    Thanks Ravi,
    Also, this is not the question of Widget in Flex, if you can answer.

    I have a captivate Movie in Flex, I am facing a problem while loading that movie and going to a particular slide. Looks like I have a timer issue, Flex loads the movie and ties to goes to slide, but Captivate has not loaded yet.
    Is there a way, I can register for captivate movie loaded event in Flex App..

    Thanks again for all the help

    • Ravi Kishore

      Hi Mark,

      There is no such event.

      Captivate has optimized its placement of slides in such a way that the experience is smooth if you continue from the beginning of the swf.

      I assume you are loading captivate swf in a Flex swf. I can suggest a workaround for you. To know whether a slide is loaded or not, all you have to do is divide captivate main time line’s currentFrame by 2. So, if you want to jump to say 30th slide, check if captivateSwf.currentFrame/2 == 30 (Here captivateSwf is the handle to loaded captivate swf.)

      Hope this helps,
      Ravi.

  • TD

    Hi Ravi,

    How do I upload widgets to make them available to others?
    I tried the Exchange, but there has been no feedback for a week now.

    Any ideas?

    Thanks
    TD

    • Ravi Kishore

      Sorry to say, The review process might take some time.

  • http://www.keylogger-mac.com Keylogger Mac

    what TD is asking is what I also wanna know. Can you give us your reply?

  • http://www.adobe.com Suresh Jayaraman

    Folks , I approve your widgets . The turn around time is between 2 -4 weeks but if you want to get things up earlier send me an email – sjayaram@adobe.com

    Sr.QE Manager – Captivate

    Ps: keylogger – I don’t see any widget in your name?

  • Timothy Beiten

    Hi Ravi,

    is this method still workable when using captivate 5.5 and Flex 4.5.1.
    The compiled widgets work perfectly but when i try to compile them myself, they dont load up. Captivate isn’t showing the invalid widget message, so i guess they are valid. Only problem is the widget properties panel stays blank when added to the captivate project.

    Could you please send some suggestions to timothy.beiten@gmail.com

    Kind regards,

    Timothy

  • Mac Liems

    Is this blog still active?
    I’ve tried out the sample Question Widget fla, but althought the widget shows up in Captivate, it stays totally blank.
    Having changed the library path, I at first got an error: can’t find the libs. Then I created an empty libs folder in the project, after which the fla compiles, but shows absolutely nothing.

    What am I doing wrong here?

  • Jarda Pavlicek

    I tried Captivate 6.0 and Flash Builder 4.6 with Flex SDK 4.6 without success. Widget displays it’s configuration parameters but don’t work when placed on slide.
    I changed Flex SDK to 3.6A and changed all spark objects to mx. And it works.

  • Loading
  • Categories

  • Archives

  • Authors

  • Recent Comments

    • mizan.ngbd2013: this verion is very helfull
    • Yarik: Perfect! Thanks for sharing source file, so I can discover and learn. I love Cp7 and Pn9 for everyday working....
    • Sandy Snyder: Cool! I look forward to trying something like this in one of my projects. Thanks for sharing!
    • Allen Partridge: I like that approach Lieve.
    • Lieve Weymeis: Since shared actions can be used also in other projects, and this action not necessary has to be...
  • Captivate & eLearning Videos

    Subscribe to Adobe eLearning on YouTube.

    Check out the latest eLearning Videos on AdobeTV

Recently Approved