greetings, sign in or register

the litl hardware with channels

Meet our Controls

Table of Contents

Overview

The litl SDK package contains a number of reusable Actionscript 3 components you can use in your own channels, should you need to. These interactions have been designed for common use cases seen in many channels on the litl OS. They include a simple modal menu system, a very generic scrolling list, a slideshow, a video player, and a filmstrip, among others. This document will outline each of the controls currently available in the SDK package, describe where they might be useful, and provide examples for each.

The controls in controls directory of the SDK package are entirely optional. You do not need to use these controls in order to create cool channels.

Goals

We had a number of goals in mind when designing these components that we felt were important.

Lightweight and performant

In order for the components to perform well under limited resources, they need to be as conservative with memory usage as possible. They should also not perform intensive tasks or unnecessarily utilize the CPU.

Flex independent

In light of the previous goal, and to reduce complexity, the controls should be independent of the Flex framework. This allows developers to create channels without a dependency on the framework, and allows a lower average channel footprint.

Skinnable

The controls need to be skinnable to some degree, to allow sufficient flexibility over look-and-feel to the end developer.

litl specific

The litl OS has some common interactions that the control set can fulfill without requiring the developer to reinvent the wheel multiple times. The control set should focus on interactions that are likely to occur in litl channels over more general interactions that are covered by other more comprehensive component sets.

Interoperable

The controls should integrate well with other frameworks and development methods.

General Usage

Requirements

The controls are written in Actionscript 3. In order to use them you should have some familiarity with Actionscript 3 development and a valid development environment, such as Adobe® Flash® Builder™ or an alternative. The remainder of this documentation will assume this fact, and is not intended as a general guide to channel development (although we hope it helps a little).

Package location

The main control classes reside in the com.litl.control package. The main controls are named:

  • Filmstrip
  • Label
  • ModalMenu
  • Slideshow
  • TextButton
  • VerticalList
  • VideoPlayer

Using the library SWC

You can use the compiled library SWC, located in the ‘controls/bin’ directory of the package.

In Adobe® Flash® Builder™ you would include this SWC in your build path within the properties for your project.

Using the Actionscript source classes

An alternative to the library SWC is to add the source files to your classpath when building your project. Being able to see the source code may allow you a greater insight into how the controls work.

An important note on osmf.swc

If when using the control source with Adobe® Flash® Builder™, you may get compilation errors regarding OSMF. This is because a different version of OSMF is included by default with Adobe® Flash® Builder™ projects. The litl VideoPlayer control utilizes OSMF version FC1 at the time of writing. You can modify your build path to exclude the osmf.swc included with the Flex 4 framework. You can avoid this caveat altogether by using the compiled LitlControls.swc instead.

Additional Resources

In addition to this document, this package also contains asdoc documentation for the controls. This is located in ‘controls/asdoc’.

Modal Menu

Overview

The Modal Menu component is an overlay for your channel to provide a number of selectable options that the user must respond to in order to continue. The menu will block out the background while visible. The buttons can be highlighted with the mouse, or manually when using the litl wheel and go button.

Usage

Creation

You can create and add the ModalMenu class to the stage in the same way as any other DisplayObject subclass. It is important when adding the menu to the stage to place it above your other content.

package
{
	import com.litl.control.ModalMenu;

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
	public class ModalMenuSample extends Sprite
	{
		protected var menu:ModalMenu;
		
		public function ModalMenuSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		private function initialize():void {
			menu = new ModalMenu();
			addChild(menu);
		}
	}
}

Setting the menu options

You can set the number of menu items, and text for each button label, by setting the dataProvider property on the ModalMenu instance. The property accepts an Array of Strings to use as labels.

Continuing the sample code above, we can modify the initialize method to read:

private function initialize():void {
        menu = new ModalMenu();
        addChild(menu);
        
        menu.dataProvider = ["First option", "Second option", "Third option"];
}

Responding to menu selection

