--- a/src/FingersDance.GestureControl/GestureControl.cs Mon Oct 26 16:03:34 2009 +0100
+++ b/src/FingersDance.GestureControl/GestureControl.cs Tue Oct 27 01:59:56 2009 +0100
@@ -17,6 +17,11 @@
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using System.Windows.Ink;
+using System.Threading;
+using System.IO;
+using System.Xml;
+using System.Reflection;
+using System.Xml.Linq;
namespace GestureControl
{
@@ -24,6 +29,14 @@
{
private double angle = 0;
public static readonly DependencyProperty GestureProperty;
+ Thread inProgess;
+ List<SurfaceGesture> _Gestures = new List<SurfaceGesture>();
+
+ /// <summary>
+ /// List of pattern readed in the patterns.xml
+ /// </summary>
+ public List<SurfaceGesturePattern> Pattern = new List<SurfaceGesturePattern>();
+
public String Gesture
{
get { return (String)GetValue(GestureControl.GestureProperty); }
@@ -31,24 +44,36 @@
}
#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 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)
+
+ public delegate void RaiseGestureEventCallBack(string gesture);
+
+ public void RaiseGestureEvent(string gesture)
{
- try
+ if (this.Dispatcher.CheckAccess())
{
- GestureRoutedEventArgs newEventArgs = new GestureRoutedEventArgs(GestureControl.gestureEvent, gesture);
- RaiseEvent(newEventArgs);
+ try
+ {
+ GestureRoutedEventArgs newEventArgs = new GestureRoutedEventArgs(GestureControl.gestureEvent, gesture);
+ RaiseEvent(newEventArgs);
+ }
+ catch (Exception e) { }
}
- catch (Exception e) { }
+ else
+ {
+ this.Dispatcher.BeginInvoke(new RaiseGestureEventCallBack(RaiseGestureEvent), gesture);
+ }
}
+
#endregion
static GestureControl()
@@ -58,6 +83,7 @@
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");
@@ -68,11 +94,13 @@
base.OnInitialized(e);
this.InitializeControl();
}
+
protected void InitializeControl()
{
- base.AddHandler(SurfaceControl.PreviewContactDownEvent, new RoutedEventHandler(AreaDown));
- base.AddHandler(SurfaceInkCanvas.StrokeCollectedEvent, new RoutedEventHandler(AreaStrokeCollected));
+ 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)
{
@@ -82,6 +110,18 @@
protected void AreaStrokeCollected(object source, RoutedEventArgs e)
{
+ if (inProgess == null)
+ {
+ inProgess = new Thread(RunCapture);
+ inProgess.Start();
+ }
+ else
+ {
+ inProgess.Abort();
+ inProgess = null;
+ inProgess = new Thread(RunCapture);
+ inProgess.Start();
+ }
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
@@ -98,14 +138,154 @@
// 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
+ _Gestures.Add(gesture);
SurfaceInkCanvas ink = e.OriginalSource as SurfaceInkCanvas;
ink.Strokes.Clear();
}
+
+ void RunCapture()
+ {
+ try
+ {
+ Thread.Sleep(1000);
+ CommonPattern();
+ string gesture = GetPattern(_Gestures);
+ if (gesture != "None")
+ {
+ this.RaiseGestureEvent(gesture);
+ }
+ _Gestures.Clear();
+ inProgess = null;
+ }
+ catch (Exception)
+ {
+ inProgess = null;
+ }
+ }
+
+ #region Pattern
+ /// <ary>
+ /// return a String with the recognized pattern, "None" if no pattern
+ /// </summary>
+ /// <returns></returns>
+ public String GetPattern(List<SurfaceGesture> gestures)
+ {
+ int found = 0;
+ List<SurfaceGesture> tmp = new List<SurfaceGesture>();
+ foreach (SurfaceGesturePattern p in Pattern)
+ {
+ if (p.Count == gestures.Count)
+ {
+ int index = 0;
+ for (index = 0; index < p.Count; index++)
+ {
+ if (p[index].Count == gestures[index].Count)
+ {
+ int i;
+ for (i = 0; i < p[index].Count; i++)
+ {
+ if (gestures[index][i].Direction != p[index][i].Direction)
+ i = p[index].Count + 1;
+ }
+ if (i == p[index].Count)
+ found++;
+
+ }
+ }
+ if (found == 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
+ Pattern.Clear();
+ 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 item;
+ foreach (XmlNode nod in nodes)
+ {
+ string name = nod["Name"].InnerText;
+ if (nod.ChildNodes.Count < 2)
+ continue;
+ item = new SurfaceGesturePattern() { Name = name };
+ List<XmlNode> childs = new List<XmlNode>();
+ foreach (XmlNode elt in nod.ChildNodes)
+ if (elt.Name.Equals("Childs"))
+ foreach (XmlNode c in elt.ChildNodes)
+ childs.Add(c);
+
+ SurfaceGesturePatternItem p;
+ int j = 0;
+ foreach (XmlNode node in childs)
+ {
+ string childname = node["Name"].InnerText;
+ List<XmlNode> subNodes = new List<XmlNode>();
+ foreach (XmlNode elt in node.ChildNodes)
+ if (elt.Name.Equals("Directions"))
+ foreach (XmlNode c in elt.ChildNodes)
+ subNodes.Add(c);
+ if (subNodes.Count == 0)
+ continue;
+
+ p = new SurfaceGesturePatternItem() { Name = childname };
+
+ foreach (XmlNode subNode in subNodes)
+ {
+ switch (subNode.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;
+ }
+ }
+ item.Add(p);
+ }
+ this.Pattern.Add(item);
+ }
+ #endregion
+ }
+ catch
+ {
+ throw new Exception("Error loading Patterns.xml");
+ }
+ }
+
+ #endregion
}
}
--- a/src/FingersDance.GestureControl/GestureControl.csproj Mon Oct 26 16:03:34 2009 +0100
+++ b/src/FingersDance.GestureControl/GestureControl.csproj Tue Oct 27 01:59:56 2009 +0100
@@ -82,6 +82,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DoubleHalfConverter.cs" />
+ <Compile Include="GestureRoutedEventArgs.cs" />
<Compile Include="GestureVector.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
@@ -96,6 +97,11 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
+ <Compile Include="SurfaceGesturePattern.cs" />
+ <Compile Include="SurfaceGesturePatternItem.cs" />
+ <Compile Include="SurfaceGesturePoint.cs" />
+ <Compile Include="SurfaceGestureVector.cs" />
+ <Compile Include="SurfaceGestureVectorDirection.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/GestureRoutedEventArgs.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Input;
+using System.Windows;
+
+namespace GestureControl
+{
+ /// <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; }
+ }
+}
--- a/src/FingersDance.GestureControl/GestureVector.cs Mon Oct 26 16:03:34 2009 +0100
+++ b/src/FingersDance.GestureControl/GestureVector.cs Tue Oct 27 01:59:56 2009 +0100
@@ -1,8 +1,4 @@
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;
@@ -22,11 +18,8 @@
/// 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
@@ -35,7 +28,6 @@
public SurfaceGesture(List<SurfaceGesturePoint> list)
{
this.Precision = 20;
- CommonPattern();
this.Generate(list);
}
/// <summary>
@@ -46,20 +38,10 @@
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
@@ -69,7 +51,7 @@
/// <returns></returns>
private bool GenerateCourb(List<SurfaceGesturePoint> list, int pas)
{
- List<SurfaceGesturePattern> tmp = new List<SurfaceGesturePattern>();
+ //List<SurfaceGesturePattern> tmp = new List<SurfaceGesturePattern>();
int sep = list.Count / pas;
double count = 0; ;
SurfaceGesturePoint past = new SurfaceGesturePoint() { X = 0, Y = 0 };
@@ -109,9 +91,9 @@
}
}
Console.Write(this);
- if (this.GetPattern() != "None")
+ /*if (this.GetPattern() != "None")
return true;
- else
+ else*/
return false;
}
/// <summary>
@@ -132,8 +114,8 @@
{
if (this.Count == 0)
{
- this.Add(new SurfaceGestureVector{Direction = type, Lenght=42});
- return ;
+ this.Add(new SurfaceGestureVector { Direction = type, Lenght = 42 });
+ return;
}
if (this[this.Count - 1].Direction != type)
this.Add(new SurfaceGestureVector { Direction = type, Lenght = 42 });
@@ -145,7 +127,7 @@
private void Generate(List<SurfaceGesturePoint> list)
{
if (list.Count < 2)
- return ;
+ return;
SurfaceGestureVectorDirection lastDirection = SurfaceGestureVectorDirection.NONE;
int lastPoint = 0;
SurfaceGesturePoint LastChange = list[0];
@@ -218,6 +200,7 @@
return SurfaceGestureVectorDirection.NONE;
}
#endregion
+
#region Override
public override String ToString()
{
@@ -231,150 +214,5 @@
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/FingersDance.GestureControl/Resources/Patterns.xml Mon Oct 26 16:03:34 2009 +0100
+++ b/src/FingersDance.GestureControl/Resources/Patterns.xml Tue Oct 27 01:59:56 2009 +0100
@@ -2,20 +2,41 @@
<Patterns>
<Pattern>
<Name>UP</Name>
- <Directions>
- <Direction>Up</Direction>
- </Directions>
+ <Childs>
+ <Child>
+ <Name>UP</Name>
+ <Directions>
+ <Direction>Up</Direction>
+ </Directions>
+ </Child>
+ </Childs>
+ </Pattern>
+ <Pattern>
+ <Name>LEFT</Name>
+ <Childs>
+ <Child>
+ <Name>Up</Name>
+ <Directions>
+ <Direction>Up</Direction>
+ </Directions>
+ </Child>
+ <Child>
+ <Name>Up</Name>
+ <Directions>
+ <Direction>Up</Direction>
+ </Directions>
+ </Child>
+ </Childs>
</Pattern>
<Pattern>
<Name>RIGHT</Name>
- <Directions>
- <Direction>Right</Direction>
- </Directions>
+ <Childs>
+ <Child>
+ <Name>RIGHT</Name>
+ <Directions>
+ <Direction>Right</Direction>
+ </Directions>
+ </Child>
+ </Childs>
</Pattern>
- <Pattern>
- <Name>LEFT</Name>
- <Directions>
- <Direction>Left</Direction>
- </Directions>
- </Pattern>
-</Patterns>
+</Patterns>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/SurfaceGesturePattern.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GestureControl
+{
+ public class SurfaceGesturePattern : List<SurfaceGesturePatternItem>
+ {
+ public String Name { get; set; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/SurfaceGesturePatternItem.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GestureControl
+{
+ public class SurfaceGesturePatternItem : List<SurfaceGestureVector>
+ {
+ public String Name { get; set; }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/SurfaceGesturePoint.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GestureControl
+{
+ /// <summary>
+ /// Describe a point in the grid
+ /// </summary>
+ public class SurfaceGesturePoint
+ {
+ public double X { get; set; }
+ public double Y { get; set; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/SurfaceGestureVector.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GestureControl
+{
+ /// <summary>
+ /// Describe a vector to help the recognize pass
+ /// </summary>
+ public class SurfaceGestureVector
+ {
+ public SurfaceGestureVectorDirection Direction { get; set; }
+ public Double Lenght { get; set; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FingersDance.GestureControl/SurfaceGestureVectorDirection.cs Tue Oct 27 01:59:56 2009 +0100
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GestureControl
+{
+ /// <summary>
+ /// Possible Gesture Vector
+ /// </summary>
+ public enum SurfaceGestureVectorDirection
+ {
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT,
+ UPLEFT,
+ UPRIGHT,
+ DOWNLEFT,
+ DOWNRIGHT,
+ NONE,
+ }
+}