PuppetMaster Guide - Writing JavaScript Actions

 

 

Please note that there will be changes and additions to the JavaScript interface as PuppetMaster is developed.

1       Introduction

 

This is a guide for writing JavaScript actions with PuppetMaster. PuppetMaster is available at http://www.lim.com.au/PuppetMaster

 

One of the ways of customizing PuppetMaster is using JavaScript.

 

This is not a tutorial on JavaScript – there are plenty of other tutorials on the internet that will teach syntax and features. This is just a guide on how to use JavaScript to provide fine control of PuppetMaster

 

 

2       Non-Interactive scripts

 

Let’s start with an example.

 

iTunesApp = new ActiveXObject("iTunes.Application");

iTunesApp.Play();

 

The script above will cause iTunes to launch and to play.. To use it, go to Preferences -> Menus -> Add Item

Select JavaScript, give it a name, (eg. “Play”) and paste the script into it. Click OK.

 

The action will be added to your Available items. To show it on your phone, drag it across to the left pane. It’ll appear immediately on your phone if you’re already connected.

 

Try it out! Make sure you have iTunes installed. Then click on “Play”. You should find that iTunes launches and plays as expected.

 

This demonstrates how simple non-interactive scripts can be created.

 

 

3       Hello World Script

 

Create a new Java Script action called “Hello World”. Paste the following script in

 

etActivate = 1;

if(ExecuteData.type == 1)

{

  RemoteController.ShowDialog("Hello World");

}

 

When you use this script on your phone, it’ll show “Hello World”. Pressing OK or Back buttons will return you to the parent menu.

 

When PuppetMaster calls the JavaScript, it provides two objects – ExecuteData and RemoteController. ExecuteData provides information on why the script is called.

 

When a script is first selected from a menu, it is sent an etActivate event. If the script does not tell the RemoteController to display anything, then the script is finished with. However, if the script does display something on the RemoteController, then PuppetMaster assigns the script an ‘active’ state and it will be called in the future.

 

RemoteController provides methods to interact with the device. Here, we are simply displaying the text “Hello World”

 

 

4       Key Handling

 

PuppetMaster will call the script with ExecuteData.Type set to etKeyPress when the user presses a button. Try the following script

 

etActivate = 1; etKeyPress = 4;

switch(ExecuteData.Type)

{

case etActivate:

RemoteController.ShowDialog("Press a key");

 break;

 

case etKeyPress:

RemoteController.ShowDialog("You pressed " + ExecuteData.KeyID);

 break;

}

 

If you look at how this script works, you’ll notice that the actual key pressed is provided by part of ExecuteData

 

 

5       Persistent Data

 

Sometimes you’d like the script to know ‘what happened before.’ The RemoteController object has a “Store” property that you can set to any value (or array of values) that will be preserved across calls. Try the following example

 

etActivate = 1; etKeyPress = 4;

switch(ExecuteData.Type)

{

case etActivate:

RemoteController.ShowDialog("Press a key");

 RemoteController.Store = 0;

 break;

 

case etKeyPress:

 RemoteController.Store = RemoteController.Store + 1;

RemoteController.ShowDialog(RemoteController.Store + ": You pressed " + ExecuteData.KeyID);

 break;

}

 

The Store is initialised to zero in the etActivate section, and is incremented every time a key is pressed. You should see this in the text output on your phone.

 

Before continuing with example scripts, it’s worth knowing about the different execute types…

 

6       Execute Types

 

The actual numeric values for the execute types can be found in the Object Reference

6.1     etActivate

 

etActivate is sent when the script is first clicked on in a menu. If the script does NOT use one of the RemoteController.Show* methods, then no further messages will be sent to the script, and the menu remains active. To be interactive, the script must handle the etActivate message.

 

6.2     etBegin, etEnd

 

etBegin is sent when the script first becomes active. etEnd is sent when the script becomes inactive. To make the script become active, it must use a RemoteController.Show* method in response to an etActivate

 

6.3     etKeyPress, etKeyRelease, etIntegerInput, etTextInput

 

etKeyPress and etKeyRelease are messages sent to the script when keys are pressed and released. The ExecuteData.KeyID property can be used to determine which key was pressed/released.

 

etIntegerInput and etTextInput are messages sent when a value has been entered by the user. Menus send 0-based integer values representing which index was selected.

 

6.4     etNext, etBack

 

etNext and etBack are special cases of user input since they are often dealt with in a very different way on the phones. They generally correspond to “OK” and “Back” keys. etNext and etBack require that you call a RemoteController.Show* if you wish your script to remain active. Not handling etNext/etBack will cause PuppetMaster to display the parent menu.

 

6.5     etTimer

 

The etTimer message is sent periodically to your script to allow updating of the phone based on time. Timers are set using RemoteController.StartTimer(Milliseconds) and stopped using RemoteController.StopTimer()

 

7       Timer Example

 

To get PuppetMaster to call your script periodically, you need to use the RemoteController.StartTimer method. You will also need to tell it to stop triggering periodic events when you exit. The following example uses JavaScript’s inbuilt Date function.

 

etActivate = 1, etBegin = 2, etEnd = 3, etTimer = 8;

switch(ExecuteData.Type)

