Gesture Control Integration in the Control Player
authorARIAS Santiago
Mon, 26 Oct 2009 08:36:15 +0100
changeset 173 e99fe78cd168
parent 172 e408e158c1a2
child 174 45c9e55fcf23
Gesture Control Integration in the Control Player
src/FingersDance.Control.Player/FingersDance.Control.Player.csproj
src/FingersDance.Control.Player/UserControlPlayer.xaml
src/FingersDance.Control.Player/UserControlPlayer.xaml.cs
src/FingersDance.sln
src/GestureControl/DoubleHalfConverter.cs
src/GestureControl/GestureControl.cs
src/GestureControl/GestureControl.csproj
src/GestureControl/GestureControl.csproj.vspscc
src/GestureControl/GestureVector.cs
src/GestureControl/Properties/AssemblyInfo.cs
src/GestureControl/Properties/Resources.Designer.cs
src/GestureControl/Properties/Resources.resx
src/GestureControl/Properties/Settings.Designer.cs
src/GestureControl/Properties/Settings.settings
src/GestureControl/Resources/Patterns.xml
src/GestureControl/Themes/Generic.xaml
--- a/src/FingersDance.Control.Player/FingersDance.Control.Player.csproj	Sun Oct 25 19:59:28 2009 +0100
+++ b/src/FingersDance.Control.Player/FingersDance.Control.Player.csproj	Mon Oct 26 08:36:15 2009 +0100
@@ -169,6 +169,10 @@
       <Project>{0B308B6E-7B1E-46C0-ACC7-0B7EFC4D0B2C}</Project>
       <Name>FingersDance.Views</Name>
     </ProjectReference>
+    <ProjectReference Include="..\GestureControl\GestureControl.csproj">
+      <Project>{99A9037F-5431-44DD-BCE9-ED60670DEBC1}</Project>
+      <Name>GestureControl</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
--- a/src/FingersDance.Control.Player/UserControlPlayer.xaml	Sun Oct 25 19:59:28 2009 +0100
+++ b/src/FingersDance.Control.Player/UserControlPlayer.xaml	Mon Oct 26 08:36:15 2009 +0100
@@ -5,9 +5,10 @@
 	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 	mc:Ignorable="d"
 	xmlns:Custom="http://schemas.microsoft.com/surface/2008" xmlns:Microsoft_Surface_Presentation_Generic="clr-namespace:Microsoft.Surface.Presentation.Generic;assembly=Microsoft.Surface.Presentation.Generic"
+	xmlns:FingersDance_Control_Player="clr-namespace:FingersDance.Control.Player"
 	x:Class="FingersDance.Control.Player.UserControlPlayer"
 	x:Name="UserControl" AllowDrop="True" Custom:SurfaceDragDrop.DragOver="Play_Pause_area_DragOver" Custom:SurfaceDragDrop.DragEnter="Play_Pause_area_DragEnter" Custom:SurfaceDragDrop.DragLeave="Play_Pause_area_DragLeave" Custom:SurfaceDragDrop.Drop="Play_Pause_area_Drop"
-	Width="560" Height="400" xmlns:FingersDance_Control_Player="clr-namespace:FingersDance.Control.Player">
+	Width="560" Height="400" xmlns:GestureControl="clr-namespace:GestureControl;assembly=GestureControl">
 	<UserControl.Resources>
 		<Storyboard x:Key="OnClick1"/>
 		<Style x:Key="FingersDance.Control.PlayerButton" TargetType="{x:Type Custom:SurfaceButton}">
@@ -165,29 +166,31 @@
     	<Viewbox Margin="0,0,0,0" Width="{Binding Path=ActualWidth, ElementName=UserControl, Mode=Default}" Height="{Binding Path=ActualHeight, ElementName=UserControl, Mode=Default}" Stretch="Uniform" AllowDrop="True">
     		<Grid Width="560" Height="400" HorizontalAlignment="Left" x:Name="GridPlayer">
     			<Grid.RowDefinitions>
-    				<RowDefinition Height="0.898*"/>
+    				<RowDefinition Height="0.305*"/>
+    				<RowDefinition Height="0.593*"/>
     				<RowDefinition Height="0.102*"/>
     			</Grid.RowDefinitions>
     			<Grid.ColumnDefinitions>
     				<ColumnDefinition Width="0.912*"/>
     				<ColumnDefinition Width="0.088*"/>
     			</Grid.ColumnDefinitions>
