The amazing adventures of Doug Hughes

Archive for November, 2009

Checking the Users Multi-Touch Capabilities

Adobe just released the beta version of Flash Player 10.1 on their ‘labs’ site. Previously I’ve written about the new multi-touch events and written a quick how to on displaying multi-touch events with the new Air 2 SDK and now I’m going to talk quickly about checking a users multi-touch capabilities.

Checking the users multi-touch capabilities is especially important because users hardware and multi-touch capabilities is going to vary widely as new monitors, mice and input devices trickle into the market place. As such, we’ll need to adjust our application to take advantage of different ‘MultiTouchInputModes’.

Here’s the code I’m suggesting:

protected function application1_creationCompleteHandler(event:FlexEvent):void {
	setTouchScreenType();
}

protected function addTransformListeners():void {
	this.addEventListener(TransformGestureEvent.GESTURE_PAN,
			transformEventHandler, false, 0, true);
	this.addEventListener(TransformGestureEvent.GESTURE_ROTATE,
			transformEventHandler, false, 0, true);
	this.addEventListener(TransformGestureEvent.GESTURE_SWIPE,
			transformEventHandler, false, 0, true);
	this.addEventListener(TransformGestureEvent.GESTURE_ZOOM,
			transformEventHandler, false, 0, true);
}

protected function addTouchListeners():void {
	this.addEventListener(TouchEvent.TOUCH_BEGIN, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_END, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_MOVE, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_OUT, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_OVER, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_ROLL_OUT, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_ROLL_OVER, touchEventHandler, false, 0, true);
	this.addEventListener(TouchEvent.TOUCH_TAP, touchEventHandler, false, 0, true);
}

protected function touchEventHandler(event:TouchEvent):void {
	trace(event.toString());
}

protected function transformEventHandler(event:TransformGestureEvent):void {
	trace(event.toString());
}

protected function setTouchScreenType():void {

	if (Capabilities.touchscreenType == TouchscreenType.FINGER) {
		addTouchListeners();
		Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
	}
	else {
		addTransformListeners();
		Multitouch.inputMode = MultitouchInputMode.GESTURE;
	}
}

Before assuming that they have gesture capabilities we could also check if they are on Snow Leopard:

if(Capabilities.os.indexOf('Mac OS 10.6') !=-1 )
{
	trace('Your kicking it with Snow Leopard');
}

I’m not sure how to check if they are on a laptop with a trackpad. Any ideas?

Any danger in just listening for all of these events? Well nothing life threatening. If the hardware isn’t capable, the events simply don’t fire. It’s always a good idea to use weak references when listening for events and/or remove event listeners so that we’re not inadvertently using up unneeded memory allocations.

So with this information we can somewhat accurately customize our application to take advantage of what type of hardware our users might be sitting behind. We might have a picture collage that reacts differently to the different type of hardware that it’s viewed on for example.

If your company is interested in multi-touch or just want to talk. Drop us a note on our contact page.

Checking Out the New MultiTouch Events in Flash 10.1

In this series on the new multi-touch capabilities in the new flash player 10.1, I’m going to take a closer look at the new events that are fired off by the flash player when dealing with multiple touch inputs.

The two new events that I’m particularly interested in are: flash.events.TouchEvent and flash.events.TransformGestureEvent.

The new TouchEvent class is fired off by the flash player when the player detects a single touch. This class should look very familiar to those who are comfortable with the MouseEvent. It’s my current understanding that this event can only be fired on touch enabled Windows 7 machines. I have no doubt that this will change in the near future but as of this writing (November 09) Linux and OSX don’t have a clear way to dispatch the TouchEvent class.

Types include:

  • TouchEvent.TOUCH_BEGIN
  • TouchEvent.TOUCH_END
  • TouchEvent.TOUCH_MOVE
  • TouchEvent.TOUCH_OUT
  • TouchEvent.TOUCH_OVER
  • TouchEvent.TOUCH_ROLL_OUT
  • TouchEvent.TOUCH_ROLL_OVER
  • TouchEvent.TOUCH_TAP

The new TransformGestureEvent class is fired off by the flash player when the player detects a gesture from the operating system. OSX users will be familiar with the ‘Pinch’, ‘Zoom’ and ‘Pan’ feature that is commonly used via the newer trackpads on most Macintosh laptops. It’s important to note that OS 10.6 (Snow Leopard) is required for the flash player to consume these events from the trackpad correctly. The flash player makes use of these gestures and dispatches the appropriate type of TransformGestureEvent. Windows 7 can also dispatch these same gesture event types.

Types include:

  • TransformGestureEvent.GESTURE_PAN
  • TransformGestureEvent.GESTURE_ROTATE
  • TransformGestureEvent.GESTURE_SWIPE
  • TransformGestureEvent.GESTURE_ZOOM

A sample event might look like this:

[TransformGestureEvent type="gestureRotate" bubbles=true, cancelable=false phase=null localX=20 localY=20 stageX=20 stageY=20 scaleX=1 scaleY=1 rotation=0 offsetX=0 offsetY=0 ctrlKey=false altkey=false shiftKey=false commandKey=false controlKey=false]

