Wednesday, June 06, 2007

Animation 1: Moving stuff around

Animation 1: Moving stuff around

There are two basic kinds of animation techniques that UJML allows. The first, which I will cover in this lesson, is sliding/moving. The other kind is strip animation (like animated gifs).

Sliding or moving an image on the screen is very simple in UJML. It relies on the <delay> tag to pause briefly between painting so that the shown image appears to move smoothly.

I usually create a boolean state-variable called sTick whose job it is to delay for a few milliseconds, then call a function called step() which calculates the next paint position. The step() function then clears and sets a state variable called sDisplay which paints the image at the updated position.

Naturally, you should use whatever naming scheme is most comfortable for you.

Here is a barebones implementation of a moving image. Note that the state variables exist only to display the image or to fire a timer event. The positioning code is contained in the step() function.

<state-variables>
   <state-var name="sDisplay" type="boolean"/>
   <state-var name="sTick" type="boolean"/>
</state-variables>
<variables>
   <var name="mImgX" type="int"/>
   <var name="mImgY" type="int"/>
</variables>
<functions>
   <function name="step" type="void">
      <script>
         sTick = false;
         // Calculate the next position to display the image
         mImgX = mImgX + 10;
         mImgY = mImgY + 10;
         if (_gt(mImgX, mScrWidth))
            mImgX = 0;
         if (_gt(mImgY, mScrHeight))
            mImgY = 0;

         _clear_state(sDisplay);
         sDisplay = true;
         sTick = true;
      </script>
   </function>
</functions>
<states>
   <state var="sDisplay">
      <transition value="true">
         <display>
            <image>
               <url>&IMGURL;</url>
               <x><eval>mImgX</eval></x>
               <y><eval>mImgY</eval></y>
               <width>&IMGW;</width>
               <height>&IMGH;</height>
            </image>
         </display>
      </transition>
   </state>
   <state var="sTick">
      <transition value="true">
         <delay>33</delay>
         <script>
            step();
         </script>
      </transition>
   </state>
</states>


A common twist on this is to determine the "slide distance" and the "slide duration" of the movement, then use the timer to move some percentage of the way towards the end point of the slide. You will see this commonly in menus where a button press will cause the sliding menu to be shown and clicking an item in the menu will cause the menu to slide off the screen (or to a docking position).

In order to do this, you must remember the time you started the movement in order to determine what percentage of "slide distance" you need to move.

<variables>
   <var name="mSlideStart" type="int"/>
</variables>
<functions>
   <function name="startSlide" type="void">
      <script>
         mSlideStart = _msec(); // save the starting time
         step();
      </script>
   </function>
   <function name="step" type="void">
      <variables>
         <var name="timedelta" type="int"/>
      </variables>
      <script>
         sTick = false;
         _clear_state(sDisplay);

         timedelta = mSlideStart - _msec();
         if (_gte(timedelta, &SLIDETIME;))
         {
            // The slide has completed
            mImgX = &IMGPOSX;;
            mImgY = &IMGPOSY;;
            sDisplay = true;
         }
         else
         {
            // The slide is only partially through
            // Get the fractional amount to move
            mImgX = &IMGPOSX; * timedelta / &SLIDETIME;;
            mImgY = &IMGPOSY; * timedelta / &SLIDETIME;;
            sDisplay = true;
            sTick = true; // do another tick until &SLIDETIME is reached
         }
      </script>
   </function>
</functions>


In this example, the program now has a function called startSlide() which is used to begin the sliding process. While the elapsed time is less than the total sliding time, the step() function calculates the distance to move based on the elapsed time and the total distance to move. If the elapsed time has not reached the total time, the sTick timer is set to fire another event later. Once the elapsed time has passed the expected total time, the image is placed at its final position and displayed. The timer is not set again (until the user calls startSlide() again).

