Enabling Touch Manipulations on Windows Phone

All Windows Phone 7 devices (even the emulator) are multi-touch. If you’re fortunate enough to have a touch-enabled PC then the WP7 emulator will translate the touch input from your screen to the emulated device – a nice touch (sorry) and a great way to debug without the need for a real device. Given devices are rarer than even the rarest of things at the moment, that’s very handy indeed.

I thought it’d be an interesting exercise to enable my Vuvuzella app for touch gestures, thereby removing the need for the awful “Spin” button and making the whole thing a lot more user friendly and useful. Okay, I’m stretching it a bit with “useful”. This turned out to be simpler than I’d hoped; approaching trivial in fact.

Silverlight for Windows Phone uses the concept of “manipulations” to process touch events. Manipulations are “meta” touch events, collecting the low-level touch data and converting it into convenient properties that make it much easier to interpret what the user is doing.

Any class derived from UIElement supports manipulation events. Specifically there are events for ManipulationStarted, ManipulationCompleted and ManipulationDelta. Two of these are self-explanatory; ManipulationDelta occurs as the input device (my finger) changes position during the manipulation. In other words it’s possible to get many deltas between a started and completed.

More details can be found on MSDN and Charles Petzold has written a very detailed description and comparison with WPF.

In my case, all I needed in terms of input was to respond to a “touch” on one of the Border elements that hosts the vuvuzella image (either using MouseLeftButtonDown as I had in v1 or ManipulationCompleted) to start the vuvuzella playing and a “swipe” to rotate the carousel.

For the touch I opted to switch to a ManipulationCompleted event on the Border element so I could handle that event and prevent it bubbling. It also means I can avoid starting the vuvuzela playing for what turns out to be a swipe – something that was happening using MouseLeftButtonDown. The only code I needed to add to the handler was a check to ensure we were seeing a “tap” gesture:

 if (e.IsTapEvent)
{
    // Code to start the vuvuzela playing goes here
}

For the swipe I started by handling the event on the Grid element that hosts the carousel but quickly changed to capturing the event on the MainPage ie the outer element. It was then very simple to add a check to ensure this wasn’t a tap, and was in fact a swipe of sufficient magnitude and velocity. ManipulationCompletedEventArgs exposes details of the overall Translation (and Scale) distance as well as the Linear and Expansion velocities. Therefore my handler was as simple as below (Rotate is the name of the storyboard that causes the carousel to rotate):

 private void MainPage_ManipulationCompleted(object sender, 
    ManipulationCompletedEventArgs e)
{
    if (e.IsTapEvent == false)
    {
        if ( e.TotalManipulation.Translation.X < -100 && 
             e.FinalVelocities.LinearVelocity.X < -1000 )
            Rotate.Begin();
    }
}

Having implemented those changes, and with a little amazement at how simple it turned out to be, I removed the UI for the “spin” button, made use of the freed up space to increase the size of the carousel a little and whipped out the Flip to take a little video of the app in action.

Of course I could get a lot more sophisticated and use manipulations to control the carousel more directly by it actually works pretty well. And given the useful lifespan of this app is another few days (Sunday is the final IIRC), I think I’ll leave it just as it is.

Unless of course I could repurpose the app for Wimbledon next year, or the Open perhaps…