The menu will dispatch an Event.SELECT event when an item is clicked with the mouse. If you are using the menu with the LitlService GO_BUTTON_PRESSED event, you can simply look at the selectedIndex property of the menu to find out which item was highlighted when the button was pressed.

Continuing to modify the initialize method above:

private function initialize():void {
        menu = new ModalMenu();
        addChild(menu);
        
        menu.dataProvider = ["First option", "Second option", "Third option"];
        
        menu.addEventListener(Event.SELECT, onMenuSelect);
}

private function onMenuSelect(e:Event):void {
	var selectedIndex:int = menu.selectedIndex;
	trace(selectedIndex);
}

Once an item has been selected, you should remove the menu from the stage with:

removeChild(menu);

Using the menu with the wheel and go button

If you have already set up a LitlService, and connected to the device, you can control the menu with wheel and go button event handlers. A common use-case would be to show the menu when the go button is pressed, listen for the wheel to move the current selection up and down the menu, then select the highlighted item when the go button is pressed a second time.

Please see the documentation for the core SDK for more information regarding the wheel and go button events.

Appendix A provides a complete example of using the ModalMenu class with wheel and go button events from the LitlService.

TextButton

Overview

The text buttons used in the ModalMenu component are also available as a separate control, should you need them. The background is skinnable for each state via the StyleManager. The StyleManager and skinning will be introduced later in this document.

Slideshow

Overview

The Slideshow control provides a way to display information such as images or text in a continuously advancing presentation. You can control the speed that the items advance, either automatically or manually. You can also control the way the data is presented by creating your own item renderer class. By default, the slideshow will wait for the next item to finish loading before moving on, displaying a 'loading' spinner if it needs to wait.

Usage

Creation

The Slideshow is part of a set of controls that use the same core scrollable list code. These controls, such as Filmstrip and VerticalList all contain similar properties in order to display their content. You can think of the Slideshow as a horizontal list, where only one item is visible at one time.

They all make use of a dataProvider property, which is an Array of data to display. This data could be text, images, or a custom object containing other information.

They also make use of an itemRenderer property. This property allows you to specify a class to create for each item in the list. When the control creates the items it needs for the list, it will create one instance of the item renderer for each item that is visible. It will then pass the corresponding item in the data provider into the item renderer, which will then use that data to load an image, show some text, etc.

At the time of writing, the litl control set comes with two simple item renderers. One for text (TextItemRenderer), and one for images (ImageItemRenderer). The slideshow component uses the ImageItemRenderer by default.

Creating your own item renderer will be explained in more detail below.

To instantiate a Slideshow, you can use code similar to:

package
{
	import com.litl.control.Slideshow;
	import com.litl.control.listclasses.ImageItemRenderer;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
        public class SlideshowSample extends Sprite
	{
		protected var slideshow:Slideshow;

		public function SlideshowSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		private function initialize():void {
			var slideshow:Slideshow = new Slideshow();
			slideshow.itemRenderer = ImageItemRenderer;
			slideshow.delay = 4;
			slideshow.transitionSpeed = 1;
			slideshow.setSize(1280, 800);
			addChild(slideshow);

                	slideshow.dataProvider = ["one.png", "two.png", "three.png"];
			
		}
	}
}

Setting the item renderer

You can change the class used for rendering items by using the line of code:

slideshow.itemRenderer = ImageItemRenderer;

You would replace ImageItemRenderer with a reference to your class.

The item renderer class you use needs to implement the interface:

com.litl.control.listclasses.IItemRenderer

Most importantly, this interface makes sure your class has a data property, to pass the item data into.

Setting the slideshow delay

You can control the delay between transitions by changing the delay property of the slideshow. This value is in seconds, and does not include the time the slideshow takes to move between items.

slideshow.delay = 5;  // Set the delay to 5 seconds between transitions.

You can also disable automatic advancing of content, by setting the delay property to 0. You can then move the slideshow forward or back manually with the moveNext or movePrevious methods.

slideshow.moveNext();  // Advance to the next slide in the slideshow.
slideshow.movePrevious();  // Move back to the previous item in the slideshow.

Setting the slideshow transition speed