Other improvements can be made to this sliding technique. Using a logarithmic sliding distance is a clever way to simulate accelerating objects. Likewise, a callback function signalling the "slide end" can be created to allow the sliding item a way to notify the user that it has completed its slide. Inverting the sign of the slide distance can be used to reverse a slide (very useful for hiding a menu).

In all, this is a very simple technique based solely on painting, moving, and delaying. All animation in UJML is based on this technique.

Thursday, May 31, 2007

Mea Culpa: _run is not _link

I mentioned in Lesson 7 that the _run() API is essentially identical to the _link() API. That is incorrect.

When an application is _run(), it pushes the current application down the application stack and disables it. The _run() application is then loaded and executed.

When an application is _link(), it becomes part of the currently running application.

The difference between these two is that all functions of the previous application are disabled when a subprogram is _run(). A _link()ed partition is loaded into memory as part of the current application, so all features of the current application are still enabled.

The _replace() API falls into the same category as _run() in that it disables the currently running application. The difference is that when the _run() application completes, the "pushed" application is re-activated (from initialization, not from where it left off). A _replace()ed application is pushed out of the application stack forever.

Sorry for the bad information.

Adjustable User Interface

Once you start working with UJML and targetting various devices, one thing becomes abundantly clear: Screen sizes are never the same. The screen size may be VGA (640x480), but most likely you won't be able to use the entire screen. What matters to you, the application developer, is not the total screen size, but the "usable screen size". This is the screen area that can be updated by the program.

In order to determine the screen size, UJML provides the API _getIntProperty(). This API takes an integer parameter defined in the DTD file and returns the appropriate information from the system. The two parameters that concern screen size are _PROPERTY_INT_SCREEN_WIDTH and _PROPERTY_INT_SCREEN_HEIGHT. By passing these parameters to _getIntProperty, we can retrieve the width and height of the usable screen area.

This code is boilerplate for the vast majority of applications:

mScrWidth = _getIntProperty( &_PROPERTY_INT_SCREEN_WIDTH; );
mScrHeight = _getIntProperty( &_PROPERTY_INT_SCREEN_HEIGHT; );

From this information, positioning objects on the screen is simply a matter of calculating offsets from the top, bottom, left, and right. If you wish to place an object flush to the right-hand side of the screen, you set its <x> parameter to be mScrWidth - objectwidth. Likewise, placing an object relative to the bottom of the screen means setting its <y> parameter to be the object's height subtracted from mScrHeight.

Knowing this simple concept, it is possible to draw anything, anywhere on the screen (or even off the screen!) However, UJML has some pitfalls which are easily worked around, yet frustrating if you don't realize the problem.

One of the first applications of screen positioning is the use of percentage offsets. Say you want to fill a certain area of the screen with _COLOR_RED. What you may find is that the area you are trying to paint never appears. The problem is a result of UJML's lack of floating point numbers. You can't say "mScrWidth * 0.42" and expect to get 42% of the screen width. UJML only provides integer arithmetic, so in order to get 42% of the screen width, you must first multiply the screen width by 42, then divide it by 100.

mPosX = mScrWidth * 42 / 100; // OK
mPosX = mScrWidth / 100 * 42; // NG: this will lose signficant digits

Keep in mind that integer arithmetic truncates, so don't divide before multiplying!

Another issue that crops up a lot is overlapping percentages. Since integer arithmetic truncates fractional values, sometimes your calculated areas will overlap each other by a pixel. In most cases, this is not a big deal, but for those of us who don't want our applications looking like they were developed by a sysadmin, it makes sense to be aware of this problem.

A decent solution is to use offsets based on the values returned by the percentage calculations. While this may have the side effect of moving the pixel problem off to the edge of the screen, those are pixels that not many people notice anyway. Better to have a row or column of black pixels on the edge of the screen than to have uneven display in the middle.

To implement this, just keep track of where you are positioning items. Then, instead of basing the position of the next item on the x,y origin, base it on the offset from the item immediately adjacent to it.

