Gesture Control
authorPAMPHILE Jonathan <pamphile@efrei.fr>
Mon, 26 Oct 2009 09:27:23 +0100
changeset 174 45c9e55fcf23
parent 173 e99fe78cd168
child 175 1d4b6d6474d5
Gesture Control
src/FingersDance.Control.Player/FingersDance.Control.Player.csproj
src/FingersDance.Control.Player/UserControlPlayer.xaml
src/FingersDance.Control.Player/UserControlPlayer.xaml.cs
src/FingersDance.Control.SyncSource/UserControlSyncSource.xaml
src/FingersDance.GestureControl/DoubleHalfConverter.cs
src/FingersDance.GestureControl/GestureControl.cs
src/FingersDance.GestureControl/GestureControl.csproj
src/FingersDance.GestureControl/GestureControl.csproj.vspscc
src/FingersDance.GestureControl/GestureVector.cs
src/FingersDance.GestureControl/Properties/AssemblyInfo.cs
src/FingersDance.GestureControl/Properties/Resources.Designer.cs
src/FingersDance.GestureControl/Properties/Resources.resx
src/FingersDance.GestureControl/Properties/Settings.Designer.cs
src/FingersDance.GestureControl/Properties/Settings.settings
src/FingersDance.GestureControl/Resources/Patterns.xml
src/FingersDance.GestureControl/Themes/Generic.xaml
src/FingersDance.GestureControl/UserGestureControl.xaml
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	Mon Oct 26 08:36:15 2009 +0100
+++ b/src/FingersDance.Control.Player/FingersDance.Control.Player.csproj	Mon Oct 26 09:27:23 2009 +0100
@@ -161,6 +161,10 @@
       <Project>{2BCEE1BF-D3AC-478C-A26B-DFDB7420E965}</Project>
       <Name>FingersDance.Control.TimeLine</Name>
     </ProjectReference>
+    <ProjectReference Include="..\FingersDance.GestureControl\GestureControl.csproj">
+      <Project>{99A9037F-5431-44DD-BCE9-ED60670DEBC1}</Project>
+      <Name>GestureControl</Name>
+    </ProjectReference>
     <ProjectReference Include="..\FingersDance.ViewModel\FingersDance.ViewModels.csproj">
       <Project>{E81BB080-0598-43AC-90CE-54D6570C4E9E}</Project>
       <Name>FingersDance.ViewModels</Name>
@@ -169,10 +173,6 @@
       <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	Mon Oct 26 08:36:15 2009 +0100
+++ b/src/FingersDance.Control.Player/UserControlPlayer.xaml	Mon Oct 26 09:27:23 2009 +0100
@@ -8,7 +8,8 @@
 	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:GestureControl="clr-namespace:GestureControl;assembly=GestureControl">
+	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}">
@@ -190,7 +191,7 @@
     				<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"/>
+    			<GestureControl:GestureControl HorizontalAlignment="Stretch" x:Name="gestureControl" VerticalAlignment="Stretch" Content="" Grid.Row="1" GestureEvent="GestureDetected"/>
     		</Grid>
     	</Viewbox>
     </Grid>
--- a/src/FingersDance.Control.Player/UserControlPlayer.xaml.cs	Mon Oct 26 08:36:15 2009 +0100
+++ b/src/FingersDance.Control.Player/UserControlPlayer.xaml.cs	Mon Oct 26 09:27:23 2009 +0100
@@ -19,6 +19,7 @@
 using FingersDance.Control.TimeLine;
 using FingersDance.Views;
 using FingersDance.ViewModels;
+using GestureControl;
 
 namespace FingersDance.Control.Player
 {
@@ -41,12 +42,10 @@
             //Control User Info
             usercontrolInfoUser.LabelSession.Content = "Seance Test";
             usercontrolInfoUser.LabelUser.Content = "User Test";
-            //Gesture Control
-            gestureControl.GestureEvent+= new GestureControl.GestureControl.GestureRoutedEventHandler(GestureDetected);
         }
+
         #endregion
 