You can alter the time the slideshow takes to perform a transition by setting the transitionSpeed property. This value is in seconds.

slideshow.transitionSpeed = 1;  // Take one second to move to the next slide

Changing the size of the slideshow

You can alter the size of the slideshow using the setSize method, as with all controls in the litl controls package.

slideshow.setSize(1280, 800); // Make the slideshow fill the whole screen

By default, the ImageItemRenderer will scale and center images to match the size of the slideshow, up to a maximum of 150% of the original size.

Appendix A provides a complete example of using the Slideshow class.

Filmstrip

Overview

The Filmstrip control is similar to the Slideshow control, in that it shows a horizontal list of items. You can change the item renderer and set the data provider in the same way as the Slideshow.

The currently highlighted item is shown in the center of the list, and the items scroll left and right as you change the selectedIndex property. It is possible to change the filmstrip background by setting a backgroundSkin style with the StyleManager. Skinning and styles will be introduced later in the document.

Usage

Creation

You can create a Filmstrip control in the same way as the other controls. Don't forget to add the newly created Filmstrip to the stage, and size and position it to your liking.

package
{
	import com.litl.control.Filmstrip;
	import com.litl.control.listclasses.ImageItemRenderer;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
        public class FilmstripSample extends Sprite
	{
		protected var filmstrip:Filmstrip;

		public function FilmstripSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		private function initialize():void {
			filmstrip = new Filmstrip();
			filmstrip.itemRenderer = ImageItemRenderer;
			filmstrip.setSize(1280, 124);
			filmstrip.move(0, 676);
			filmstrip.setStyle("padding", 10);
			addChild(filmstrip);
			
			filmstrip.dataProvider = [ "one.png", "two.png", "three.png" ];
			
		}
	}
}

Setting the item renderer

You can change the class used for rendering items by using the line of code:

filmstrip.itemRenderer = ImageItemRenderer;

You would replace ImageItemRenderer with a reference to your class.

The item renderer class you use needs to implement the interface:

com.litl.control.listclasses.IItemRenderer

Most importantly, this interface makes sure your class has a data property, to pass the item data into.

Setting the current scroll position

Scrolling the filmstrip left and right manually is possible with the scrollPosition property. You can listen for wheel events in a similar way to the ModalMenu control in order to change the current scrollPosition. Alternatively, you can provide buttons in your interface to scroll left and right. The filmstrip does not provide scroll buttons for you in order to be as flexible as possible.

filmstrip.scrollPosition = 4;  // Set the current position to 4.
filmstrip.scrollPosition++;  // Scroll forward by one item.

Appendix A provides a more comprehensive example of using the filmstrip with the wheel and go button.

Vertical List

Overview

The vertical list control is almost identical to the Filmstrip control, except that the content is displayed vertically, and the content is not centered in the list. The VerticalList control also supplies clickable up and down buttons to scroll the list.

Listening for events on the VerticalList

The VerticalList control dispatches an Event.CHANGE event when the currently selected item has changed (for example, when a user clicks on an item).

list.addEventListener(Event.CHANGE, onListChange);

Video Player

Overview

The video player provides a simple way to play video or other media using a litl-themed control bar. The video player utilizes the Open Source Media Framework (OSMF) from Adobe, and can support the same media types (streaming flv, swf, audio, etc.). In addition to these types, the video player has additional code to handle YouTube URLs by wrapping the YouTube chromeless player.

The video player will automatically scale up or down the content to match the player's current size. The scaling method in use is 'letterbox', which means that the player will show all of the video it can while maintaining gaps on the top and bottom, or on the left and right, depending on the aspect ratio of the video, and the aspect ratio of the available space.

The default video control bar supports play/pause, scrubbing, and displaying the current buffer information.

Usage

Creation

In order to use the VideoPlayer control, you need to instantiate it, add it to the stage, position and size it. You can then pass in a url, or OSMF resource to play.