mPosX = 0; // this is the first object, based on the x,y origin
mPosW = mScrWidth * 42 / 100;
mPosX2 = mPosX + mPosW; // This is the second object, dynamically positioning itself relative to the first object

In a nutshell, that's it. Positioning items on the screen is relatively easy, and UJML provides excellent drawing capabilities for the application developer. Since we can't depend on the screen size of our devices to always be the same, it is important that our applications adapt to the screen size we are given.

Tuesday, March 06, 2007

Lesson 7: Loading and Unloading applications

UJML applications can be thought of as residing on a stack. The earliest launched application lives at the lowest stack position and the most recently launched application lives at the top of the stack. This lesson will discuss the methods for launching applications.

A UJML application is the code between the or tags in a file with a .ujml extension. The compiler looks for *.ujml to determine the application source files, so every application must conform to those requirements.

Practically, there is no difference between code contained in an tag and code contained in a tag. Conceptually, an
is a standalone application that is _run() while a is a smaller part of a larger application that is _link()ed to the parent application. In practice, there is no difference except in name. As a rule of thumb, I use in my startup application file while I use in all other files.

There are three ways to launch an application from within another application. The first is the easiest, but affords the least control over the startup parameters. To launch another application, call _run(appURL). Use the URL to your application as the parameter to this API. When this is called, the launched application takes the top position in the stack and also takes the topmost position in the Z-order.

Applications that are launched with _run() control their own lifetime. They can exit and return control to the owning application by calling _unloadSelf().

The second type of application activation is the _link() API. This has two advantages over _run(). First, it provides a way to give a name to the application. This is useful because it means that the launching application can _unlink() the partition explicitly. In the
_run() case, the launching application must wait for the _run() application to _unloadSelf() itself. The other benefit is that _link() allows the launching application to set the Z-order of the _link()ed partition. Depending on how the whole application is designed, it may be useful to load certain partitions higher or lower in the Z-order. A pop-up screen (like a notification) would need a very high Z-order while a resource loader could use a lower Z-order. Leaving off the Z-order value in the call will cause the application to be loaded above the launching application.

A
_link()ed partition may call _unloadSelf() to remove itself from the application stack, but the more typical method is by using the _unlink() API. The string parameter passed to _unlink() is the name that was passed as the first parameter to _link().

Be careful with the naming, though. If the same partition name is used for than once, the first
_link()ed partition will be automatically _unlink()ed to make room for the next partition.

The third type of application launch is _replace(). This is a relatively minor API compared to
_link() or _run(). It has most of the same characteristics of _run(), but instead of loading the application at the next open stack position, it implicitly _unlink()s the current application and _link()s the new one at that position. I have not found this API to be of any use, personally.

Although the UJML documentation says that the launching application is de-activated, it is actually suppressed in the Z-order. If an event comes in and the topmost application does not handle it, the event will trickle down the application stack until a handler is found or it reaches the bottom of the stack. Be sure that no unwanted event handlers are active when launching an application.

By effectively using the application stack, it is possible to write multi-featured applications in a small space since you can
_link() and _unlink() necessary components on the fly.

Wednesday, February 28, 2007

Lesson 6: State machines

At this point we've covered the basics of the UJML language. You know how to display images, capture user events, set up and execute states, and write functions. Putting this all together, we can create <state-machines>.

A state machine is a collection of state variables, variables, functions, and states that can be used to modularize UJML code. Every state machine has a name which is used as a prefix to the functions and variables of the state machine.

You can create a state machine inline in your UJML code or you can separate it out into another file and include the file in your UJML code. Either way, the state machine code is copied into the UJML code at compile time.

Here is an example of a separately written state machine module. The filename extension is .ujms which indicates that it is a UJML state machine definition.

hello.ujms

