We had a great time at the Columbia Code Camp this year. A lot of great speakers and volunteers to help with the event. We had I think around 150 people show up which was amazing since it was snowing, raining and freezing temperatures .
I did my multi-touch presentation for the first time and I think it went very well. Had some great feedback and questions afterwards.
So as promised I am posting up the materials and a quick explanation of what is available to use for Multi-Touch in WPF and Silverlight. In the demo code for WPF you will need to change the App.xaml to point to the different demo windows. You can download the demo code here.
In both WPF and Silverlight there is a concept called Raw Touch. These events are close to the mouse events in that they work with a device and a point (position) on the visual. Here are the events:
- TouchDown – Occurs when a touch device touches the visual
- TouchMove – Occurs when a touch device is down and starts to move across the visual
- TouchUp – Occurs when the touch device is lifted off the visual
- TouchEnter – Occurs when the touch device is down and while moving enters a new visual
- TouchLeave – Occurs when the touch device is down and while moving leaves a visual
- Touch.TouchFrameReported – Static Event that is fired any time a touch device activates on a visual
In WPF we can attach handlers to the above events to an individual element and they will only fire when touch is activated on that visual. For Silverlight however we do not have this. The TouchFrameReported event will fire no matter what visual has had touch activated. It is constantly looking for this event on a frame draw. Even if you touch your finger down and hold it without moving the TouchFrameReported event is still firing with a Move action.
The key to these events (even the Silverlight one) is the GetTouchPoint or GetTouchPoints methods. With these methods you can pass in an element and get the point that you are currently touching. What’s cool about this is that if we have 2 elements one of top of the other, but the element underneath is larger than the we actually touched, we can pass in the element underneath and get the touch point relative to that element instead of the one on top. So we have a lot of power behind where we can get these touch points in relation to which elements we have defined.
Another key to RawTouch is the Device’s Device Id. Each unique finger that touches the screen will get a unique device ID. By utilizing this device ID we can accurately keep track of which finger is performing what action and act appropriately. By doing this we can now truly write something in Multi-Touch .
To see more detail please look at the RawTouch and Gesture demos. The Gesture demos show how we can write one common library in WPF and Silverlight that can recognize straight line gesture activations and abstractly report them to a handler or command.
One other cool thing that we do have in WPF that we don’t have in Silverlight is Manipulations. These events take alot of the guess work out of raw touch and simplifies the data passed into the handlers.
The events to take note of are:
- ManipulationStarting – occurs when a manipulation is triggered and about to start
- ManipulationStarted – occurs when a manipulation has started
- ManipulationDelta – occurs when a manipulation has changed its data based on movement
- ManipulationInertiaStarting – occurs when inertia is about to kick in for a manipulation.
Lets say we want to handle the pinching resize functionality that seems to be common in multi-touch. Well with RawTouch that would be very difficult as we have to calculate that 2 touch points are moving in opposite directions away from each other. Then we have to calculate the difference between them and provide a scale vector. This could be a real pain to do in RawTouch.
With Manipulations all of that hard work is done for us. When the ManipulationDelta event fires the args provide a DeltaManipulation with a Scale property. This Scale is the vector difference of our resize. If Scale is not populated then we know we did not do a resize. We are also provided with a Rotate that is a decimal in the degree change and a Translate which handles straight movement. Manipulations make it very easy to get started with multi-touch.
Inertia is a cool way to provide smooth deceleration transitions from a manipulation to a stopping point. Lets say you move a rectangle across the screen but you don’t want it to stop immediately when you lift your finger, but instead you want it to keep going and slow down to a stopping point. Inertia is an easy way to allow this.
When the ManipulationInertiaStarting event fires it has already calculated your velocity for you! It has determined how much distance was crossed and how fast your manipulation occured to give you this initial velocity. From this you just provide it a deceleration rate to tell it how fast it needs to slow down. A deceleration rate of 10 inches per second every second could look like this “10.0 * 96 / (1000 * 1000)”. With this we can control how it slows down when continuing a manipulation.
For more detail on the code please see the demos provided.
Well thats the basics of what multi-touch capabilities are provided in WPF and Silverlight. I hope you enjoyed this topic and enjoy the code!
I will be presenting on this topic in Atlanta at the Atlanta MS Pros user group on March 1st. I hope to see you there!