Skip Ribbon Commands
Skip to main content

Quick Launch

Home
Touching on Windows 7, Silverlight 3 and 4, Microsoft Surface ...
December 17
Quick Tip: Radians vs. Degrees

You can build Surface applications using WPF or XNA. While the two are different from one another, once you get used to it, switching between WPF and XNA isn’t too bad.

There is one thing that always trips me up though: when the manipulation processor reports back rotation delta in the Delta event, it will be reported in either radians or degrees. It all depends on what you’re programming in. If you’re using WPF, it will be in degrees. If you’re using XNA, it will be in radians. Looking at the online help for the Surface SDK confirms this difference as well.

Converting from one to the other is simple:

radiandegree

So, if you’re trying to do some kind of custom rotation calculation and things aren’t working as you expected, make sure you’re using the correct units!

Paul Osburn
Engineering Director, Surface

November 25
Hard Rock at PDC09

It was a good week at PDC09 for the Hard Rock Worldwide Memorabilia application.

Hard Rock Worldwide Memorabilia Application for Microsoft Surface

At the show, the Surface team dedicated a Surface (sounds kinda repetitive) to all things Hard Rock, which included the custom attract and memorabilia applications Vertigo and Duncan/Channon created with Hard Rock. It was the same Surface experience you’ll get (minus the atmosphere, music, cocktails, food, etc.) when you visit Hard Rock’s new cafe on the Vegas strip.

We also got word that the Worldwide Memorabilia application was runner up in Microsoft’s Touch First Developer challenge.

There were over 40 entries across six different countries. Runner-up … so close. There must be fabulous prizes for runner-up though. Maybe an autographed photo of the Surface team? Or perhaps a toaster. Either would be exciting.

 

 

 

Paul Osburn
Engineering Director

October 14
Quick Tip: Freeing Up Resources when Using the Surface Simulator

On my machine, running the Surface Simulator that comes with Surface SDK SP1 works great. My resolution is high enough (the Simulator requires a resolution of 1280x960 or higher to run) and I’ve got enough memory to keep everybody happy.

Sometimes you might need to develop on a machine that may be a bit less powerful that what is needed to run things smoothly. To free up some resources you can kill the Surface Attract application once the Simulator starts. This doesn’t help much since the Surface Shell stops the attract app as soon as your application runs.

So, one thing you can do is to stop the attract application AND the Surface Shell once the simulator starts. Then run your application from Visual Studio as usual. On a machine with limited resources, especially memory, not running the shell does help. You won’t see any access points and you won’t get all of the functionality the shell provides, but it does seem to work pretty well.

Simulator-without-Shell  
Simulator Running without the Surface Shell

A word of warning though … I wouldn’t consider running the Surface Simulator without the Surface Shell best practice. Sure, it’s fun to live on the edge, but the Surface Shell provides a lot of functionality for you. More importantly, when your application runs on a Surface unit it will be running in the shell. For Surface development I’ve found it better to have my development environment reflect, as closely as possible, my production environment. I usually find bugs quicker that way.

Also, make sure you don’t kill the Surface Input process. Instead of multi-touch you would get no-touch.

Paul Osburn
Engineering Director, Surface

October 14
Starting a Surface App

When a user starts your Surface application from the Launcher, your app has 10 seconds to start up or the Surface Shell will shut it down and let the user know that your application could not be started. This seems reasonable to me as ensuring a great user experience on the Surface is top priority. A fast start is important.

ChristmasTree

By default a SurfaceWindow has the AutoSignalLoadComplete attribute set to true. This means that the Launcher is notified automatically when the window load completes. When the Launcher is notified that the application is loaded, the Launcher loading screen disappears and your app is front and center.

This is fine for a lot of Surface applications but some require a bit more planning. After all, this is the user’s first impression of your application. You’ve got a chance to impress them or disappoint/frustrate them. If your loading sequence is complex it’s best to step back and plan it out. Sketching the flow of the startup sequence on a whiteboard or piece of paper is usually good enough.

StartupWhiteboard

One application we built needed to create a complex 3D object, download map information and retrieve a good amount of other data (text, images, etc.) on startup. The UI was “frozen” while the polygons for the 3D object were being rendered. In our case it made sense to have the Launcher load screen displayed while the object was being created. Once the object was created, however, we were ready to have the user see our app. Once we displayed something to the user the application started retrieving the data it needs. Sometimes that data comes from the Internet, sometimes it comes from a local source.

We needed a bit more control if we wanted to ensure a smooth and cool startup experience. So we set AutoSignalLoadComplete to false:

<s:SurfaceWindow x:Class="MyNamespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="http://schemas.microsoft.com/surface/2008"
    AutoSignalLoadComplete="False">

Doing that means you need to tell the Launcher once (and only once) that your app has finished loading. That’s easy enough. Based on your planning, let the Launcher know your app is finished loading at the right time.

// Let the Launcher know that it can dismiss the loading screen
ApplicationLauncher.SignalApplicationLoadComplete();

While controlling the startup experience is easy, ensuring a good user experience may take a little planning depending on the complexity of your application.

 

Paul Osburn
Engineering Director, Surface

October 13
Circular ScatterViewItems Made Simple

After building Surface applications over the past year we realized that we’ve learned some things along the way. Sharing some of those lessons learned (and documenting them so we can find them later) seemed like the next step. If you can add to or improve upon what we’ll post in the blog, make sure to leave a comment. We like learning new things.

I’m not big on the obligatory ‘first post,’ so I’ll end the introduction there and get right to it.

For one of our projects I needed to create a circular ScatterViewItem that the user could interact with. It should contain everything in it … that is to say, it should clip its contents. A clipping path was the obvious choice.

So I tried using an EllipseGeometry for the clipping path of the ScatterViewItem:

<s:ScatterViewItem Background="DarkMagenta" Width="80" Height="80">
    <s:ScatterViewItem.Clip>
        <EllipseGeometry RadiusX="40" RadiusY="40" Center="40,40"/>
    </s:ScatterViewItem.Clip>
</s:ScatterViewItem>

This works great until you try resizing the item. The clipping geometry doesn’t stay in sync with the ScatterViewItem as the size changes. Makes sense since I’m hard-coding the radius and center values.

Can't Resize Circular ScatterViewItem

As the size of the ScatterViewItem changes we need to update the size and center of the EllipseGeometry. The simplest way I found to do this is to override the GetLayoutClip method for the ScatterViewItem.

protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
    return new EllipseGeometry(
        new Point(layoutSlotSize.Width / 2, layoutSlotSize.Height / 2), 
        layoutSlotSize.Width / 2, 
        layoutSlotSize.Height / 2);
}

Each time the item goes through its layout logic the custom clip will be applied using the current width and height values for the ScatterViewItem. I created a user control and sub-classed the ScatterViewItem. This made it easy to override the GetLayoutClip method.

Using the new custom ScatterViewItem looks like this:

<c:CustomScatterViewItem Background="Chartreuse" Width="80" Height="80"/>

Now I’m able to resize the circular ScatterViewItem and as I resize it, the clipping path is updated as expected. Plus its bright green, which is nice.

A Circular ScatterViewItem you Can Resize!

 

Paul Osburn
Engineering Director, Surface