<ujml>
   <partition>
      <state-machines>
         <state-machine name="HelloWorld">
            <state-variables>
               <state-var name="sShow" type="boolean"/>
            </state-variables>
            <variables>
               <var name="mName" type="string"/>
            </variables>
            <functions>
               <function name="setName" type="void" visibility="public">
                  <parameters>
                     <var name="aName" type="string"/>
                  </parameters>
                  <script>
                     mName = aName;
                  </script>
               </function>
               <function name="show" type="void" visibility="public">
                  <script>
                     _clear_state(sShow);
                     sShow = true;
                  </script>
               </function>
            </functions>
            <states>
               <state var="sShow">
                  <transition value="true">
                     <display>
                        <label>
                           <text><eval>_strcat("Hello, ", mName, "!")</eval></text>
                        </label>
                     </display>
                  </transition>
               </state>
            </states>
         </state-machine>
      </state-machines>
   </partition>
</ujml>

To use this state machine, you first need to include it into your application.

<ujml>
<application>
    <state-machines>
       <include file="hello.ujms" state-machine="HelloWorld" />
    </state-machines>
    ...
</application>
</ujml>


Now, you can call the state machine functions from any script block.

<ujml>
<application>
    ...
    <script>
       HelloWorld.setName("Lauren");
       HelloWorld.show();
    </script>
    ...
</application>
</ujml>


By separating out this code, you make your main application code simpler and easier to follow. Since the state machine code is encapsulated in another file, you can keep logically separate code isolated.

It is important to be aware of Z-order when using state machines. An application may include the <state-machine> block at either the top of the partition or at the bottom or both. If the state machine is included at the top of the partition, then it will display with a lower Z-order (underneath) the display of the partition. Alternatively, if the state machine is included at the bottom of the partition, it will display with a higher Z-order than the partition's display. This is a common error to make. The clues are that your state machine variables are correct in the debugger but nothing is displayed on the screen. It is likely that your state machine has a lower Z-order than it needs to display correctly.

Another important point is that state machines are not objects. There is no concept of a state machine 'object', so you can't create multiple instances of a state machine. State machines are merely collections of functions, variables, and states that encapsulate some functionality for your application.

Wednesday, November 08, 2006

Lesson 5: Functions

Lesson 5: Functions

Functions are sections of code that can be executed by a script. If you are familiar with programming, then this needs no introduction, but if you are brand new to programming, you may want to familiarize yourself with the concept here.

Generally, functions have a name, return value, parameter list, and executable code. In addition, functions have a property called scope and another property called visibility.

You declare functions in a child-leaf of the <functions> tag. The following is an example of a very simple function.

<functions>
   <function name="SetName" type="boolean">
      <parameters>
         <var name="name" type="string" />
      </parameters>
      <variables>
         <var name="ret" type="boolean" />
      </variables>
      <script>
         mName = name;

         ret = true;
      </script>
      <return><eval>ret</eval></return>
   </function>
</functions>

In this example, a function called "SetName" is defined. It returns a boolean value to the caller. The caller passes in a string variable called "name", and the function defines a local boolean variable called "ret". When called, the script is executed (the value of name is assigned to the global variable mName and true is assigned to the local variable ret). The function returns the value contained inside of ret.

If you are familiar with C++, the following is approximately equivalent code:

bool SetName(string name)
{
   bool ret;

   mName = name;

   ret = true;

   return ret;
}

To call a function from code, type the function name, append appropriate parameters, and if desirable, assign the return value to a variable. The following is an example of some code calling SetName.

<variables>
   <var name="mName" type="string" />
   <var name="mIsSet" type="string" />
</variables>
<script>
   mIsSet = SetName("Lauren");
</script>

This snippet shows the script calling SetName with the string "Lauren". It catches the return value and stores it in a global variable called "mIsSet".

Functions may also call other functions. However, they may not call themselves. A function that calls itself is called a recursive function. UJML does not permit functions to be recursive.

That's the gist of it. You use functions to execute code. By splitting your program up into a logical set of functions and giving each function a good name, your code will be cleaner, easier to read, and have a better architecture than if you tried to build the program out of a single block of executable script code.

Friday, October 20, 2006

Lesson 4c: Resources and Display control

Lesson 4c: Resources and Display control