package
{
	import com.litl.control.VideoPlayer;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
        public class VideoSample extends Sprite
	{
		protected var player:VideoPlayer;

		public function VideoSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		private function initialize():void {
			player = new VideoPlayer();
			addChild(player);
			player.setSize(1280, 800);
			
			player.url = "http://dl.dropbox.com/u/2980264/OSMF/logo_animated.flv";
			player.autoPlay = true;
		}
	}
}

Setting the current media

You can pass in a remote url to the media to play. This can be a progressive download flv, mp3, or streaming source such as Adobe® Flash® Media Server, among others.

player.url = "http://path.to.your.media/";

If you are familiar with OSMF, you can also pass in a MediaResource with the resource property. The litl controls package includes a YouTubeResource class to allow you to load a YouTube video by ID. For more information, see the YouTubeResource asdocs.

player.resource = new YouTubeResource("qybUFnY7Y8w");

Playing or pausing media

Playing or pausing the current media playback is possible with the play() and pause() methods, respectively.

player.play(); // Start the media if it is not already playing.
player.pause(); // Pause the current media if it is playing.

Seeking to a point in the current media

The player has a seek method to seek to a certain point in the current media. The media must support seeking in order for this to work, and the destination time should be within the media duration.

player.seek(50) // Seek to 50 seconds into the current media.

Listening for media events

The video player will dispatch events when the current media has loaded and is ready to play, when the current media has finished playing, and when an error has occurred when loading or streaming the current media.

player.addEventListener(VideoPlayerEvent.READY, onVideoReady);
player.addEventListener(VideoPlayerEvent.COMPLETE, onVideoComplete);
player.addEventListener(ErrorEvent.ERROR, onVideoError);

Appendix A contains a more comprehensive VideoPlayer example.

Skinning and StyleManager

Overview

Each control in the litl controls package uses the com.litl.skin.StyleManager class to lookup certain style properties when they are created. StyleManager maintains a list of styles for each control type, and custom styles you can refer to by name.

Please note that this StyleManager is not related to the Flex StyleManager, and does not provide the same functionality.

You can however, include CSS with your project, and add it to StyleManager's styles in order to use them with the controls you create.

The litl controls come with a default skin, which consists of two Actionscript classes and a css file (com/litl/skin/defaultSkin.css). If you like, you can take a look at this css file for reference if you need to create your own skin, or modify the default. You can combine your own styles in addition to the default. Any styles added to the StyleManager override any previously added styles.

Adding a CSS file or String to the StyleManager

In order to add styles to the StyleManager, you can use CS declarations in the form of a string. You should do this before you instantiate any litl controls, usually when your application initializes.

The static method StyleManager.getInstance().addCSS() can be used to add CSS rules.

var myCSS:String = ".myCSSRule { paddingTop: 5; }";
StyleManager.getInstance().addCSS(myCSS);

You can also add styles from a file by embedding it in your SWF as a ByteArray, and calling StyleManager.getInstance().addEmbeddedStyleSheet()

package
{
	import flash.utils.ByteArray;
	
	[Embed(source="mySkin.css", mimeType="application/octet-stream")]
	public class MySkinCSS extends ByteArray
	{
	
	}
}

StyleManager.getInstance().addEmbeddedStyleSheet(MySkinCSS);

A sample mySkin.css file

/* CSS file */
/* This style will change the font color of all Label components */
Label
{
	color: 0xcccccc;
}

.mainButton
{
	fontFace: CorpoS;
	color: 0xffffff;
	size: 24;
}

.titleText
{
	fontFace: CorpoS;
	fontStyle: italic;
	color: 0xffffff;
	size: 24;
}

Applying styles to single instances

In the CSS example above, we defined a style for the class ".titleText".

We can apply this style to a single instance of a Label or TextButton by using the styleName property of all litl controls.

myLabel.styleName = ".titleText";

The label instance will then take on the styles defined in the css.

Applying single styles to an instance

In addition to the above methods, you can apply a single style to a control by using the setStyle method.

myLabel.setStyle("color", 0xff0000);

Style precedence