{

case etActivate:

case etTimer:

 RemoteController.ShowDialog(new Date());

 break;

case etBegin:

 RemoteController.StartTimer(1000);

 break;

 

case etEnd:

 RemoteController.StopTimer();

 break;

}

 

RemoteController.StartTimer takes a parameter in milliseconds that represents the time between each etTimer message. Running the above example should cause the system time to be displayed on your mobile phone.

 

8       MultiState scripts

 

The following example gives an idea of how scripts with multiple states can be created. Understanding how it works is left as an exercise to the reader.

 

etActivate = 1; etIntegerInput = 6; etNext = 7; etBack = 9;

stMenu = 0; stDialog = 1; stPercentInput = 2;

 

function ShowMenu()

{

 RemoteController.Store[0] = stMenu;

 RemoteController.ShowMenu("MultiState Example", new Array("Show Dialog", "Show Percent Input"));

}

 

function HandlePercentInput()

{

 switch(ExecuteData.Type)

 {

 case etBack:

 case etNext:

  ShowMenu();

  break;

 

 case etIntegerInput:

  RemoteController.Store[1] = ExecuteData.Input;

  break;

 }

}

 

function HandleDialog()

{

 switch(ExecuteData.Type)

 {

 case etBack:

 case etNext:

   ShowMenu();

   break;

 }

}

 

function HandleMenu()

{

 if(ExecuteData.Type == etIntegerInput)

 {

  switch(ExecuteData.Input)

  {

  case 0:

    RemoteController.ShowDialog("Current Percent " + RemoteController.Store[1]);

    RemoteController.Store[0] = stDialog;

    break;

 

  case 1:

    RemoteController.ShowPercentInput("Enter Percent", RemoteController.Store[1]);

    RemoteController.Store[0] = stPercentInput;

    break;

  }

 }

}

 

if(ExecuteData.Type == etActivate)

{

 RemoteController.Store = new Array(2);

 RemoteController.Store[0] = stMenu;

 RemoteController.Store[1] = 50 // Just give percent some starting value

 ShowMenu();

}

 

switch(RemoteController.Store[0])

{

case stMenu:

 HandleMenu();

 break;

case stDialog:

 HandleDialog();

 break;

case stPercentInput:

 HandlePercentInput();

 break;

}

 

 

9       Object Reference

 

9.1     ExecuteData object

 

The ExecuteData object provides information on why the script is being run.

 

9.1.1      Properties

Name

Notes

Type

This provides the type. The following are currently defined:

 etActivate = 1

 etBegin = 2

 etEnd = 3

 etKeyPress = 4

 etKeyRelease = 5

 etIntegerInput = 6

 etBack = 7

 etTimer = 8

 etNext = 9

 etTextInput = 10

These are discussed in the Execute Types section

KeyID

String value that represents the key pressed.

 “<” – Left Arrow

 “>” – Right Arrow

 “^” – Up Arrow

 “v” – Down Arrow

 “0” – “9”, “#, “*” – Keypad

 “u”, “d” - + and – buttons on Sony Ericsson phones

 “f” – Menu Button

 “c” – Clear button (Not available on all phones)

Input

Integer value for menus, percent input

String value for text input

 

9.2     RemoteController object

 

The RemoteController object provides access to remote control device.

 

9.2.1    Properties

Name

Notes

CanShowImage

This returns true or false depending on if the device is capable of displaying images.

Store

This value is used to store data across multiple script executions. See Persistent Data section.

ImageWidth

This is the image display width of the device

ImageHeight

This is the image display height of the device

 

9.2.2    Methods

Name

Notes

ShowDialog(Text);

Displays Text on the device

ShowImage ImageFileName, ImageFileType, TimeBeforeHighQuality

ImageFileName must be a full path to a supported image file type.

TimeBeforeHighQuality controls active degradation of the image. If another image has been displayed within the last TimeBeforeHighQuality (in milliseconds), then the image will be converted to a lower quality to improve interactivity if required. To always display a high quality image, specify 0.

Showing an image that is of different dimensions to ImageWidth and ImageHeight will cause it to be resized to fit before display.

Supported file types are currently: BMP, JPG, PCX, TGA

ShowMenu(Title, MenuArray);

MenuArray is an array of strings. Sends input via etIntegerInput which is zero-based

ShowPercentInput(Title, StartingPercent);

Shows a percent input on the phone. etIntegerInput messages will be generated for every change in value.

ShowProgress(Text);

Shows a progress dialog.

ShowSortedMenu(Title, MenuArray);

Same as ShowMenu, but will sort the names before display.

ShowText(Title, Text);

Shows Text on the device. If the text is too long to fit in one screen, the user can scroll it using Up/Down arrows

ShowTextInput(Title, InitialText);

Allows the user to input text. Most phones support T9 input for this.

Store

This value is used to store data across multiple script executions. See Persistent Data section.

 

 

10  Modes

 

Mode Type

Events related to the mode

Dialog

etKeyPress, etKeyRelease

Text

etKeyPress, etKeyRelease

Percent Input

etIntegerInput

Progress

etKeyPress, etKeyRelease

Menu

etIntegerInput

Text Input

etTextInput

Image

etKeyPress, etKeyRelease

 

 

Comments, corrections, questions? Email me: jeff@lim.com.au