What we've discovered so far is that it is very easy to draw things on the screen and straightforward to update the screen using state transitions. However there lies a very subtle problem that affects the display on actual devices.
The problem is that visual elements are shown as soon as they are loaded. This does not sound like a problem, and on devices with fast filesystems, network connections, and graphics cards it isn't. The problem occurs when you attempt to run the code on a slower device with lots of network overhead or a slow graphics chip. Since the display only shows items as they are loaded, a page may not render fully because it is waiting for the requested images to arrive over the network.

Users may find this acceptable for some applications like web browsing or news browsing when the primary user interaction is reading text, but once the focus falls on displaying images, it becomes very difficult to provide a uniform, pleasant user experience if images are not displayed in a reasonable manner.

The most reasonable manner for most applications is to display all the images at once. This means that the program will load all the images before displaying them.

To manage resources, UJML provides the resource tag. Resources are defined by a URL, and they have the ability to give status notification via the event tag. Resources are also peculiar because they are only definable within state transitions. So by using a state variable it is possible to directly affect when a resource is loaded, and by effectively handling the load events it is possible to control the program flow.

When the state transition is active, the resources defined in it are loaded. When the state transition becomes inactive, the loaded resources are unloaded and any pending network requests are cancelled.

This lends itself to two straightforward applications. The first is very useful for applications that use a lot of images that provide the program's "look and feel". Putting all the images that will exist for the life of the application in a single state transition and setting it at the outset of the program will guarantee that those images will be immediately available any time they are needed. The second is to force all displayable items to be drawn simultaneously by not drawing the screen until all items have been loaded.

To create a "permanent resource partition", as I like to call it, all you need to do is define a new partition with a boolean state variable which is set to true in the script section of the partition definition. To complete the partition, a state transition is defined for the variable that contains all the permanent application resources.

<ujml>
   <partition>
      <state-variables>
         <state-var name="sLoadResources" type="boolean" />
      </state-variables>
      <script>
         sLoadResources = true;
      </script>
      <states>
         <state var="sLoadResources">
            <transition value="true">
               <resources>
                  <resource>
                     <url>http://example.com/a.jpg</url>
                  </resource>
                  <resource>
                     <url>http://example.com/b.jpg</url>
                  </resource>
               </resources>
            </transition>
         </state>
      </states>
   </partition>
</ujml>


In the above example code, two image resources are loaded when this partition is linked to the main application. The script is run immediately and sLoadResources is activated. Since sLoadResources is never set to false, the resources in the partition are available for the entire lifetime of the application, even from other partitions which may be loaded later.

That is the most straightforward usage of resources, however to gain the full benefit of the management technique, it is necessary to use the event tag to catch resource events.

There are two resource events. onResourceAvailable for successful loading, and onResourceError when an error occurred in the loading of the resource. These two events provide you with the tools necessary to regulate program flow.

The second technique which I mentioned above makes heavy use of resource events. The key is to tie each resource event to a counter which will signal when the program should proceed with processing.