A control will use styles in a certain order of precedence. Styles added with setStyle will take top priority, followed by styles added with the styleName property, followed by styles defined for an entire class ("Label" for example).

Loading an external CSS file

One final way to use a CSS stylesheet in your application is to load it at runtime from an external URL. You can do this with the static StyleManager.getInstance().loadStyleSheet() method.

You will need to wait for a StyleSheetLoadEvent.COMPLETE event before continuing with your application initialization routine.

StyleManager.getInstance().addEventListener(StyleSheetLoadEvent.COMPLETE, onStyleSheetLoaded);

StyleManager.getInstance().loadStyleSheet("myStyles.css");

For more information on the StyleManager methods, please consult the asdocs.

Supported styles

Style properties that are supported vary between each control. The properties used by each control are listed in Appendix B.

Appendix A

ModalMenu example

package
{
	import com.litl.control.Label;
	import com.litl.control.ModalMenu;
	import com.litl.sdk.message.*;
	import com.litl.sdk.service.LitlService;
	import com.litl.sdk.util.Tween;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
	public class ModalMenuSample extends Sprite
	{
		
		protected var menuOpen:Boolean = false;
		protected var menu:ModalMenu;
		
		protected var helpLabel:Label;
		
		protected var service:LitlService;
		
		public function ModalMenuSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		protected function initialize():void {
			
			helpLabel = new Label();
			addChild(helpLabel);
			helpLabel.move(10, 10);
			helpLabel.width = 1280;
			
			helpLabel.text = "Connecting to simulator.. if nothing happens, please make sure the simulator is running.";
			
			service = new LitlService(this);
			service.connect("menu_sample", "Menu sample", "1.0", false);
			
			service.addEventListener(InitializeMessage.INITIALIZE, handleInitialize);
			service.addEventListener(WheelStatusMessage.WHEEL_STATUS, handleWheelStatus);
			service.addEventListener(UserInputMessage.WHEEL_NEXT_ITEM, handleWheelNext);
			service.addEventListener(UserInputMessage.WHEEL_PREVIOUS_ITEM, handleWheelPrevious);			
			
		}
		
		/**
		 * Fade the menu into view, if it isn't already.
		 */
		public function showMenu():void {
			Tween.tweenTo(menu, 0.4, { alpha: 1 });
			menuOpen = true;
			
			// Automatically select the middle item.
			menu.selectedIndex = menu.dataProvider ? Math.floor(menu.dataProvider.length / 2) : -1;
		}
		
		/**
		 * Fade the menu out of view, if it isn't already.
		 */
		public function hideMenu():void {
			trace("Selected menu item: " + menu.selectedIndex);
			
			Tween.tweenTo(menu, 0.4, { alpha: 0 });
			menuOpen = false;
		}
		
		/**
		 * Scroll the menu down one item.
		 */
		public function nextItem():void {
			menu.selectedIndex++;
		}
		
		/**
		 * Scroll the menu up one item.
		 */
		public function previousItem():void {
			menu.selectedIndex--;
		}
		
		/**
		 * Called when the device has sent all our saved properties, and is ready for us to begin.
		 * @param e	The InitializeMessage instance.
		 *
		 */
		private function handleInitialize(e:InitializeMessage):void {
			menu = new ModalMenu();
			addChild(menu);
			menu.alpha = 0;
			
			menu.dataProvider = [ "One", "Two", "Three" ];
			
			trace("*** In the simulator, switch to CHANNEL view, then press the go button to show the menu ***");
			helpLabel.text = "*** In the simulator, select this instance, switch to CHANNEL view, then press the go button to show the menu ***";
		}
		
		/**
		 * Called when the go button is pressed on the device.
		 * This event will usually be followed by an optional GO_BUTTON_HELD event, and then a GO_BUTTON_RELEASED event.
		 * @param e	The UserInputMessage instance.
		 *
		 */
		private function handleGoPressed(e:UserInputMessage):void {
			
			// When the go button is pressed, request to enable or disable the wheel.
			// This will result in a WheelStatusMessage, which we listen for
			// and call handleWheelStatus.
			
			if (service.wheelEnabled) {
				service.disableWheel();
			}
			else {
				service.enableWheel();
			}
		}
		
		/**
		 * Called when the wheel has been disabled or enabled. In our case, we will use this to show
		 * the menu.
		 * @param e	The WheelStatusMessage instance.
		 *
		 */
		private function handleWheelStatus(e:WheelStatusMessage):void {
			if (e.wheelEnabled)
				showMenu();
			else
				hideMenu();
		}
		
		private function handleWheelNext(e:UserInputMessage):void {
			if (menuOpen)
				nextItem();
		}
		
		private function handleWheelPrevious(e:UserInputMessage):void {
			if (menuOpen)
				previousItem();
		}
	}
}