-    			<FingersDance_Control_Player:UserControlInfoUser Margin="0,-4.398,0,7.398" x:Name="usercontrolInfoUser" Grid.ColumnSpan="1" Grid.Row="1" Height="30"/>
-    			<MediaElement x:Name="MediaElementVideo" MediaOpened="MediaElementVideo_MediaOpened" Stretch="Fill" ScrubbingEnabled="False" StretchDirection="Both" />
+    			<FingersDance_Control_Player:UserControlInfoUser Margin="0,-0.498,0,11.298" x:Name="usercontrolInfoUser" Grid.ColumnSpan="1" Grid.Row="2" Height="30"/>
+    			<MediaElement x:Name="MediaElementVideo" MediaOpened="MediaElementVideo_MediaOpened" Stretch="Fill" ScrubbingEnabled="False" StretchDirection="Both" Grid.RowSpan="2" />
     			<Custom:SurfaceButton x:Name="Rewind_area" Content="" ContactDown="ButtonRewind_ContactDown" 
                                       Click="ButtonRewind_Click" Foreground="{x:Null}" Background="#FFFFFFFF" BorderBrush="{x:Null}" 
-                                      Opacity="0" Style="{DynamicResource FingersDance.Control.PlayerButton}" HorizontalAlignment="Left" Width="72"/>
+                                      Opacity="0" Style="{DynamicResource FingersDance.Control.PlayerButton}" HorizontalAlignment="Left" Width="72" Grid.RowSpan="1"/>
     			<Custom:SurfaceButton x:Name="Fast_Forward_area" Content="" ContactDown="ButtonFastForward_ContactDown" Click="ButtonFastForward_Click" 
                                       Foreground="{x:Null}" Background="#FFFFFFFF" BorderBrush="{x:Null}" Opacity="0" 
-                                      Style="{DynamicResource FingersDance.Control.PlayerButton}" HorizontalAlignment="Right" Width="72"/>
+                                      Style="{DynamicResource FingersDance.Control.PlayerButton}" HorizontalAlignment="Right" Width="72" Grid.RowSpan="1"/>
     			<Custom:SurfaceButton x:Name="Play_Pause_area" ContactDown="ButtonPlayPause_ContactDown" Click="ButtonPlayPause_Click" Foreground="{x:Null}" 
-                                      Background="#FFFFFFFF" BorderBrush="{x:Null}" Style="{DynamicResource FingersDance.Control.PlayerButton}" Opacity="0" Margin="72,0,72,0"/>
-    			<StackPanel Opacity="1" Background="{x:Null}" x:Name="StackPanelAnnotation" Height="Auto" d:LayoutOverrides="Height" Margin="-1,-159.4,0,0" Grid.Column="1" Grid.Row="1" Grid.RowSpan="1">
+                                      Background="#FFFFFFFF" BorderBrush="{x:Null}" Style="{DynamicResource FingersDance.Control.PlayerButton}" Opacity="0" Margin="72,0,72,0" Grid.RowSpan="1"/>
+    			<StackPanel Opacity="1" Background="{x:Null}" x:Name="StackPanelAnnotation" Height="Auto" d:LayoutOverrides="Height" Margin="-1,77.8,0,0" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2">
     				<Rectangle x:Name="rect1" Width="50" Height="50" Fill="{x:Null}" Stroke="#FF000000"/>
     				<Rectangle x:Name="rect2" Width="50" Height="50" Fill="{x:Null}" Stroke="#FF000000"/>
     				<Rectangle x:Name="rect3" Width="50" Height="50" Fill="{x:Null}" Stroke="#FF000000"/>
     				<Rectangle x:Name="rect4" Width="50" Height="50" Fill="{x:Null}" Stroke="#FF000000" VerticalAlignment="Bottom"/>
     			</StackPanel>
+    			<GestureControl:GestureControl HorizontalAlignment="Stretch" x:Name="gestureControl" VerticalAlignment="Stretch" Content="" Grid.Row="1"/>
     		</Grid>
     	</Viewbox>
     </Grid>