Just like a mouse event the developer can handle that rotation event however they wanted. Most likely a developer might want to rotate the currentTarget of the TransformGestureEvent.

One requirement that might be overlooked is that you have to specify the type of events that your applications will be consuming.

This code is required:

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT

or

Multitouch.inputMode = MultitouchInputMode.GESTURE;

Your flash 10.1 or Adobe Air 2 application can switch between touch input modes but it can’t consume them both at the same time.

If there is anything that Alagad can do to help you or your company get started with your multi-touch project, please don’t hesitate to contact us.

Thanks for posting comments, corrections or questions.

Tracing Out MultiTouch Events

There hasn’t been a ton of interest when I’ve posted multi-touch subject matter on this blog in the past. But I’m not letting that stop me. I’m excited about the new features in the Beta version of Adobe Air 2, and I’m going to start in on a series of Blog posts that talk about some of the basics of the new multi-touch capabilities in the new flash player release.

One of the first things I did when I was starting to play with the new feature were to trace out all of the new multi-touch events that come with new Flash Player 10.1 (also used within Air 2 applications).

Here’s the code I quickly came up with:

protected function application1_creationCompleteHandler(event:FlexEvent):void {
	setTouchScreenType();
}

protected function addTransformListeners():void {
	this.addEventListener(TransformGestureEvent.GESTURE_PAN,
			transformEventHandler);
	this.addEventListener(TransformGestureEvent.GESTURE_ROTATE,
			transformEventHandler);
	this.addEventListener(TransformGestureEvent.GESTURE_SWIPE,
			transformEventHandler);
	this.addEventListener(TransformGestureEvent.GESTURE_ZOOM,
			transformEventHandler);
}

protected function addTouchListeners():void {
	this.addEventListener(TouchEvent.TOUCH_BEGIN, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_END, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_MOVE, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_OUT, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_OVER, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_ROLL_OUT, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_ROLL_OVER, touchEventHandler);
	this.addEventListener(TouchEvent.TOUCH_TAP, touchEventHandler);
}

protected function touchEventHandler(event:TouchEvent):void {
	eventLabel.text = event.toString() + "n" + eventLabel.text;
}

protected function transformEventHandler(event:TransformGestureEvent):void {
	eventLabel.text = event.toString() + "n" + eventLabel.text;
}

protected function setTouchScreenType():void {
	if (Capabilities.touchscreenType != 'finger') {
		addTouchListeners();
		Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
	}
	else {
		addTransformListeners();
		Multitouch.inputMode = MultitouchInputMode.GESTURE;
	}
}

On the creation complete event I start listening for some of our new multi-touch events. Within the MXML I have a TextArea named ‘eventLabel’ that displays the events as a user touches the screen. Just that simple.

If you have a touch enabled screen or an OSX 10.6 operating system with a newish trackpad, feel free to give something like this a try and hopefully you’ll start to see all the new events scrolling down your screen.

In the next post in this series I plan on discussing the two new events of Flash Player 10.1 in a little more detail.

Thanks for any comments and corrections.

Connecting Adobe Flex to FileMaker Pro Applications

Adobe’s Flex framework is a beautiful tool for building forward facing applications and exposing data, editing data and visualizing data in a variety of different ways. Many companies may be avoiding using this technology simply because they feel that they’ve already committed to another platform. I’d like to quickly highlight the possibility that the Flex framework may still be an exceptional resource to add to your existing technology platform. Say, for example, you have a client that wanted to deliver their existing filemaker pro application with the rich front end user interface created in Flex.

Here are a few quick tips to help you get started.

After installing File Maker and File Maker Server. Open the correct File Maker database file. Set privileges for ‘fmsxml’. ( File – Manage – Accounts & Privileges ) I recommend creating a Privilege Set for exposing this data via xml.

In your File Maker Server Console tool, upload your data set to the server. Make sure that your new database is running and that there is a check-mark under the XML column.

In a browser the following URL will display all of the record sets from your data set:

http://127.0.0.1/fmi/xml/fmresultset.xml?-db=FileMakerFile&-lay=Layout&-findall Replace http://127.0.0.1/ with your server location. (Replace ‘FileMakerFile’ and ‘Layout’ with the Database and Layout of the data that you’d like to display)

Notice the ‘findall’ command at the end. FileMaker Server behaves very much like a web service meaning that FileMaker bakes in a set of commands that allows you to add, update, delete, find a specific record sets or find the entire record set right out to the box.

Adobe Flex has a set of defined classes and methods for specially working with XML data. Using these classes Flex is able to retrieve, update or delete data from the FileMaker database in organized way. In this case, I just created some quick data visualizations from the data set.

If your company is interested in exposing your preexisting data sets to a richer user interface powered by Adobe Flex please don’t hesitate to contact us.

Adobe releases Air 2 and Flash Player 10.1 on Labs

Adobe released Air 2 in Beta on the labs section of their website last evening. I’ve been building multi-touch applications in Flash and Flex for the past two year. In order to do this in the past you had to create your own touch events and use additional software to interpret touch events in a meaningful way and dispatch custom touch events that could be used by the Flash runtime. Finally with the beta of Adobe Air and the Air SDK we have native multi-touch events in Flash.