Slideshow example

package
{
	import com.litl.control.Label;
	import com.litl.control.Slideshow;
	import com.litl.control.listclasses.ImageItemRenderer;
	import com.litl.sdk.message.*;
	import com.litl.sdk.service.LitlService;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
	public class SlideshowSample extends Sprite
	{
		protected var slideshow:Slideshow;
		
		protected var helpLabel:Label;
		
		protected var service:LitlService;
		
		public function SlideshowSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		protected function initialize():void {
			
			helpLabel = new Label();
			addChild(helpLabel);
			helpLabel.move(10, 10);
			helpLabel.width = 1280;
			
			helpLabel.text = "Connecting to simulator.. if nothing happens, please make sure the simulator is running.";
			
			service = new LitlService(this);
			service.connect("slideshow_sample", "Slideshow sample", "1.0", false);
			
			service.addEventListener(InitializeMessage.INITIALIZE, handleInitialize);
			service.addEventListener(UserInputMessage.MOVE_NEXT_ITEM, handleNextItem, false, 0, true);
			service.addEventListener(UserInputMessage.MOVE_PREVIOUS_ITEM, handlePreviousItem, false, 0, true);
		}
		
		/**
		 * Scroll the slideshow forward (right) one item.
		 */
		public function handleNextItem(e:UserInputMessage):void {
			slideshow.moveNext();
		}
		
		/**
		 * Scroll the slideshow backwards (left) one item.
		 */
		public function handlePreviousItem(e:Event = null):void {
			slideshow.movePrevious();
		}
		
		/**
		 * Called when the device has sent all our saved properties, and is ready for us to begin.
		 * @param e	The InitializeMessage instance.
		 *
		 */
		private function handleInitialize(e:InitializeMessage):void {
			var slideshow:Slideshow = new Slideshow();
			slideshow.itemRenderer = ImageItemRenderer;
			slideshow.delay = 4;
			slideshow.transitionSpeed = 1;
			slideshow.setSize(1280, 800);
			addChild(slideshow);
			
			slideshow.dataProvider = [ "one.png", "two.png", "three.png" ];
			
			helpLabel.text = "";
		}
	
	}
}

Filmstrip example