<ujml>
   <partition>
      <state-variables>
         <state-var name="sLoad" type="boolean" />
         <state-var name="sDraw" type="boolean" />
      </state-variables>
      <variables>
         <var name="mLoadCnt" type="int" />
         <var name="mToLoad" type="int" />
      </variables>
      <functions>
         <function name="AllResourcesLoaded" type="void">
            <script>
               // All resources have been loaded, so paint the screen
               sDraw = true;
            </script>
         </function>
      </functions>
      <script>
         mLoadCnt = 0; // No resources loaded yet
         mToLoad = 2; // We are expecting two resources
         sLoad = true; // Begin the resource loading routine
      </script>
      <states>
         <state var="sLoad">
            <transition value="true">
               <resources>
                  <resource>
                     <url>http://example.com/a.jpg</url>
                     <event name="onResourceAvailable">
                        <script>
                           mLoadCnt++;
                           if (_eq(mLoadCnt, mToLoad))
                           {
                              AllResourcesLoaded();
                           }
                        </script>
                     </event>
                     <event name="onResourceError">
                        <script>
                           mToLoad--;
                           if (_eq(mLoadCnt, mToLoad))
                           {
                              AllResourcesLoaded();
                           }
                        </script>
                     </event>
                  </resource>
                  <resource>
                     <url>http://example.com/b.jpg</url>
                     <event name="onResourceAvailable">
                        <script>
                           mLoadCnt++;
                           if (_eq(mLoadCnt, mToLoad))
                           {
                              AllResourcesLoaded();
                           }
                        </script>
                     </event>
                     <event name="onResourceError">
                        <script>
                           mToLoad--;
                           if (_eq(mLoadCnt, mToLoad))
                           {
                              AllResourcesLoaded();
                           }
                        </script>
                     </event>
                  </resource>
               </resources>
            </transition>
         </state>
         <state var="sDraw">
            <display>
               <image>
                  <url>http://example.com/a.jpg</url>
                  <x>0</x>
                  <y>0</y>
                  <width>100</width>
                  <height>100</height>
               </image>
               <image>
                  <url>http://example.com/b.jpg</url>
                  <x>100</x>
                  <y>0</y>
                  <width>100</width>
                  <height>100</height>
               </image>
            </display>
         </state>
      </states>
   </partition>
</ujml>


Briefly, when the partition is loaded, it immediately begins loading the resources by setting the sLoad state variable to true. When each resource fires its success/error event, the corresponding script checks to see if all resources have been loaded, and if they have been, it sets sDraw to true to paint the two pictures side by side.

This technique can be extended to as many resources as you want, given the device's memory constraints. Also, if a function is provided that sets sLoad to false, the resources can be unloaded as well. It is even possible to create an array of boolean state variables to provide fine-grained loading and unloading of resources.

One key item to remember, though, is that as long as a resource is in use (by either the resource tag or a display tag) the resource is kept in memory. So in order to force a.jpg and b.jpg out of memory in the example above, it is necessary to set both sLoad and sDraw to false so that no state transition using the resource is active.

Resource do not necessarily have to be images, too. Sound files, even other UJBC files may be loaded using the resource tag.

The resource tag is the most important tool UJML provides for managing memory and providing users with a solid user experience. There are other even more fine-grained tools for resource management like _prefetch and _discard, but most of the heavy lifting will typically be handled using the resource tag.

Monday, August 28, 2006

Lesson 4b: State variables and transitions

In the previous sublesson, I mentioned state variables and that they may be used to display visual elements. This is a simplification of their purpose, but in regards to displays, state variables are the only way to update the display.

I find that thinking of applications as a series of screens helps me understand the concept behind state variables. On mobile phones, this is very obvious. You press the menu button to show the menu (a screen), you select an item from the menu and it loads a different part of the application (another screen). Any of the menu items may lead to any number of other screens. One screen, in other words, may have many different screen transitions.

In a typical programming language, you'd set up an object's member variables (color=red, size=10, etc) and then call a method which then performs some processing based upon the updated object state. A state is defined in this situation by its defining characteristics (variables) and its behavior is defined by the results of the execution (method). To change state, the program must explicitly call the state transition with the correct variables. If the input parameters are incorrect, the program may behave in an undefined manner.

UJML introduces the concept of state variables. They are different from normal variables because they have special knowledge about their internal values. When a state variable's value changes, it reacts by executing a script defined for that particular value. This leads to two fundamental properties of state variables:

1) State variables may be any type except for reference data types.
2) State variable execution scripts can be called implicitly by the UIE Player.

The second property is the more interesting of the two. By simply changing the value of a state variable, the specified script is executed.

State variables are declared as follows:

<ujml>
   <application>
      <state-variables>
         <state-var name="sPaintScreen" type="boolean" />
      </state-variables>
   </application>
</ujml>

