Cover

What I Learned By Writing a WP7 App: Part 1 - Manipulations

June 24, 2010
No Comments.

As some of you have heard, I am working on a Windows Phone 7 book. While most of my time has been spent trying to convince the publisher to let me call it “The Windows Phonebook: Writing Applications for Windows Phone 7, A-Z”, I’ve had the chance to start writing a real application with it. The purpose of the application is to get comfortable with the programming environment but be able to ship a free app at launch that has some value (yeah, I am already signed up for a Marketplace Developer account!).

For this first application, I decided to completely rip off use for inspiration a couple of Android applications that show the current phase of the moon. Writing this simple app was not that difficult (though its not done so I won’t be sharing the code yet), but I found that I spent more time trying to get good moon images and a good moon-phase algorithm than I did in getting the Silvelright code to work. Here’s the current look of the application:

Moon Phaser

(click the image for a full sized version)

The idea is simple, show the current day’s moon phase and let the user swipe right or left to move the current day and watch the moon change phase. To do this I had to get comfortable with Manipulations.

Manipulations are the way that the Windows Phone 7 SDK communicates the touch interface to the developer.  Currently the Manipulations are only available to subclasses of the Control class because the ‘events’ are exposed as protected virtual methods. This is suboptimal but it does work. I hope this changes in later versions of the SDK.

When using Manipulations, you have three virtual methods you can override (typically in a UserControl or in my case the MainPage which derives from the PhoneApplicationPage class). These methods are:

  • OnManipulationStarted
  • OnManipulationDelta
  • OnManipulationCompleted

In my case I focused on the completion of a Manipulation (swipes) so I only had to deal with one of the methods: OnManipulationCompleted. This virtual method passes in ManipulationCompletedEventArgs object that contains information about the manipulation and the object it was connected to. So in my overriding of the virtual method, the first thing I needed to do was to ensure that the manipulation was directly on the the image of the moon by checking the ManipulationContainer property of the ManipulationCompletedEventArgs:

public partial class MainPage : PhoneApplicationPage
{
  // ...

  protected override void OnManipulationCompleted(
    ManipulationCompletedEventArgs e)
  {
    base.OnManipulationCompleted(e);

    // Ensure its the Moon Picture that is being manipulated
    if (e.ManipulationContainer == moonPic)
    {
      // ...
    }
  }

  // ...

}

Since we cannot (hopefully yet) handle events directly on Controls, I needed to ensure that the swipe happened on the image itself.  Now that I knew its on the picture of the moon, I could test to see what kind of swipe occurred if any. The ManipulationCompletedEventArgs has a property called TotalManipulation that exposes the information about the complete touch gesture. The TotalManipulation property is an instance of the ManipulationDelta class. This class exposes two properties that tell you about the type of gesture that was generated.  The properties are:

  • Translation: The movement of the gesture as in dragging or swiping.
  • Scale: The extent of a pinch gesture.

The name of these properties is similiar to their relationship to the Transforms that match the two operations (TranslateTransform and ScaleTransform). With the information in the TotalManipulation, I could determine if a swipe occurred simply by testing to see direction of the swipe (by testing the Translation’s X and Y properties):

// If its a swipe right which means that the user 
// dragged their finger at least 100 pixels to the right 
// and didn't move their finger far to up or down 
// (-25 to 25 in the translation)
if (e.TotalManipulation.Translation.X > 100 &&
    (e.TotalManipulation.Translation.Y > -25 && 
     e.TotalManipulation.Translation.Y < 25))
{
  _vm.MoveToNextDay();
  SetMoonFrame();
}

// If its a swipe left which means that the user 
// dragged their finger at least 100 pixels to the left
// and didn't move their finger far to up or down 
// (-25 to 25 in the translation)
if (e.TotalManipulation.Translation.X < -100 &&
    (e.TotalManipulation.Translation.Y > -25 && 
     e.TotalManipulation.Translation.Y < 25))
{
  _vm.MoveToPreviousDay();
  SetMoonFrame();
}

In this code I am checking the translation to see where the swipe happened.  Checking the X axis was making sure the swipe was at least 100 pixels in length and the Y axis to make sure it was somewhat level swipe.  While some are hoping that the raw gesture data will also be exposed by Microsoft for the phone, the simplification of the Manipulation API does make most simple work dead easy to code against.

As I continue working on the book and this (and other) applications, I’ll continue this series to hopefully highlight some of the new API’s in the WP7 SDK.