package
{
	import com.litl.control.Filmstrip;
	import com.litl.control.Label;
	import com.litl.control.listclasses.ImageItemRenderer;
	import com.litl.sdk.message.*;
	import com.litl.sdk.service.LitlService;
	import com.litl.sdk.util.Tween;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
	public class FilmstripSample extends Sprite
	{
		private static const FILMSTRIP_HIDDEN_Y:Number = 805;
		private static const FILMSTRIP_SHOWN_Y:Number = 676;
		
		protected var filmstripOpen:Boolean = false;
		protected var filmstrip:Filmstrip;
		
		protected var helpLabel:Label;
		
		protected var service:LitlService;
		
		public function FilmstripSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		protected function initialize():void {
			
			helpLabel = new Label();
			addChild(helpLabel);
			helpLabel.move(10, 10);
			helpLabel.width = 1280;
			
			helpLabel.text = "Connecting to simulator.. if nothing happens, please make sure the simulator is running.";
			
			service = new LitlService(this);
			service.connect("filmstrip_sample", "Filmstrip sample", "1.0", false);
			
			service.addEventListener(InitializeMessage.INITIALIZE, handleInitialize);
			service.addEventListener(UserInputMessage.GO_BUTTON_PRESSED, handleGoPressed);
			service.addEventListener(WheelStatusMessage.WHEEL_STATUS, handleWheelStatus);
			service.addEventListener(UserInputMessage.WHEEL_NEXT_ITEM, handleWheelNext);
			service.addEventListener(UserInputMessage.WHEEL_PREVIOUS_ITEM, handleWheelPrevious);
		}
		
		/**
		 * Slide the filmstrip into view, if it isn't already.
		 */
		public function showFilmstrip():void {
			Tween.tweenTo(filmstrip, 0.4, { y: FILMSTRIP_SHOWN_Y });
			filmstripOpen = true;
		}
		
		/**
		 * Slide the filmstrip out of view, if it isn't already.
		 */
		public function hideFilmstrip():void {
			Tween.tweenTo(filmstrip, 0.4, { y: FILMSTRIP_HIDDEN_Y });
			filmstripOpen = false;
		}
		
		/**
		 * Scroll the filmstrip forward (right) one item.
		 */
		public function nextItem():void {
			filmstrip.scrollPosition++;
		}
		
		/**
		 * Scroll the filmstrip backwards (left) one item.
		 */
		public function previousItem():void {
			filmstrip.scrollPosition--;
		}
		
		/**
		 * Called when the device has sent all our saved properties, and is ready for us to begin.
		 * @param e	The InitializeMessage instance.
		 *
		 */
		private function handleInitialize(e:InitializeMessage):void {
			// Create the filmstrip.
			filmstrip = new Filmstrip();
			filmstrip.itemRenderer = ImageItemRenderer;
			filmstrip.setSize(1280, 124);
			filmstrip.move(0, FILMSTRIP_HIDDEN_Y);
			filmstrip.setStyle("padding", 10);
			filmstrip.
			//filmstrip.addEventListener(Event.CHANGE, onFilmstripChange, false, 0, true);
			addChild(filmstrip);
			
			filmstrip.dataProvider = [ "one.png", "two.png", "three.png" ];
			
			trace("*** In the simulator, switch to CHANNEL view, then press the go button to show the filmstrip ***");
			helpLabel.text = "*** In the simulator, select this instance, switch to CHANNEL view, then press the go button to show the filmstrip ***";
		}
		
		/**
		 * Called when the go button is pressed on the device.
		 * This event will usually be followed by an optional GO_BUTTON_HELD event, and then a GO_BUTTON_RELEASED event.
		 * @param e	The UserInputMessage instance.
		 *
		 */
		private function handleGoPressed(e:UserInputMessage):void {
			
			// When the go button is pressed, request to enable or disable the wheel.
			// This will result in a WheelStatusMessage, which we listen for
			// and call handleWheelStatus.
			
			if (service.wheelEnabled) {
				service.disableWheel();
			}
			else {
				service.enableWheel();
			}
		}
		
		/**
		 * Called when the wheel has been disabled or enabled. In our case, we will use this to show
		 * the filmstrip.
		 * @param e	The WheelStatusMessage instance.
		 *
		 */
		private function handleWheelStatus(e:WheelStatusMessage):void {
			if (e.wheelEnabled)
				showFilmstrip();
			else
				hideFilmstrip();
		}
		
		private function handleWheelNext(e:UserInputMessage):void {
			if (filmstripOpen)
				nextItem();
		}
		
		private function handleWheelPrevious(e:UserInputMessage):void {
			if (filmstripOpen)
				previousItem();
		}
	}
}

VideoPlayer example