-
         #region Properties
         public double TotalMilliseconds
         {
--- a/src/FingersDance.Control.SyncSource/UserControlSyncSource.xaml	Mon Oct 26 08:36:15 2009 +0100
+++ b/src/FingersDance.Control.SyncSource/UserControlSyncSource.xaml	Mon Oct 26 09:27:23 2009 +0100
@@ -14,7 +14,11 @@
         	<FingersDance_Control_TimeLine:UserControlTimeLine Margin="0,0,60,0" x:Name="UCTimeLine" DragStarted="UserControlTimeLine_DragStarted" DragCompleted="UserControlTimeLine_DragCompleted" TimerTick="UserControlTimeLine_TimerTick" d:LayoutOverrides="Height" Background="{x:Null}" />
         </Grid>
         <Grid HorizontalAlignment="Stretch" Width="Auto" Height="Auto" VerticalAlignment="Stretch" x:Name="GridPlayer" Margin="0,54,0,0">
-        	<FingersDance_Control_Player:UserControlPlayer PlayerOpened="UserControlPlayer_PlayerOpened" x:Name="UserControlPlayer" VerticalAlignment="Stretch" d:LayoutOverrides="GridBox" Width="{Binding Path=ActualWidth, ElementName=GridPlayer, Mode=Default}" Margin="0,0,0,0" Height="{Binding Path=ActualHeight, ElementName=GridPlayer, Mode=Default}" />
+        	<Grid.RowDefinitions>
+        		<RowDefinition Height="0.424*"/>
+        		<RowDefinition Height="0.576*"/>
+        	</Grid.RowDefinitions>
+        	<FingersDance_Control_Player:UserControlPlayer PlayerOpened="UserControlPlayer_PlayerOpened" x:Name="UserControlPlayer" VerticalAlignment="Stretch" Width="{Binding Path=ActualWidth, ElementName=GridPlayer, Mode=Default}" Margin="0,0,0,0" Height="{Binding Path=ActualHeight, ElementName=GridPlayer, Mode=Default}" Grid.RowSpan="2" />
         </Grid>
     </Grid>
 </UserControl>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/DoubleHalfConverter.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/GestureControl.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/GestureControl.csproj	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/GestureControl.csproj.vspscc	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/GestureVector.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Properties/AssemblyInfo.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Properties/Resources.Designer.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Properties/Resources.resx	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Properties/Settings.Designer.cs	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Properties/Settings.settings	Mon Oct 26 09:27:23 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/FingersDance.GestureControl/Resources/Patterns.xml	Mon Oct 26 09:27:23 2009 +0100
@@ -0,0 +1,21 @@
+<?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>
+</Patterns>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/Themes/Generic.xaml	Mon Oct 26 09:27:23 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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/UserGestureControl.xaml	Mon Oct 26 09:27:23 2009 +0100
@@ -0,0 +1,12 @@
+<UserControl
+	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+	mc:Ignorable="d"
+	xmlns:local="clr-namespace:GestureControl"
+	x:Class="GestureControl.UserGestureControl"
+	x:Name="UserControl"
+	d:DesignWidth="640" d:DesignHeight="184">
+	<local:GestureControl Content="GestureControl"/>
+</UserControl>
\ No newline at end of file
--- a/src/FingersDance.sln	Mon Oct 26 08:36:15 2009 +0100
+++ b/src/FingersDance.sln	Mon Oct 26 09:27:23 2009 +0100
@@ -39,7 +39,7 @@
 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}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GestureControl", "FingersDance.GestureControl\GestureControl.csproj", "{99A9037F-5431-44DD-BCE9-ED60670DEBC1}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
--- a/src/GestureControl/DoubleHalfConverter.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-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
-    }
-}
--- a/src/GestureControl/GestureControl.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-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();
-        }
-    }
-}
--- a/src/GestureControl/GestureControl.csproj	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-<?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
--- a/src/GestureControl/GestureControl.csproj.vspscc	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-""
-{
-"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"
-}
--- a/src/GestureControl/GestureVector.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-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
-}
--- a/src/GestureControl/Properties/AssemblyInfo.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-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")]
--- a/src/GestureControl/Properties/Resources.Designer.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <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;
-            }
-        }
-    }
-}
--- a/src/GestureControl/Properties/Resources.resx	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-<?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
--- a/src/GestureControl/Properties/Settings.Designer.cs	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//------------------------------------------------------------------------------
-// <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;
-            }
-        }
-    }
-}
--- a/src/GestureControl/Properties/Settings.settings	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?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
--- a/src/GestureControl/Resources/Patterns.xml	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-<?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>
--- a/src/GestureControl/Themes/Generic.xaml	Mon Oct 26 08:36:15 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<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>