The state variable is scoped to the entire application block, so it may be accessed anywhere from within the block. It is also possible to define state variables that have more restricted scope, but I'll try to cover that later when I discuss state machines.

When a state variable is updated, it transitions to a new state. This is called a state transition. A state transition may contain a display routine, audio routine, script routine, or a resource definition. It may also use a variable declaration to provide any necessary local variables to the script.

This is an example of a simple state transition that displays an image.

<state var="sPaintScreen">
   <transition value="true">
      <display>
         <image>
            <url>http://photos1.blogger.com/img/158/8299/320/050923_003L1.jpg</url>
            <x>0</x>
            <y>0</x>
            <width>240</width>
            <height>320</height>
         </image>
      </display>
   </transition>
</state>

This state transition will display the specified image on the screen when the 'sPaintScreen' state variable is set to "true". When 'sPaintScreen' is set to "false", anything specified in the "true" transition will be deleted. In short, "true" shows the image, and "false" hides the image.

Now, to paint the image to the screen, the application's script just sets the sPaintScreen state variable to true.

<ujml>
   <application>
      <state-variables>
         <state-var name="sPaintScreen" type="boolean" />
      </state-variables>
      <script>
         // Paint the image
         sPaintScreen = true;
      </script>
      <states>
         <state var="sPaintScreen">
            <transition value="true">
               <display>
                  <image>
                     <url>http://photos1.blogger.com/img/158/8299/320/050923_003L1.jpg</url>
                     <x>0</x>
                     <y>0</y>
                     <width>240</width>
                     <height>320</height>
                  </image>
               </display>
            </transition>
         </state>
      </states>
   </application>
</ujml>

The code above does essentially the same thing as the code in the previous lesson. The difference is that this version separates the painting of the image from the application display. When a visual element is included directly in the application's display, it remains on the screen at the lowest Z-order. By moving the visual element into a state transition display, it can be shown and erased from the display programmatically.

We previously used function key accelerators to handle user interactions. If we use the same technique here, we can update the display in response to user key presses.

<fn>
   <text>Update Display</text>
   <event name="onselect">
      <accelerators>
         <key>F1</key>
      </accelerators>
      <script>
         // flip flop the boolean value
         sPaintScreen = !sPaintScreen;
      </script>
   </event>
</fn>

This key handler will either show or erase the image on the screen when the user presses the F1 key. The program we have been working on is now interactive!

<ujml>
   <application>
      <state-variables>
         <state-var name="sPaintScreen" type="boolean" />
      </state-variables>
      <script>
         // Paint the image
         sPaintScreen = true;
      </script>
      <display>
         <fn>
            <text>Update Display</text>
            <event name="onselect">
               <accelerators>
                  <key>F1</key>
               </accelerators>
               <script>
                  // flip flop the boolean value
                  sPaintScreen = !sPaintScreen;
               </script>
            </event>
         </fn>
      </display>
      <states>
         <state var="sPaintScreen">
            <transition value="true">
               <display>
                  <image>
                     <url>http://photos1.blogger.com/img/158/8299/320/050923_003L1.jpg</url>
                     <x>0</x>
                     <y>0</y>
                     <width>240</width>
                     <height>320</height>
                  </image>
               </display>
            </transition>
         </state>
      </states>
   </application>
</ujml>

Briefly, the above code declares a state variable called 'sPaintScreen'. The sPaintScreen variable is set to 'true' which puts the sPaintScreen=true state transition into the queue. The display is updated with the F1 key bound to the 'onselect' event. The pending state transition is executed and the image is shown on the screen. When the user presses the F1 key, sPaintScreen is set to 'false' which then erases any visual elements specified in 'true'. Since there is no explicit 'false' transition, no special handling is performed. If the user presses the F1 key again, sPaintScreen is set to 'true' which puts the image back on the screen.

Try the code and play with it for a little while. Investigate adding an event handler into the sPaintScreen=true state transition. Doing so will allow you to change the text of the F1 key accelerator.

Next time I will cover using the resources tag to manage the handling of images.