The most basic touch event class is called TouchEvent. The TouchEvent class is going to look extremely familiar to anyone that has used the MouseEvent. Most commonly developers might use the TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END and TouchEvent.TOUCH_TAP event types.

In addition to the touch Event class there are events that respond to gestures. The TransformGestureEvent class responds to pans, zooms and rotate.

If you go to Adobe Labs and pull the 10.1 release of the Flash player you’ll be able see content that is multi-touch enabled in your browser. You can start playing with multi-touch applications by going and grabbing the Adobe Air SDK at Adobe labs.

Other feature of note in Air 2 (from the labs site)

  • Support for the detection of mass storage devices.
  • Advanced networking capabilities like secure sockets, UDP support, and the ability to listen on sockets.
  • Support for native code integration.
  • The ability to open a file with its default application.
  • Multi-touch and gesture support.
  • New APIs for access to raw microphone data.
  • Webkit update with HTML5/CSS3 support.
  • Global error handling.
  • Improved cross-platform printing
  • Improved security and support for enterprise and government standards.

Custom Preloaders for Flex

I’d like to encourage the general Flex community to take a second to build a quick custom preloader for the project that they are currently working on. It doesn’t take but a minute or two and it will distinguish your application from the sea of other Flex applications out there right from the start.

One of the easiest ways I’ve found to build a custom preloader for your Flex application is to start in Flash Professional. I usually just build a nice animation over 100 frames. If you are using some text that gives the amount loaded then you’ll need to make sure you set that to dynamic text so that we can manipulate that information later. Make sure you export your Custom Preloader class for action script. ( I’m in CS3 and you just go to the Library, right click on the preloader and change the linkage to export for ActionScript. Next export that same Library preloader object as a SWC.

Now over in Flex Builder we’ll need to import that SWC. You can do this by dropping the SWC in your libs folder. Or you can specify the location of the SWC in the project properties section. File – Properties – Build Path – Library path – Add SWC.

Keeping this quick, I’d suggest just extending the DownloadProgressBar Your preloader class will be able to take advantage of some of the code that’s already baked into that component.

In the class constructor add the custom preloader. When the ‘on added to stage’ event fires center the preloader and be sure to stop the preloader from running.

We’ll use the pre-baked ‘set preloader’ method to listen for some events. The preloader class passes in a reference to itself so that it can listen for events like progress or completion.

public override function set preloader(preloader:Sprite):void
{
	preloader.addEventListener(ProgressEvent.PROGRESS, onProgress);
	preloader.addEventListener(FlexEvent.INIT_COMPLETE, intComplete);
}

After the application has loaded we just need ot fire the complete event. Otherwise our viewers will be able to see our preloader but not ever view the application.

protected function intComplete(event:FlexEvent):void
{
	dispatchEvent(new Event(Event.COMPLETE));
}

We’re also listening for the progress event. We use that to update the current frame of our flash preloader, additionally we can update our dynamic text input. (here called ‘percent’)

protected function onProgress(event:ProgressEvent):void
{
	customPreloader.percent.text = Math.ceil(event.bytesLoaded / event.bytesTotal *100).toString() + '%';
	customPreloader.gotoAndStop( Math.ceil(event.bytesLoaded / event.bytesTotal *100));
}

Here’s the entire preloader class:

package com.alagad.view.preloader {

import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;

import mx.events.FlexEvent;
import mx.preloaders.DownloadProgressBar;

public class RedPreloader extends DownloadProgressBar {

	protected var customPreloader:CustomPreloader;

	public function RedPreloader() {
		customPreloader = new CustomPreloader();
		addEventListener(Event.ADDED_TO_STAGE, onAdded);
		addChild(customPreloader);
	}

	protected function onAdded(event:Event):void {
		customPreloader.stop();
		/put in in the upper middle
		customPreloader.x = stage.stageWidth * 0.5 + 65;
		customPreloader.y = stage.stageHeight * 0.5 - 160;
	}

	public override function set preloader(preloader:Sprite):void {
		preloader.addEventListener(ProgressEvent.PROGRESS, onProgress);
		preloader.addEventListener(FlexEvent.INIT_COMPLETE, intComplete);
	}

	protected function intComplete(event:FlexEvent):void {
		dispatchEvent(new Event(Event.COMPLETE));
	}

	protected function onProgress(event:ProgressEvent):void {
		customPreloader.percent.text = Math.ceil(event.bytesLoaded / event.bytesTotal * 100).toString() + '%';
		customPreloader.gotoAndStop(Math.ceil(event.bytesLoaded / event.bytesTotal * 100));
	}
}
}

The last thing to do is quickly add the class that we made to our main application tag.


If your looking for inspiration for preloaders then you need to check out Big Spaceships new site called PrettyLoaded (http://www.prettyloaded.com)

If your looking for a nice video tutorial covering some of the stuff in this blog post, be sure to check out Lee Brimelow’s website http://gotoandlearn.com where he shows off how to build a custom Flex Preloader in this episode.

Tag Cloud