How to Create a New Primitive Condition

Note: You need TouchToolkit Oct CTP or higher version to create new return type(s)

Step 1: Create the primitive condition & primitive condition validator classes (C# files)

folder.png
  1. Select the "Primitive Conditions" folder
  2. Goto add new items
  3. Select the "PrimitiveCondition" template
  4. Specify the primitive condition name
This will create 2 C# files (e.g. PrimitiveCondition1.cs & PrimitiveCondition1Validator.cs)

Step 2: Update gesture definition language parser definition file
  • Edit the "Extensions/Language Syntax/PrimitiveConditions.pd" file to add the new primitive condition.
pricon1.png
  • Edit the "Extensions/Language Syntax/PrimitiveConditionSyntax.pd" file to add the syntax for the new primitive condition.
pricon2.png

Step 3: Write code to validate the condition

So far, we have created a new primitive condition and also notified the language parser and compiler about it. Now its time to write C# code. Let's create primitive condition that will check the touch limits in a gesture definition.

An example of TouchLimit condition is the "Tap" gesture:
tap.png

The class that contains the data (i.e. TouchLimit.cs) could look like this:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace TouchToolkit.GestureProcessor.PrimitiveConditions.Objects
{
    public class TouchLimit : IPrimitiveConditionData
    {
        private string _type = string.Empty;
        public string Type
        {
            get
            {
                return _type;
            }
            set
            {
                _type = value;
            }
        }

        private int _minValue = 0;
        public int Min
        {
            get
            {
                return _minValue;
            }
            set
            {
                _minValue = value;
            }
        }

        private int _maxValue = 0;
        public int Max
        {
            get
            {
                return _maxValue;
            }
            set
            {
                _maxValue = value;
            }
        }

        public bool Equals(IPrimitiveConditionData data)
        {
            bool result = false;
            if (data is TouchLimit)
            {
                var d1 = data as TouchLimit;
                if (d1.Type == this.Type &&
                    d1.Min == this.Min &&
                    d1.Max == this.Max)
                    result = true;
            }

            return result;
        }


        public void Union(IPrimitiveConditionData value)
        {
            TouchLimit touchLimit = value as TouchLimit;

            if (this.Min > touchLimit.Min)
                this.Min = touchLimit.Min;

            if ((this.Max != 0 || touchLimit.Max != 0))
            {
                if (!string.Equals(this.Type, "Range", StringComparison.OrdinalIgnoreCase))
                    this.Type = "Range";

                if (this.Max < touchLimit.Max)
                    this.Max = touchLimit.Max;
            }
        }


        public string ToGDL()
        {
            string gl = string.Empty;
            if (string.Equals(this.Type, "Range", StringComparison.OrdinalIgnoreCase))
            {
                gl = string.Format("Touch limit: {0}..{1}", this.Min, this.Max);
            }
            else
            {
                gl = string.Format("Touch limit: {0}", this.Min);
            }

            return gl;
        }
    }
}


and, that class that will validate the condition against the raw touch data could look like this:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Combinatorial;
using System.Collections.Generic;
using TouchToolkit.GestureProcessor.PrimitiveConditions.Objects;
using TouchToolkit.GestureProcessor.PrimitiveConditions.Validators;
using TouchToolkit.GestureProcessor.Objects;

namespace TouchToolkit.GestureProcessor.PrimitiveConditions
{
    public class TouchLimitValidator : IPrimitiveConditionValidator
    {
        class TouchLimitType
        {
            public const string Range = "Range";
            public const string FixedValue = "Fixed";
        }

        private TouchLimit _data;

        public void Init(IPrimitiveConditionData ruleData)
        {
            _data = ruleData as TouchLimit;
        }

        public ValidSetOfPointsCollection Validate(List<TouchPoint2> points)
        {
            ValidSetOfPointsCollection list = new ValidSetOfPointsCollection();

            if (_data.Type == TouchLimitType.FixedValue)
            {
                if (points.Count == _data.Min)
                {
                    list.Add(new ValidSetOfTouchPoints(points));
                }
                else if (points.Count > _data.Min)
                {
                    // Generate possible valid combinitions
                    Combinations c = new Combinations(points.ToArray(), _data.Min);
                    while (c.MoveNext())
                    {
                        TouchPoint2[] arr = c.Current as TouchPoint2[];
                        ValidSetOfTouchPoints set = new ValidSetOfTouchPoints(arr);
                        list.Add(set);
                    }
                }
            }
            else if (_data.Type == TouchLimitType.Range)
            {
                if (points.Count >= _data.Min && points.Count <= _data.Max)
                {
                    list.Add(new ValidSetOfTouchPoints(points));
                }
            }

            return list;
        }

        public ValidSetOfPointsCollection Validate(ValidSetOfPointsCollection sets)
        {
            ValidSetOfPointsCollection list = new ValidSetOfPointsCollection();
            foreach (var item in sets)
            {
                var tlist = Validate(item);
                list.AddRange(tlist);
            }

            return list;
        }


        public bool Equals(IPrimitiveConditionValidator rule)
        {
            if (rule is TouchLimitValidator)
            {
                TouchLimitValidator r1 = rule as TouchLimitValidator;

                return (r1._data.Equals(this._data));
            }
            else
                return false;
        }

        public IPrimitiveConditionData GenerateRuleData(List<TouchPoint2> points)
        {
            throw new NotImplementedException();
        }
    }
}

Last edited Oct 25, 2010 at 2:11 AM by shahed, version 15

Comments

No comments yet.