Bamboo Dock Knowledge Bank

 
 

Using tablet pen pressure and gesture

By Wacom 12 January 2010
User Level: Intermediate

The Bamboo Mini SDK provides classes and infrastructure for using the special functionalities of the Bamboo tablet. In the current version of the SDK the following tablet features are available:

  • Pen pressure
  • Pen sensor (tells if the the tip or the eraser of the pen is in use)
  • Multi-touch gestures for tablets with touch support.
    • Zoom in and out
    • Rotate clockwise and counterclockwise
    • Vertical scroll
    • Horizontal scroll
    • Swipe

There are two ways you can access tablet information:

  • The currently recommended way is to use the tabletState static property of the BambooMiniGlobals class.
  • The other approach is to handle tablet events dispatched from the display objects on stage. This approach is more convenient in most situations but it is less flexible and there is a risk of degrading performance due to the fact that it relies on a large number of bubbling events.

Using the BambooMiniGlobals.tabletState object

The BambooMiniGlobals class has a static property tabletState from the type ItabletState. This objects provides information for the pen pressure, sensor and multi-touch gestures. The definition of the ItabletState interface is as follows:

	[Event(name="tabletStatePenPressureChange", type="com.wacom.mini.core.tablet.TabletStateEvent")]
	[Event(name="tabletStatePenSensorChange", type="com.wacom.mini.core.tablet.TabletStateEvent")]
	[Event(name="tabletStateDriverVersionReceive", type="com.wacom.mini.core.tablet.TabletStateEvent")]
	[Event(name="tabletStateInitialize", type="com.wacom.mini.core.tablet.TabletStateEvent")]
	
	[Event(name="zoom", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
	[Event(name="rotate", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
	[Event(name="vscroll", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
	[Event(name="hscroll", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
	[Event(name="swipe", type="com.wacom.mini.core.tablet.TabletGestureEvent")]

	public interface ITabletState extends IEventDispatcher
	{
		[Bindable("tabletStatePenSensorChange")]
		function get penSensor() : PenSensor;
	
		[Bindable("tabletStatePenPressureChange")]
		function get penPressure() : Number;
	
		[Bindable("tabletStateDriverVersionReceive")]
		function get driverVersion() : String;
	
		function loadDriverVersion() : void;
	
		[Bindable("tabletStateInitialize")]
		function get initialized() : Boolean;
	}

As you can see, this object dispatches events when the pen pressure is updated, when the pen sensor is changed, driver version is known, etc. In addition there are the penSensor and penPressure properties which can be used as a source of data bindings. All multi-touch gesture events are dispatched by this object. To exemplify this, imagine you want to handle the horizontal scroll gesture in you application. The way to do it is to add an event listener to the tabletState object:

	BambooMiniGlobals.tabletState.addEventListener(TabletGestureEvent.HSCROLL,
	  function (event : TabletGestureEvent) : void
		  {
			var direction : String = 
			(event.direction == 
			TabletGestureEventDirection.LEFT) ? 
			"Left" : "Right";
			trace( "Horizontal scroll gesture. Direction=
			"+ direction);
		  });	

You can notice that TabletGestureEvent contains info only for the direction of the scroll but not for the value. This is caused by the way drivers report the information - you just receive many HSCROLL events for a single gesture done by the user.

Listening for events dispatched by the display objects on stage

This approach is generaly more convenient since it mimics the way Mouse and Keyboard events are dispatched in Flash but it relies on a large number of bubbling events which might affect the performance of you application.

If you want to use this feature you have to set the dispatchTabletEvents static property from the BambooMiniGlobals class to true.

By doing this you're telling the TabletManager to dispatch a TabletEvent for every mouseMove, mouseDown, mouseUp, etc. event that is dispatched by an object displayed on stage.

Let's see an example:

You have a Sprite "A" on your stage. Every time "A" dispatches a mouseMove event on the same frame, TabletManager makes it dispatch penMove too.

This penMove event is from the type com.wacom.mini.core.tablet.TabletEvent. This event extends the MouseEvent class and has all the properties that the mouse event has (localX,currentTarget, etc.).

In addition they have two more properties: pressure and penSensor.

The gesture events will be dispatched in a similar fashion. Basically it will listen for a multi-touch gesture event the same way it will for a regular keyboard event.

This is the list of tablet events that are dispatched by the objects into the display list. As you can see most of them correspond to mouse events (penDown ? mouseDown, penTap ? mouseClick, etc.).

	[Event(name="penDown", type="com.wacom.mini.core.tablet.TabletEvent")]
	[Event(name="penUp", type="com.wacom.mini.core.tablet.TabletEvent")]
	[Event(name="penMove", type="com.wacom.mini.core.tablet.TabletEvent")]
	[Event(name="penTap", type="com.wacom.mini.core.tablet.TabletEvent")]
	[Event(name="penRollOver", type="com.wacom.mini.core.tablet.TabletEvent")]
	[Event(name="penRollOut", type="com.wacom.mini.core.tablet.TabletEvent")] 

	[Event(name="penPressureChange", type="com.wacom.mini.core.tablet.TabletEvent")]

	[Event(name="penSensorChange", type="com.wacom.mini.core.tablet.TabletEvent")]

	[Event(name="zoom", type="com.wacom.mini.core.tablet.TabletGestureEvent")] 
	[Event(name="rotate", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
	[Event(name="vscroll", type="com.wacom.mini.core.tablet.TabletGestureEvent")] 
	[Event(name="hscroll", type="com.wacom.mini.core.tablet.TabletGestureEvent")] 
	[Event(name="swipe", type="com.wacom.mini.core.tablet.TabletGestureEvent")]
 

If you are using the mxml you could run into a problem because you are unable to write the event handler in-line the component declaration when using Flex® components.

 
< - This would NOT WORK.

To resolve this inconvenience you can use the TabletEventsProxy class:

<mx:TextInput text = "some text" id = "myTextInput"/>
<tablet:TabletEventsProxy source = "{myTextInput}" 
penMove = "trace(' Pen move WITH pressure :' + 'event.pressure' + ' .Sensor :' + 'event.penSensor.value')" 
penDown = "trace(' Pen down.Sensor used :' + 'event.penSensor.value')"
penUp = "trace(' Pen up ')" 
penTap = "trace(' Pen tap ')" />

In this example we are tracing tablet events dispatched by the myTextInput component. We declare a TabletEventsProxy instance and set its source property to be the text input. The TabletEventsProxy instance has metadata for all tablet events and will add the declared event listeners to its source property (our text input). This way, we are processing the tablet events dispatched by the myTextInput component. The following code is an example of a button that will scale up in size when the user presses harder with the pen cursor on it. It uses the TabletEventsProxy to declare inline event handlers for the penPressureChange and penRollOut events. When the pen pressure is changed, the width and the height will be increased depending on the value of the pressure.

<m:Button id = "btn" width = "100" height = "100" label = "Click Me" verticalCenter = "0" horizontalCenter = "0" / >

<tablet:TabletEventsProxy source="{btn}" 
		penPressureChange="btn.width = btn.height = Math.round(100 + event.pressure/16)"
        penRollOut="btn.width = btn.height = 100"/>

Conclusion

In this article you have learned how take advantage of the tablet features in you Mini. Using them allows you to build applications that utilize the pen pressure info and gain access to multi-touch gestures.