Coming to the Surface

In my last blog entry I posted a link to the Surface Session in PDC : https://channel9.msdn.com/pdc2008/PC17/

This post is just to summarize some of the points with developing on surface.

Porting a WPF application to Surface

1) Add Reference to Surface assembly (Microsoft.Surface.Presentation)

Add the XML Namespace to the XAML file: https://schemas.microsoft.com/surface/2008

 <Window x:Class="PhotoDemo.Window1"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:s="https://schemas.microsoft.com/surface/2008"

2) Replace the controls with s:Surface.<control>

WPF Surface
 Window
 s:Surface.Window
 Button
 s:Surface.Button
 ScrollViewer
 s:Surface.ScrollViewer
 ListBox
 s:Surface.ListBox

The only problem with this is that the application will still be displayed one way, and not give the 360 feel users would expect with a surface. This is where the ScatterView control comes in.

ScatterView

To create a ScatterView around a control simply surround it with the tag:

 <s:ScatterView>

The ScatterView contains ItemTemplates, which can bind to a DataTemplate.

e.g. for a ScatterView of Images:

 <s:ScatterView Name="Scatter">
  <s:ScatterView.ItemTemplate>
    <DataTemplate>
      <Image Source="{Binding}"/>
    </DataTemplate>
  </s:ScatterView.ItemTemplate>
</s:ScatterView>

then in the code after InitializeComponent(); populate the items source (sample pictures):

 public Window1()
{
  InitializeComponent();
  Scatter.ItemsSource = System.IO.Directory.GetFiles(@"c:\users\public\pictures\sample pictures", "*.jpg"); 
  AddActivationHandlers();
}

Compile, and you should see some pictures which you can move around the surface, resize and rotate.

ScatterView Additional Properties

The items within ScatterView have some additional properties:

 CanScale (Boolean)
CanRotate (Boolean)

DecelerationRate (Double)

These are mostly obvious (i.e. CanScale means the user is able to enlarge and reduce the controls by dragging in opposite directions with fingers, CanRotate means the user is able to turn controls by moving fingers around in a circular motion, and DecelerationRate is how much “friction” there is on the surface when a control is thrown.

 <s:ScatterView>
  <s:ScatterView.ItemTemplate>
    <Style TargetType="{x:Type s:ScatterViewItem}">
      <Setter Property="CanScale" 
              Value="{Binding ElementName=scale, Path=IsChecked}" />
      <Setter Property="CanRotate" 
              Value="{Binding ElementName=rotate, Path=IsChecked}" />
      <Setter Property="CanScale" 
              Value="{Binding ElementName=decel, Value}" />
    </Style>
</s:ScatterView>
<StackPanel Width="200" Height="120" Background="Gray">
  <s:SurfaceCheckBox Name="scale" IsChecked="True" FontSize="20">
    CanScale
  </s:SurfaceCheckBox>
  <s:SurfaceCheckBox Name="rotate" IsChecked="True" FontSize="20">
    CanRotate
  </s:SurfaceCheckBox>
  <Label FontSize="20">Deceleration Rate:</Label>
  <s:SurfaceSlider Name="decel" Minimum="1" Maximum="6000" />
</StackPanel>

The Minimum and Maximum values are in device independent pixels per second per second (i.e. lower number is slippery, higher is rougher)

Tagged Objects

The final part of this session was for recognizing when objects are put onto the surface.  The items should have a tag either

 Contact.Tag.Byte

or

 Contact.Tag.Identity

The Byte tag contains 256 different ID’s, whereas the Identity Tag allows 340,282,366,920,938,000,000,000,000,000,000,000,000 different ID’s

These not only recognise a specific object, but also the position and orientation of the object.

You can create custom controls or TagVisualizer which allows custom UI’s for each Tag recognised, how to handle the object being removed form the surface.

 <s:TagVisualizer>

To allocate this with a tag

 <s:TagVisualizer>
  <s:TagVisualizer.Definitions>
    <s:ByteTagVisualizationDefination
      Source="<xaml file for Visualization>"
      Value="<Value written on the tag, example hex>0x40"
      PhysicalCenterOffsetFromTag="<x,y values of center offset between object and Visualization> e.g. -.23,-.4"
      OrientationOffsetFromTag="<Rotational offset between tag on object and Visualization (may be measured clockwise in degrees)>e.g. 266" />
  </s:TagVisualizer.Definitions>
</s:TagVisualizer>

I’ll look forward to playing around with this some more in the future (fingers crossed)

Comments

  • Anonymous
    November 11, 2008
    PingBack from http://www.tmao.info/coming-to-the-surface/

  • Anonymous
    April 28, 2009
    I have a special scenario where the scatter view should scatter the items around the center of it. There should be no items floating around at the corners of scatter view.This is at the initial stage.But user can drag items to any side after loading. Is there something called ScatterCenter which specifies a point where the concentration of items is more... Thanks in advance Joy

  • Anonymous
    November 18, 2009
    Nice article, but can you digg deeper into the situation in which you have a organisation using bussiness cards with ByteTags? How can one approach the automatisation of usage of 200 tags in a application ?