--- a/src/FingersDance.Control.Player/UserControlPlayer.xaml.cs	Sun Oct 25 19:59:28 2009 +0100
+++ b/src/FingersDance.Control.Player/UserControlPlayer.xaml.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -37,8 +37,12 @@
             this.InitializeComponent();
             MediaElementVideo.LoadedBehavior = MediaState.Manual;
             MediaElementVideo.UnloadedBehavior = MediaState.Manual;
+            //SAR
+            //Control User Info
             usercontrolInfoUser.LabelSession.Content = "Seance Test";
             usercontrolInfoUser.LabelUser.Content = "User Test";
+            //Gesture Control
+            gestureControl.GestureEvent+= new GestureControl.GestureControl.GestureRoutedEventHandler(GestureDetected);
         }
         #endregion
 
@@ -97,7 +101,33 @@
         
         #endregion
 
-        
+        #region GestureEvents
+
+        public void GestureDetected(object sender, GestureControl.GestureRoutedEventArgs e)
+        {
+            Console.WriteLine("gesture detected: " + e.Gesture);
+            switch (e.Gesture)
+            {
+                case "UP":
+                    //
+                    usercontrolInfoUser.LabelSession.Content = "UP!";
+                    break;
+                case "LEFT":
+                    usercontrolInfoUser.LabelSession.Content = "LEFT!";
+                    break;
+                case "RIGHT":
+                    usercontrolInfoUser.LabelSession.Content = "RIGHT!";
+                    break;
+                case "DOWN":
+                    usercontrolInfoUser.LabelSession.Content = "DOWN!";
+                    break;
+                default:
+                    //this.TxtGesture.Text = e.Gesture;
+                    break;
+            }
+        }
+        #endregion
+
         #region Button Simple Player Actions
         private void ButtonPlayPause_ContactDown(object sender, Microsoft.Surface.Presentation.ContactEventArgs e)
         {
--- a/src/FingersDance.sln	Sun Oct 25 19:59:28 2009 +0100
+++ b/src/FingersDance.sln	Mon Oct 26 08:36:15 2009 +0100
@@ -39,6 +39,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FingersDance.Control.Close", "FingersDance.Control.Close\FingersDance.Control.Close.csproj", "{D579FDB5-D412-4797-A0FF-C5873AE08BB8}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GestureControl", "GestureControl\GestureControl.csproj", "{99A9037F-5431-44DD-BCE9-ED60670DEBC1}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -189,6 +191,12 @@
 		{D579FDB5-D412-4797-A0FF-C5873AE08BB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D579FDB5-D412-4797-A0FF-C5873AE08BB8}.Release|Any CPU.Build.0 = Release|Any CPU
 		{D579FDB5-D412-4797-A0FF-C5873AE08BB8}.Release|x86.ActiveCfg = Release|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{99A9037F-5431-44DD-BCE9-ED60670DEBC1}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/DoubleHalfConverter.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Data;
+
+namespace GestureControl
+{
+    class DoubleHalfConverter : IValueConverter
+    {
+        #region IValueConverter Members
+
+        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            return (double)((double)value / 1.5);
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+
+        #endregion
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/GestureControl.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Diagnostics;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Animation;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Microsoft.Surface;
+using Microsoft.Surface.Presentation;
+using Microsoft.Surface.Presentation.Controls;
+using System.Windows.Ink;
+
+namespace GestureControl
+{
+    public class GestureControl : ContentControl
+    {
+        private double angle = 0;
+        public static readonly DependencyProperty GestureProperty;
+        public String Gesture
+        {
+            get { return (String)GetValue(GestureControl.GestureProperty); }
+            set { SetValue(GestureControl.GestureProperty, value); }
+        }
+
+        #region GestureEvent
+        public delegate void GestureRoutedEventHandler(object sender, GestureRoutedEventArgs e);
+        public static readonly RoutedEvent gestureEvent = EventManager.RegisterRoutedEvent(
+            "GestureEvent", RoutingStrategy.Bubble, typeof(GestureRoutedEventHandler), typeof(GestureControl));
+
+        public event GestureRoutedEventHandler GestureEvent
+        {
+            add { AddHandler(gestureEvent, value); }
+            remove { RemoveHandler(gestureEvent, value); }
+        }
+        protected virtual void RaiseGestureEvent(String gesture)
+        {
+            try
+            {
+                GestureRoutedEventArgs newEventArgs = new GestureRoutedEventArgs(GestureControl.gestureEvent, gesture);
+                RaiseEvent(newEventArgs);
+            }
+            catch (Exception e) { }
+        }
+        #endregion
+
+        static GestureControl()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(GestureControl), new FrameworkPropertyMetadata(typeof(GestureControl)));
+
+            GestureControl.GestureProperty = DependencyProperty.Register("Gesture", typeof(String), typeof(GestureControl),
+                    new FrameworkPropertyMetadata("None", new PropertyChangedCallback(OnGestureChanged)));
+        }
+        private static void OnGestureChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
+        {
+            //Debug.WriteLine("changed", "Gesture");
+        }
+
+        protected override void OnInitialized(EventArgs e)
+        {
+            base.OnInitialized(e);
+            this.InitializeControl();
+        }
+        protected void InitializeControl()
+        {
+           base.AddHandler(SurfaceControl.PreviewContactDownEvent, new RoutedEventHandler(AreaDown));
+           base.AddHandler(SurfaceInkCanvas.StrokeCollectedEvent, new RoutedEventHandler(AreaStrokeCollected));
+        }
+        // get angle from the first contact of the stroke
+        protected void AreaDown(object source, RoutedEventArgs e)
+        {
+            ContactEventArgs c = (ContactEventArgs)e;
+            this.angle = c.Contact.GetOrientation(this) - 270;
+        }
+
+        protected void AreaStrokeCollected(object source, RoutedEventArgs e)
+        {
+            Debug.WriteLine("collected", "Stroke");
+            System.Windows.Controls.InkCanvasStrokeCollectedEventArgs tmp = e as System.Windows.Controls.InkCanvasStrokeCollectedEventArgs;
+            // Apply a rotation with the angle of the first contact
+            Matrix rot = Matrix.Identity;
+            rot.Rotate(-this.angle);
+            Stroke s = tmp.Stroke;
+            s.Transform(rot, true);
+            // Get a list of point from a Bezier curve
+            StylusPointCollection tmp2 = s.GetBezierStylusPoints();
+            // Generate a list of SurfaceGesturePoint, just X and Y but can be improve
+            List<SurfaceGesturePoint> pointList = new List<SurfaceGesturePoint>();
+            foreach (StylusPoint p in tmp2)
+                pointList.Add(new SurfaceGesturePoint { X = p.X, Y = p.Y });
+            // create the gesture analyser and set the list
+            SurfaceGesture gesture = new SurfaceGesture(pointList, 1);
+            // try to get a pattern from the list, if one, raise a event
+            this.Gesture = gesture.GetPattern();
+            if (this.Gesture != "None")
+            {
+                this.RaiseGestureEvent(this.Gesture);
+            }
+            // clear the stroke
+            SurfaceInkCanvas ink = e.OriginalSource as SurfaceInkCanvas;
+            ink.Strokes.Clear();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/GestureControl.csproj	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{99A9037F-5431-44DD-BCE9-ED60670DEBC1}</ProjectGuid>
+    <OutputType>library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>GestureControl</RootNamespace>
+    <AssemblyName>GestureControl</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <ExpressionBlendVersion>3.0.1927.0</ExpressionBlendVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Surface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="Microsoft.Surface.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="Microsoft.Surface.Presentation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="Microsoft.Surface.Presentation.Generic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="UIAutomationProvider">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="PresentationCore">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="PresentationFramework">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="Themes\Generic.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="GestureControl.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DoubleHalfConverter.cs" />
+    <Compile Include="GestureVector.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources\Patterns.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/GestureControl.csproj.vspscc	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/GestureVector.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,380 @@
+using System;
+using System.IO;
+using System.Xml;
+using System.Reflection;
+using System.Xml.Linq;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Input;
+using System.Windows;
+
+namespace GestureControl
+{
+    /// <summary>
+    /// Take a list of points and try to recognize a pattern
+    /// </summary>
+    public class SurfaceGesture : List<SurfaceGestureVector>
+    {
+
+        #region Prop
+        /// <summary>
+        /// Allow some variation without log a direction
+        /// </summary>
+        public int Precision { get; set; }
+        /// <summary>
+        /// List of pattern readed in the patterns.xml
+        /// </summary>
+        public List<SurfaceGesturePattern> Pattern = new List<SurfaceGesturePattern>();
+        #endregion
+        #region Constructor
+        /// <summary>
+        /// load know patterns and generate the vector list from a list of points with a default 20 precision factor
+        /// </summary>
+        /// <param name="list"></param>
+        public SurfaceGesture(List<SurfaceGesturePoint> list)
+        {
+            this.Precision = 20;
+            CommonPattern();
+            this.Generate(list);
+        }
+        /// <summary>
+        /// load know patterns and generate the vector list from a list of points with a precision factor
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="precision"></param>
+        public SurfaceGesture(List<SurfaceGesturePoint> list, int precision)
+        {
+            this.Precision = precision;
+            CommonPattern();
+            this.Generate(list);
+        }
+        //public SurfaceGesture(System.Windows.Ink.Stroke stroke, int precision)
+        //{
+        //    StylusPointCollection tmp = stroke.GetBezierStylusPoints();
+        //    List<SurfaceGesturePoint> pointList = new List<SurfaceGesturePoint>();
+        //    foreach (StylusPoint p in tmp)
+        //        pointList.Add(new SurfaceGesturePoint { X = p.X, Y = p.Y });
+        //    this.Precision = precision;
+        //    this.Generate(pointList);
+        //    CommonPattern();
+        //}
+        #endregion
+        #region GenerateVector
+        /// <summary>
+        /// Generate list of vector from courbe mouvements, filter with the pas value
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="pas"></param>
+        /// <returns></returns>
+        private bool GenerateCourb(List<SurfaceGesturePoint> list, int pas)
+        {
+            List<SurfaceGesturePattern> tmp = new List<SurfaceGesturePattern>();
+            int sep = list.Count / pas;
+            double count = 0; ;
+            SurfaceGesturePoint past = new SurfaceGesturePoint() { X = 0, Y = 0 };
+            double y = 0;
+
+            for (int i = 0; i < list.Count - 1; i++)
+            {
+                if (i % pas != 0)
+                {
+                    count += Math.Atan(list[i + 1].Y / list[i + 1].X) - Math.Atan(list[i].Y / list[i].X);
+                }
+                else
+                {
+                    count /= pas;
+                    if (count == 0 || this.GetDistancePoints(past, list[i + 1]) < 5)
+                    {
+                        y = list[i + 1].Y;
+                        past.X = count;
+                        continue;
+                    }
+                    if (y > list[i + 1].Y)
+                    {
+                        if (past.X > count)
+                            this.AddDirection(SurfaceGestureVectorDirection.UPRIGHT);
+                        else
+                            this.AddDirection(SurfaceGestureVectorDirection.UPLEFT);
+                    }
+                    else
+                    {
+                        if (past.X > count)
+                            this.AddDirection(SurfaceGestureVectorDirection.DOWNRIGHT);
+                        else
+                            this.AddDirection(SurfaceGestureVectorDirection.DOWNLEFT);
+                    }
+                    y = list[i + 1].Y;
+                    past.X = count;
+                }
+            }
+            Console.Write(this);
+            if (this.GetPattern() != "None")
+                return true;
+            else
+                return false;
+        }
+        /// <summary>
+        /// Get distance between two points
+        /// </summary>
+        /// <param name="p1"></param>
+        /// <param name="p2"></param>
+        /// <returns></returns>
+        private int GetDistancePoints(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
+        {
+            return (int)Math.Sqrt(Math.Pow((p2.X - p1.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
+        }
+        /// <summary>
+        /// add a direction in the vector list if past who not the same
+        /// </summary>
+        /// <param name="type"></param>
+        private void AddDirection(SurfaceGestureVectorDirection type)
+        {
+            if (this.Count == 0)
+            {
+                this.Add(new SurfaceGestureVector{Direction = type, Lenght=42});
+                return ;
+            }
+            if (this[this.Count - 1].Direction != type)
+                this.Add(new SurfaceGestureVector { Direction = type, Lenght = 42 });
+        }
+        /// <summary>
+        /// generate list of vector
+        /// </summary>
+        /// <param name="list"></param>
+        private void Generate(List<SurfaceGesturePoint> list)
+        {
+            if (list.Count < 2)
+                return ;
+            SurfaceGestureVectorDirection lastDirection = SurfaceGestureVectorDirection.NONE;
+            int lastPoint = 0;
+            SurfaceGesturePoint LastChange = list[0];
+
+            /////// TEST///////////
+            if (this.GenerateCourb(list, 5) == true)
+                return;
+            this.Clear();
+            ///////////////////////
+
+            for (int i = 0; i < list.Count - 1; i++)
+            {
+                if (GetHorizontal(list[lastPoint], list[i + 1]) == SurfaceGestureVectorDirection.UP && lastDirection != SurfaceGestureVectorDirection.UP)
+                {
+                    this.Add(new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.UP, Lenght = (Math.Abs(LastChange.Y - list[i + 1].Y)) });
+                    LastChange = list[i + 1];
+                    lastDirection = SurfaceGestureVectorDirection.UP;
+                }
+                else if (GetHorizontal(list[lastPoint], list[i + 1]) == SurfaceGestureVectorDirection.DOWN && lastDirection != SurfaceGestureVectorDirection.DOWN)
+                {
+                    this.Add(new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.DOWN, Lenght = (Math.Abs(LastChange.Y - list[i + 1].Y)) });
+                    LastChange = list[i + 1];
+                    lastDirection = SurfaceGestureVectorDirection.DOWN;
+                }
+                else if (GetVertical(list[lastPoint], list[i + 1]) == SurfaceGestureVectorDirection.LEFT && lastDirection != SurfaceGestureVectorDirection.LEFT)
+                {
+                    this.Add(new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.LEFT, Lenght = (Math.Abs(LastChange.X - list[i + 1].X)) });
+                    LastChange = list[i + 1];
+                    lastDirection = SurfaceGestureVectorDirection.LEFT;
+                }
+                else if (GetVertical(list[lastPoint], list[i + 1]) == SurfaceGestureVectorDirection.RIGHT && lastDirection != SurfaceGestureVectorDirection.RIGHT)
+                {
+                    this.Add(new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.RIGHT, Lenght = (Math.Abs(LastChange.X - list[i + 1].X)) });
+                    LastChange = list[i + 1];
+                    lastDirection = SurfaceGestureVectorDirection.RIGHT;
+                }
+                ++lastPoint;
+            }
+        }
+        private SurfaceGestureVectorDirection GetHorizontal(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
+        {
+            if (p1.Y < p2.Y)
+            {
+                // go up
+                if (Math.Abs(p2.Y - p1.Y) > this.Precision && Math.Abs(p2.X - p1.X) < Math.Abs(p2.Y - p1.Y))
+                    return SurfaceGestureVectorDirection.DOWN;
+            }
+            else
+            {
+                // go down
+                if (Math.Abs(p1.Y - p2.Y) > this.Precision && Math.Abs(p1.X - p2.X) < Math.Abs(p1.Y - p2.Y))
+                    return SurfaceGestureVectorDirection.UP;
+            }
+            return SurfaceGestureVectorDirection.NONE;
+        }
+        private SurfaceGestureVectorDirection GetVertical(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
+        {
+            if (p1.X < p2.X)
+            {
+                // go left
+                if (Math.Abs(p2.X - p1.X) > this.Precision && Math.Abs(p2.Y - p1.Y) < Math.Abs(p2.X - p1.X))
+                    return SurfaceGestureVectorDirection.RIGHT;
+            }
+            else
+            {
+                // go right
+                if (Math.Abs(p1.X - p2.X) > this.Precision && Math.Abs(p1.Y - p2.Y) < Math.Abs(p1.X - p2.X))
+                    return SurfaceGestureVectorDirection.LEFT;
+            }
+            return SurfaceGestureVectorDirection.NONE;
+        }
+        #endregion
+        #region Override
+        public override String ToString()
+        {
+            String ret = "";
+
+            foreach (SurfaceGestureVector v in this)
+            {
+                ret += (v.Direction + ", lenght:" + v.Lenght + ", precision:" + this.Precision + "\n");
+                //Console.WriteLine(v.Direction + ", lenght:" + v.Lenght + ", precision:" + this.Precision);
+            }
+            return ret;
+        }
+        #endregion
+        #region Pattern
+        /// <summary>
+        /// return a String with the recognized pattern, "None" if no pattern
+        /// </summary>
+        /// <returns></returns>
+        public String GetPattern()
+        {
+            foreach (SurfaceGesturePattern p in this.Pattern)
+            {
+                if (p.Count == this.Count)
+                {
+                    int i;
+                    for (i = 0; i < p.Count; i++)
+                    {
+                        if (this[i].Direction != p[i].Direction)
+                            break ;
+                    }
+                    if (i == p.Count)
+                        return p.Name;
+                }
+            }
+            return "None";
+        }
+        /// <summary>
+        /// Load know patterns from the Resources/Patterns.xml file
+        /// </summary>
+        private void CommonPattern()
+        {
+            try
+            {
+                #region Load Patterns
+                System.IO.Stream file = Assembly.GetExecutingAssembly().GetManifestResourceStream("GestureControl.Resources.Patterns.xml");
+                XmlDocument xml = new XmlDocument();
+                xml.Load(file);
+                XmlElement root = xml.DocumentElement;
+                XmlNodeList nodes = root.SelectNodes("//Pattern");
+                SurfaceGesturePattern p;
+                int i = 0;
+                foreach (XmlNode node in nodes)
+                {
+                    string name = node["Name"].InnerText;
+                    XmlNodeList subNodes = node.SelectNodes("//Directions");
+                    if (subNodes == null)
+                        continue;
+                    p = new SurfaceGesturePattern() { Name = name };
+                    foreach (XmlNode subNode in subNodes[i++])
+                    {
+                        XmlNodeList dl = subNode.ChildNodes;
+                        foreach (XmlNode d in dl)
+                        {
+                            switch (d.InnerText)
+                            {
+                                case "Up":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.UP });
+                                    break;
+                                case "Down":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.DOWN });
+                                    break;
+                                case "Left":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.LEFT });
+                                    break;
+                                case "Right":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.RIGHT });
+                                    break;
+                                case "DownRight":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.DOWNRIGHT });
+                                    break;
+                                case "DownLeft":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.DOWNLEFT });
+                                    break;
+                                case "UpRight":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.UPRIGHT });
+                                    break;
+                                case "UpLeft":
+                                    p.Add(new SurfaceGestureVector() { Direction = SurfaceGestureVectorDirection.UPLEFT });
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }
+                    }
+                    this.Pattern.Add(p);
+                }
+                #endregion
+            }
+            catch
+            {
+                throw new Exception("Error loading Patterns.xml");
+            }
+        }
+        #endregion
+    }
+    #region Tools
+    /// <summary>
+    /// Gesture event who return a object with a Gesture String value
+    /// </summary>
+    public class GestureRoutedEventArgs : RoutedEventArgs
+    {
+        public String Gesture { get; private set; }
+            
+        public GestureRoutedEventArgs() : base() { }
+        public GestureRoutedEventArgs(String gesture) : base() { this.Gesture = gesture; }
+        public GestureRoutedEventArgs(RoutedEvent routedEvent) : base(routedEvent) { }
+        public GestureRoutedEventArgs(RoutedEvent routedEvent, String gesture) : base(routedEvent) { this.Gesture = gesture; }
+        public GestureRoutedEventArgs(RoutedEvent routedEvent, Object source) : base(routedEvent, source) { }
+        public GestureRoutedEventArgs(RoutedEvent routedEvent, Object source, String gesture) : base(routedEvent, source) { this.Gesture = gesture; }
+    }
+
+    public class SurfaceGesturePattern : List<SurfaceGestureVector>
+    {
+        public String Name { get; set; }
+
+    }
+    /// <summary>
+    /// Possible Gesture Vector
+    /// </summary>
+    public enum SurfaceGestureVectorDirection
+    {
+        UP,
+        DOWN,
+        LEFT,
+        RIGHT,
+        UPLEFT,
+        UPRIGHT,
+        DOWNLEFT,
+        DOWNRIGHT,
+        NONE,
+    }
+    /// <summary>
+    /// Describe a point in the grid
+    /// </summary>
+    public class SurfaceGesturePoint
+    {
+        public double X { get; set; }
+        public double Y { get; set; }
+    }
+
+    /// <summary>
+    /// Describe a vector to help the recognize pass
+    /// </summary>
+    public class SurfaceGestureVector
+    {
+        public SurfaceGestureVectorDirection Direction { get; set; }
+        public Double Lenght { get; set; }
+    }
+    #endregion
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Properties/AssemblyInfo.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GestureControl")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft IT")]
+[assembly: AssemblyProduct("GestureControl")]
+[assembly: AssemblyCopyright("Copyright © Microsoft IT 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set 
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>.  For example, if you are using US english
+//in your source files, set the <UICulture> to en-US.  Then uncomment
+//the NeutralResourceLanguage attribute below.  Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+    //(used if a resource is not found in the page, 
+    // or application resource dictionaries)
+    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+    //(used if a resource is not found in the page, 
+    // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Properties/Resources.Designer.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Ce code a été généré par un outil.
+//     Version du runtime :2.0.50727.4927
+//
+//     Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
+//     le code est régénéré.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace GestureControl.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
+    /// </summary>
+    // Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
+    // à l'aide d'un outil, tel que ResGen ou Visual Studio.
+    // Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
+    // avec l'option /str ou régénérez votre projet VS.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GestureControl.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Remplace la propriété CurrentUICulture du thread actuel pour toutes
+        ///   les recherches de ressources à l'aide de cette classe de ressource fortement typée.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Properties/Resources.resx	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Properties/Settings.Designer.cs	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Ce code a été généré par un outil.
+//     Version du runtime :2.0.50727.4927
+//
+//     Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
+//     le code est régénéré.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace GestureControl.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Properties/Settings.settings	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Resources/Patterns.xml	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<Patterns>
+  <Pattern>
+    <Name>UP</Name>
+    <Directions>
+      <Direction>Up</Direction>
+    </Directions>
+  </Pattern>
+  <Pattern>
+    <Name>RIGHT</Name>
+    <Directions>
+      <Direction>Right</Direction>
+    </Directions>
+  </Pattern>
+  <Pattern>
+    <Name>LEFT</Name>
+    <Directions>
+      <Direction>Left</Direction>
+    </Directions>
+  </Pattern>
+  <Pattern>
+    <Name>DOWN</Name>
+    <Directions>
+      <Direction>Down</Direction>
+    </Directions>
+  </Pattern>
+</Patterns>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GestureControl/Themes/Generic.xaml	Mon Oct 26 08:36:15 2009 +0100
@@ -0,0 +1,33 @@
+<ResourceDictionary
+    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"
+    xmlns:local="clr-namespace:GestureControl">
+    
+    <local:DoubleHalfConverter x:Key="DoubleHalfConverter" />
+    
+    <Style TargetType="{x:Type local:GestureControl}">
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="{x:Type local:GestureControl}">
+                    <Border Background="Transparent"
+                            BorderBrush="{TemplateBinding BorderBrush}"
+                            Width="{Binding ElementName=CC,Path=ActualWidth}"
+                            Height="{Binding ElementName=CC,Path=ActualHeight}">
+                            <!-- BorderThickness="{TemplateBinding BorderThickness}">  -->
+                        <Grid>
+                            <ContentControl x:Name="CC" BorderBrush="red" BorderThickness="3" Content="{TemplateBinding Content}"></ContentControl>
+                           <s:SurfaceInkCanvas Width="{Binding ElementName=CC,Path=ActualWidth,Converter={StaticResource DoubleHalfConverter}}" Height="{Binding ElementName=CC,Path=ActualHeight,Converter={StaticResource DoubleHalfConverter}}" x:Name="InkArea">
+                                <s:SurfaceInkCanvas.DefaultDrawingAttributes >
+                                    <DrawingAttributes 
+                                    Color = "Blue" Width = "4" />
+                                </s:SurfaceInkCanvas.DefaultDrawingAttributes>
+                            </s:SurfaceInkCanvas>
+                            <!-- <s:SurfaceTextBox Width="100" Height="50" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Gesture}" /> -->
+                        </Grid>
+                    </Border>  
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+</ResourceDictionary>