# HG changeset patch # User PAMPHILE Jonathan # Date 1256605196 -3600 # Node ID 0896f36b9d5797082db7819dc6b4b25852e1caf4 # Parent 1d4b6d6474d502709f02041a7baae156632ea89c Multi Touch diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/GestureControl.cs --- 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 _Gestures = new List(); + + /// + /// List of pattern readed in the patterns.xml + /// + public List Pattern = new List(); + 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 + /// + /// return a String with the recognized pattern, "None" if no pattern + /// + /// + public String GetPattern(List gestures) + { + int found = 0; + List tmp = new List(); + 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"; + } + + /// + /// Load know patterns from the Resources/Patterns.xml file + /// + 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 childs = new List(); + 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 subNodes = new List(); + 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 } } diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/GestureControl.csproj --- 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 @@ + Code @@ -96,6 +97,11 @@ Settings.settings True + + + + + ResXFileCodeGenerator Resources.Designer.cs diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/GestureRoutedEventArgs.cs --- /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 +{ + /// + /// Gesture event who return a object with a Gesture String value + /// + 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; } + } +} diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/GestureVector.cs --- 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 /// public int Precision { get; set; } - /// - /// List of pattern readed in the patterns.xml - /// - public List Pattern = new List(); #endregion + #region Constructor /// /// 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 list) { this.Precision = 20; - CommonPattern(); this.Generate(list); } /// @@ -46,20 +38,10 @@ public SurfaceGesture(List list, int precision) { this.Precision = precision; - CommonPattern(); this.Generate(list); } - //public SurfaceGesture(System.Windows.Ink.Stroke stroke, int precision) - //{ - // StylusPointCollection tmp = stroke.GetBezierStylusPoints(); - // List pointList = new List(); - // 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 /// /// Generate list of vector from courbe mouvements, filter with the pas value @@ -69,7 +51,7 @@ /// private bool GenerateCourb(List list, int pas) { - List tmp = new List(); + //List tmp = new List(); 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; } /// @@ -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 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 - /// - /// return a String with the recognized pattern, "None" if no pattern - /// - /// - 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"; - } - /// - /// Load know patterns from the Resources/Patterns.xml file - /// - 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 - /// - /// Gesture event who return a object with a Gesture String value - /// - 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 - { - public String Name { get; set; } - - } - /// - /// Possible Gesture Vector - /// - public enum SurfaceGestureVectorDirection - { - UP, - DOWN, - LEFT, - RIGHT, - UPLEFT, - UPRIGHT, - DOWNLEFT, - DOWNRIGHT, - NONE, - } - /// - /// Describe a point in the grid - /// - public class SurfaceGesturePoint - { - public double X { get; set; } - public double Y { get; set; } - } - - /// - /// Describe a vector to help the recognize pass - /// - public class SurfaceGestureVector - { - public SurfaceGestureVectorDirection Direction { get; set; } - public Double Lenght { get; set; } - } - #endregion } diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/Resources/Patterns.xml --- 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 @@ UP - - Up - + + + UP + + Up + + + + + + LEFT + + + Up + + Up + + + + Up + + Up + + + RIGHT - - Right - + + + RIGHT + + Right + + + - - LEFT - - Left - - - + \ No newline at end of file diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/SurfaceGesturePattern.cs --- /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 + { + public String Name { get; set; } + } +} diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/SurfaceGesturePatternItem.cs --- /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 + { + public String Name { get; set; } + + } +} diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/SurfaceGesturePoint.cs --- /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 +{ + /// + /// Describe a point in the grid + /// + public class SurfaceGesturePoint + { + public double X { get; set; } + public double Y { get; set; } + } +} diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/SurfaceGestureVector.cs --- /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 +{ + /// + /// Describe a vector to help the recognize pass + /// + public class SurfaceGestureVector + { + public SurfaceGestureVectorDirection Direction { get; set; } + public Double Lenght { get; set; } + } +} diff -r 1d4b6d6474d5 -r 0896f36b9d57 src/FingersDance.GestureControl/SurfaceGestureVectorDirection.cs --- /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 +{ + /// + /// Possible Gesture Vector + /// + public enum SurfaceGestureVectorDirection + { + UP, + DOWN, + LEFT, + RIGHT, + UPLEFT, + UPRIGHT, + DOWNLEFT, + DOWNRIGHT, + NONE, + } +}