package
{
	import com.litl.control.Label;
	import com.litl.control.Slideshow;
	import com.litl.control.VideoPlayer;
	import com.litl.control.listclasses.ImageItemRenderer;
	import com.litl.sdk.message.*;
	import com.litl.sdk.service.LitlService;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	[SWF(backgroundColor="0", width="1280", height="800", frameRate="21")]
	public class VideoPlayerSample extends Sprite
	{
		protected var player:VideoPlayer;
		
		protected var helpLabel:Label;
		
		protected var service:LitlService;
		
		public function VideoPlayerSample() {
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initialize();
		}
		
		protected function initialize():void {
			
			helpLabel = new Label();
			addChild(helpLabel);
			helpLabel.move(10, 10);
			helpLabel.width = 1280;
			
			helpLabel.text = "Connecting to simulator.. if nothing happens, please make sure the simulator is running.";
			
			service = new LitlService(this);
			service.connect("videoplayer_sample", "Video player sample", "1.0", false);
			
			service.addEventListener(InitializeMessage.INITIALIZE, handleInitialize);
		
		}
		
		/**
		 * Called when the device has sent all our saved properties, and is ready for us to begin.
		 * @param e	The InitializeMessage instance.
		 *
		 */
		private function handleInitialize(e:InitializeMessage):void {
			player = new VideoPlayer();
			addChild(player);
			player.setSize(1280, 800);
			
			player.url = "http://dl.dropbox.com/u/2980264/OSMF/logo_animated.flv";
			player.autoPlay = true;
			helpLabel.text = "";
		}
	
	}
}

Appendix B

Style properties used by litl controls

TextButton

Style nameDescription
upSkinDefine a class to use for the button's "up" state. You should include the whole package (ie. com.litl.skin.parts.TextButtonUpSkin)
downSkinDefine a class to use for the button's "down" state. You should include the whole package (ie. com.litl.skin.parts.TextButtonDownSkin)
overSkinDefine a class to use for the button's "over" state. You should include the whole package (ie. com.litl.skin.parts.TextButtonOverSkin)
disabledSkinDefine a class to use for the button's "disabled" state. You should include the whole package (ie. com.litl.skin.parts.TextButtonDisabledSkin)

TextButtonUpSkin, TextButtonDownSkin, TextButtonOverSkin, TextButtonDisabledSkin

Style nameDescription
borderColorThe color of the button border, ie. 0xffffff
borderThicknessThe thickness of the button border, in pixels.
backgroundColorThe color of the button background, ie. 0x9ad7db
cornerRadiusThe roundedness of the button corners, in pixels.

.textButtonUpLabel, .textButtonOverLabel, .textButtonDownLabel, .textButtonDisabledLabel

Style nameDescription
fontFaceThe font to use for TextButton labels.
colorThe font color to use for TextButton labels.
sizeThe font size to use for TextButton labels, in pixels.

Slideshow

Style nameDescription
paddingThe number of pixels to place between the content and the slideshow border.
gapThe pixel gap between items in the list

Filmstrip

Style nameDescription
paddingThe number of pixels to place between the content and the filmstrip border.
gapThe pixel gap between items in the list
backgroundSkinDefine a class to use for the Filmstrip background. You should include the whole package (ie. com.litl.skin.parts.FilmstripBackground)

VerticalList

Style nameDescription
paddingThe number of pixels to place between the content and the list border.
gapThe pixel gap between items in the list
backgroundSkinDefine a class to use for the VerticalList background. You should include the whole package.

LitlScrubBar

Style nameDescription
trackSkinDefine a class to use for the video player's scrub bar track. You should include the whole package.
barSkinDefine a class to use for the video player's scrub progress bar. You should include the whole package.
bufferBarSkinDefine a class to use for the video player's scrub buffer bar. You should include the whole package.

LitlPlayButton, LitlPauseButton

Style nameDescription
upSkinDefine a class to use for the button's "up" state. You should include the whole package (ie. com.litl.skin.parts.PlayButtonUpSkin)
downSkinDefine a class to use for the button's "down" state. You should include the whole package (ie. com.litl.skin.parts.PlayButtonDownSkin)
overSkinDefine a class to use for the button's "over" state. You should include the whole package (ie. com.litl.skin.parts.PlayButtonOverSkin)
disabledSkinDefine a class to use for the button's "disabled" state. You should include the whole package (ie. com.litl.skin.parts.PlayButtonDisabledSkin)