summaryrefslogtreecommitdiff
path: root/Anoto/FormAnotoSupervision.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Anoto/FormAnotoSupervision.cs')
-rw-r--r--Anoto/FormAnotoSupervision.cs648
1 files changed, 648 insertions, 0 deletions
diff --git a/Anoto/FormAnotoSupervision.cs b/Anoto/FormAnotoSupervision.cs
new file mode 100644
index 0000000..4ed4f51
--- /dev/null
+++ b/Anoto/FormAnotoSupervision.cs
@@ -0,0 +1,648 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Anoto;
+using System.Threading;
+//using Ivy;
+using IvyBus;
+using System.Media;
+using AnotoData;
+//using Data;
+
+using Microsoft.Ink;
+
+
+namespace Anoto
+{
+
+
+ public partial class FormAnotoSupervision : Form
+ {
+ Recognizer TheRecognizer;
+ RecognizerContext TheRecognizerContext;
+
+ // AppDatabase TheData;
+ DateTime LastDataUpdate;
+
+ private SoundPlayer SoundPenDown = new SoundPlayer();
+ private SoundPlayer SoundPenUp = new SoundPlayer();
+
+ private const int MAX_LOG_LENGTH = 100;
+
+ Anoto.GenericStreamer.PenManagerClass PenManager;
+
+ // AnotoStrip[] Strips;
+ List<AnotoHotArea> HotAreas;
+
+ AnotoRadarScreen TheAnotoRadarScreen;
+ AnotoStripBoard TheAntotoStripBoard;
+
+ Dictionary<string, List<PointF>> PensPoints;
+ Dictionary<string, Brush> PensBrush;
+ Dictionary<string, Pen> Pens;
+
+ List<AnotoPen> AnotoPens;
+
+ Mutex mutex;
+ Random Rnd;
+
+
+ Bitmap DrawingArea;
+ private SolidBrush TranparentBlack;
+
+
+ XMLStateMachine StateMAchine;
+
+ public FormAnotoSupervision()
+ {
+ InitializeComponent();
+
+ StateMAchine = new XMLStateMachine();
+ StateMAchine.StateTable = "XMLStates.xml";
+ StateMAchine.CurrentState = "Start";
+
+ // TheData = new AppDatabase(TheIvyBus);
+ }
+
+ void TheIvyDomain_DomainChanged(object sender, EventArgs e)
+ {
+ TheIvyBus.ivy.Stop();
+ TheIvyBus.ivy.Start(TheIvyDomain.Domain);
+ }
+
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ // TheRecognizer.;
+ //TheRecognizer.CreateRecognizerContext();
+
+ TranparentBlack = new SolidBrush(Color.FromArgb(100, 0, 0, 0));
+
+ TheIvyDomain.Location = new Point(0, 30);
+
+ DrawingArea = new Bitmap(pictureBox1.Width, pictureBox1.Height);
+ pictureBox1.Image = DrawingArea;
+
+
+ //Start IVY
+ TheIvyBus.ivy.Start(TheIvyDomain.Domain);
+
+ TheIvyDomain.DomainChanged += new EventHandler(TheIvyDomain_DomainChanged);
+
+ this.Controls.Add(TheIvyDomain);
+
+ AnotoPens = new List<AnotoPen>();
+
+ PenManager = new Anoto.GenericStreamer.PenManagerClass();
+
+ PenManager.PenConnected += new Anoto.GenericStreamer._IPenManagerEvents_PenConnectedEventHandler(pm_PenConnected);
+ PenManager.PenDisconnected += new GenericStreamer._IPenManagerEvents_PenDisconnectedEventHandler(PenManager_PenDisconnected);
+ PenManager.NewCoordinate += new Anoto.GenericStreamer._IPenManagerEvents_NewCoordinateEventHandler(PenManager_NewCoordinate);
+ PenManager.PenDown += new Anoto.GenericStreamer._IPenManagerEvents_PenDownEventHandler(PenManager_PenDown);
+ PenManager.PenUp += new Anoto.GenericStreamer._IPenManagerEvents_PenUpEventHandler(PenManager_PenUp);
+ PenManager.Start();
+
+ mutex = new Mutex();
+
+ InitDictionary();
+
+ Rnd = new Random();
+
+ AnotoStrip[] Strips = AnotoStrip.LoadFileStrip("Strips.csv");
+ HotAreas = new List<AnotoHotArea>();
+ foreach (var strip in Strips)
+ {
+ HotAreas.Add(strip);
+ }
+
+ TheAnotoRadarScreen = new AnotoRadarScreen();
+ HotAreas.Add(TheAnotoRadarScreen);
+
+ TheAntotoStripBoard = new AnotoStripBoard();
+ HotAreas.Add(TheAntotoStripBoard);
+
+
+ listBoxHotAreas.Items.Clear();
+
+ foreach (var ha in HotAreas)
+ {
+ listBoxHotAreas.Items.Add(ha);
+ }
+
+ //Load sounds
+ LoadSounds();
+ }
+
+ private void LoadSounds()
+ {
+ this.SoundPenDown.SoundLocation = "PenDown.wav";
+ this.SoundPenDown.LoadAsync();
+ this.SoundPenUp.SoundLocation = "PenUp.wav";
+ this.SoundPenUp.LoadAsync();
+ }
+
+
+
+ private void InitDictionary()
+ {
+ PensPoints = new Dictionary<string, List<PointF>>();
+ PensBrush = new Dictionary<string, Brush>();
+ Pens = new Dictionary<string, Pen>();
+ }
+
+ #region Pen management/ events
+
+ void pm_PenConnected(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, string productName, ushort pid)
+ {
+ AnotoPen pen = new AnotoPen(penSerial, PenType, time, productName, pid);
+ AnotoPens.Add(pen);
+
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ listBoxAnotoPens.Items.Add(pen);
+ AddLog("Pen connected " + penSerial + " " + PenType.ToString() + " " + productName);
+
+ }));
+
+ // Console.WriteLine("Pen connected " + penSerial + " " + PenType.ToString() + " " + productName);
+ if (!PensPoints.ContainsKey(penSerial))
+ PensPoints.Add(penSerial, new List<PointF>());
+ else
+ PensPoints[penSerial] = new List<PointF>();
+
+ if (!PensBrush.ContainsKey(penSerial))
+ PensBrush.Add(penSerial, new SolidBrush(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255))));
+ else
+ PensBrush[penSerial] = new SolidBrush(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255)));
+
+ if (!Pens.ContainsKey(penSerial))
+ Pens.Add(penSerial, new Pen(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255))));
+ else
+ Pens[penSerial] = new Pen(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255)));
+ }
+
+ void PenManager_PenDisconnected(string penSerial, GenericStreamer.PenType PenType, ulong time)
+ {
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ mutex.WaitOne();
+ AnotoPen p = null;
+ foreach (AnotoPen item in listBoxAnotoPens.Items)
+ {
+ if (item.PenSerial == penSerial)
+ p = item;
+ }
+ if (p != null)
+ {
+ listBoxAnotoPens.Items.Remove(p);
+ AddLog("Pen Disconnected " + penSerial + " " + PenType.ToString());
+
+ }
+ mutex.ReleaseMutex();
+ }));
+ }
+
+ List<List<PointF>> InkMarks = new List<List<PointF>>();
+ DateTime LastDateTimePenUp = DateTime.Now;
+ /// <summary>
+ /// After one second, the trail is no more valid
+ /// </summary>
+ int MaxMillisecondForNewtrail = 1000;
+
+ void PenManager_PenUp(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, byte penDownSeqNbr, int isSpcdGenerated)
+ {
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ AddLog("Pen Up " + penSerial + " ");
+ if (checkBoxEnableSound.Checked)
+ SoundPenUp.Play();
+ // Console.WriteLine("Pen Up " + penSerial + " time " + time);
+
+ if ((DateTime.Now - LastDateTimePenUp).TotalMilliseconds > MaxMillisecondForNewtrail)
+ {
+ //MaxMillisecondForNewtrail second has past since the last trail
+ //Erase previous Data
+ InkMarks = new List<List<PointF>>();
+ }
+ //Copie the data the the current text recognizer
+ List<PointF> tmpLst = new List<PointF>();
+ foreach (var pt in PensPoints[penSerial])
+ {
+ tmpLst.Add(pt);
+ }
+ InkMarks.Add(tmpLst);
+ //Try to recogize It
+ TryRecognition();
+
+ LastDateTimePenUp = DateTime.Now;
+
+ pictureBox1.Invalidate();
+ }));
+ }
+
+ private void TryRecognition()
+ {
+ // Declare a new TabletPropertyDescriptionCollection (this is new in 1.7)
+ TabletPropertyDescriptionCollection tpdc = new TabletPropertyDescriptionCollection();
+
+ // Define the X and Y extents for this TabletPropertyDescriptionCollection
+ TabletPropertyMetrics tpmX = new TabletPropertyMetrics();
+ tpmX.Maximum = AnotoData.AnotoHotArea.MaxX;
+ TabletPropertyMetrics tpmY = new TabletPropertyMetrics();
+ tpmY.Maximum = tpmX.Maximum = AnotoData.AnotoHotArea.MaxY;
+
+ // Define the NormalPressure for the Tablet PropertyDescriptionCollection
+ TabletPropertyMetrics tpmNP = new TabletPropertyMetrics();
+ // This defines 1024 levels of pressure
+ tpmNP.Maximum = 1024;
+
+ TabletPropertyMetrics tpmSt = new TabletPropertyMetrics();
+
+ // Add each of the propertyMetrics to the TabletPropertyDescriptionCollection
+ // This defines what the data stream will look like, in this case (X, Y, NP)
+ tpdc.Add(new TabletPropertyDescription(PacketProperty.X, tpmX));
+ tpdc.Add(new TabletPropertyDescription(PacketProperty.Y, tpmY));
+ // tpdc.Add(new TabletPropertyDescription(PacketProperty.TimerTick, tpmSt));
+ // tpdc.Add(new TabletPropertyDescription(PacketProperty.NormalPressure, tpmNP));
+
+ InkCollector myInkCollector = new InkCollector();
+
+ bool hasValideStrokes = false;
+ foreach (var stroke in InkMarks)
+ {
+ if (stroke.Count > 0)
+ {
+ Point point;
+ Point[] pts = new Point[stroke.Count];
+ int[] data = new int[stroke.Count * tpdc.Count];
+ int index = 0;
+ int data_index = 0;
+
+ foreach (PointF pt in stroke)
+ {
+
+ int x = (int)(pt.X * AnotoData.AnotoHotArea.MaxX);
+ data.SetValue(x, data_index++);
+ int y = (int)(pt.Y * AnotoData.AnotoHotArea.MaxY);
+ data.SetValue(y, data_index++);
+ //?????
+ // data.SetValue(1000 + 100 * data_index , data_index++);
+ // data.SetValue(512, data_index++);
+ point = new Point(x, y);
+ pts.SetValue(point, index++);
+ hasValideStrokes = true;
+ }
+
+ //Convert this array of ink space points to pixels.
+ //myInkCollector.Renderer.PixelToInkSpace(inkArea.Handle, ref pts);
+ //Stroke stroke = myInkCollector.Ink.CreateStroke(pts);
+ Stroke inkStroke = myInkCollector.Ink.CreateStroke(data, tpdc);
+ myInkCollector.Ink.Strokes.Add(inkStroke);
+ }
+ }
+ if (hasValideStrokes)
+ {
+ TheRecognizerContext = new RecognizerContext();
+ RecognitionStatus recognitionStatus;
+ //TheRecognizerContext.Factoid = Microsoft.Ink.Factoid.Number+"|" + Microsoft.Ink.Factoid.LowerChar
+ // + "|" + Microsoft.Ink.Factoid.UpperChar;// "";
+ TheRecognizerContext.Factoid = "(0|1|2|3|4|5|6|7|8|9|)";
+ TheRecognizerContext.RecognitionFlags = RecognitionModes.Coerce;
+ TheRecognizerContext.Strokes = myInkCollector.Ink.Strokes;
+
+ RecognitionResult rr = TheRecognizerContext.Recognize(out recognitionStatus);
+ if (rr != null)
+ textBoxRecognition.Text = rr.ToString();
+ }
+ /*
+ //throw new NotImplementedException();
+ RecognitionStatus recognitionStatus;
+ //Create the stroke collection
+ Strokes strokes;
+ Point[] pts = new Point[InkMarks.Count];
+ int index = 0;
+ foreach (var p in InkMarks)
+ {
+ pts[index] = new Point((int)(p.X * AnotoData.AnotoHotArea.MaxX),
+ (int)(p.X * AnotoData.AnotoHotArea.MaxY)
+ );
+ index++;
+ }
+
+ Stroke stroke = null;
+ stroke.SetPoints(pts);
+
+ TheRecognizerContext.Strokes.Add(stroke);
+
+ TheRecognizerContext.Recognize(out recognitionStatus);*/
+ }
+
+ void PenManager_PenDown(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, byte penDownSeqNbr, Anoto.GenericStreamer.PenTipType PenTipType, int isValidColor, byte r, byte g, byte b, int isSpcdGenerated)
+ {
+ // Console.WriteLine("Pen Down " + penSerial + " time " + time);
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ mutex.WaitOne();
+ PensPoints.Remove(penSerial);
+
+ PensPoints.Add(penSerial, new List<PointF>());
+ AddLog("Pen Down " + penSerial + " ");
+
+ if (checkBoxEnableSound.Checked)
+ SoundPenDown.Play();
+ mutex.ReleaseMutex();
+ }));
+ }
+
+ void PenManager_NewCoordinate(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, string page, int x, int y, byte imgSeqNbr, byte force)
+ {
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ mutex.WaitOne();
+ PensPoints[penSerial].Add(AnotoHotArea.GetHomogeneousCoordinate(x, y));
+ mutex.ReleaseMutex();
+
+ // Console.WriteLine("Pen NewCoordinate " + penSerial + " time " + time + " x " + x + " y " + y);
+
+ if ((DateTime.Now - LastDataUpdate).TotalMilliseconds > 100)
+ {
+ PopulateGraphicalData(page, x, y, force);
+ LastDataUpdate = DateTime.Now;
+ }
+
+ PopulateData(penSerial, page, x, y, force);
+ }));
+ }
+
+ #endregion
+
+ private void AddLog(string p)
+ {
+ listBoxEvents.Items.Insert(0, p + " " + DateTime.Now.ToString("HH:mm:ss"));
+
+ if (listBoxEvents.Items.Count > MAX_LOG_LENGTH)
+ listBoxEvents.Items.RemoveAt(listBoxEvents.Items.Count - 1);
+ }
+
+ private void PopulateGraphicalData(string page, int x, int y, byte force)
+ {
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ SetProgressBarValue(progressBarX, x);
+ SetProgressBarValue(progressBarY, y);
+ SetProgressBarValue(progressBarForce, (int)force);
+
+ labelX.Text = "X: " + x;
+ labelY.Text = "Y: " + y;
+
+ labelPage.Text = page;
+
+ pictureBox1.Invalidate();
+ }));
+ }
+
+ public AnotoHotArea GetHotArea(int x, int y, string page)
+ {
+ AnotoHotArea result = null;
+ foreach (var s in HotAreas)
+ {
+ if (s.IsInside(x, y, page))// AnotoHotArea.PagesIP[s.PageIndex] == page)
+ {
+ return s;
+ }
+ }
+ return result;
+ }
+
+ private void PopulateData(string penSerial, string page, int x, int y, byte force)
+ {
+ this.Invoke(new MethodInvoker(delegate()
+ {
+ //Find the Strip name
+ // AnotoHotArea hotArea = AnotoHotArea
+ AnotoHotArea hotArea = GetHotArea(x, y, page);
+
+ if (hotArea is AnotoStrip)
+ {
+ AnotoStrip strip = (AnotoStrip)hotArea;
+ SubCategories cell = strip.GetStripArea(x, y);
+ labelStripInfo.Text = cell.ToString() + " : " + strip.GetTextForCell(cell)
+
+ + Environment.NewLine + " " + strip.ToString();
+ // TheIvyBus.SendMsg("SelectionEvent acc=bordeaux wp=WP1 role=TC Flight=" + strip.SSR);
+
+ //Halo
+ if (LastSSR != strip.SSR)
+ {
+ TheIvyBus.SendMsg("SelectionEvent Flight=" + LastSSR + " Perform=False");
+ string ivySMG = "SelectionEvent Flight=" + strip.SSR + " Perform=True";
+ LastSSR = strip.SSR;
+ TheIvyBus.SendMsg(ivySMG);
+ AddLog(ivySMG);
+ }
+
+
+ /* if ((cell != StateMachineCurrentCell) || (StateMachineCurrentStrip != strip))
+ {
+ Console.WriteLine("New Action");
+ //Test if new message:
+ StateMachineInput(cell, strip);
+ }*/
+ }
+
+ if (hotArea is AnotoRadarScreen)
+ {
+ AnotoRadarScreen screen = (AnotoRadarScreen)hotArea;
+ labelStripInfo.Text = "Screen";
+ //send the pen down to the SimpleRadar Screen
+
+ screen.SendIvyMsg(penSerial, x, y, page, TheIvyBus);
+
+ };
+
+ if (hotArea is AnotoStripBoard)
+ {
+ AnotoStripBoard stripBoard = (AnotoStripBoard)hotArea;
+ labelStripInfo.Text = "Strip Board";
+ }
+ }));
+ }
+
+
+ private AnotoStrip StateMachineCurrentStrip;
+ private SubCategories StateMachineCurrentCell;
+
+ string LastAlidadeStart = "";
+ string LastAlidadeStop = "";
+
+ string LastSSR = "";
+
+ public void DisplayAlidade(string start, string stop)
+ {
+ if (!string.IsNullOrEmpty(LastAlidadeStart))
+ {
+ //hide the previous alidate
+ TheIvyBus.SendMsg("DistanceFeedbackOff acc=bordeaux wp=WP1 role=TC Start=" + LastAlidadeStart + " End=" + LastAlidadeStop);
+ }
+
+ //If the same previous start and stop do nothing -> remove the alidade
+ if (!((start == LastAlidadeStart) && (stop == LastAlidadeStop)))
+ {
+ //Show the new alidade
+ TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + start + " End=" + stop);
+
+ LastAlidadeStop = stop;
+ LastAlidadeStart = start;
+
+ }
+ else
+ {
+ LastAlidadeStop = "";
+ LastAlidadeStart = "";
+ }
+ }
+
+
+ public void StateMachineInput(SubCategories cell, AnotoStrip strip)
+ {
+ StateMachineCurrentStrip = strip;
+ StateMachineCurrentCell = cell;
+ string ivySMG = "";
+ if (StateMAchine.Next(cell.ToString()) != String.Empty)
+ {
+ Console.WriteLine(StateMAchine.Action);
+ //New state
+ switch (StateMAchine.Action)
+ {
+ case "Hilight":
+ //Send IVY Selection event
+ ivySMG = "SelectionEvent Flight=" + strip.SSR + " Perform=True";
+ TheIvyBus.SendMsg(ivySMG);
+ AddLog(ivySMG);
+ break;
+ case "AlidadeInfoInfo":
+ //Send IVY Selection event
+ DisplayAlidade(StateMachineCurrentStrip.SSR, strip.SSR);
+ // TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.SSR + " End=" + strip.SSR);
+ break;
+ case "AlidadeInfoBeacon":
+ //Send IVY Selection event
+ DisplayAlidade(StateMachineCurrentStrip.SSR, strip.GetTextForCell(cell));
+ // TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.SSR + " End=" + strip.GetTextForCell(cell));
+ break;
+
+ case "AlidadeBeaconInfo":
+ //Send IVY Selection event
+ DisplayAlidade(StateMachineCurrentStrip.GetTextForCell(StateMachineCurrentCell), strip.SSR);
+ // TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.GetTextForCell(StateMachineCurrentCell) + " End=" + strip.SSR);
+ break;
+
+ default:
+ break;
+ }
+
+
+ };
+ }
+
+
+
+ void SetProgressBarValue(ProgressBar pb, int val)
+ {
+ if (val < pb.Minimum)
+ pb.Minimum = val;
+ if (val > pb.Maximum)
+ pb.Maximum = val;
+ pb.Value = val;
+ }
+
+
+ private void Form1_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ PenManager.Stop();
+ }
+
+
+ private void pictureBox1_Paint(object sender, PaintEventArgs e)
+ {
+ //draw the dots
+ Graphics g = e.Graphics;
+
+ g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
+
+ g.FillRectangle(Brushes.White, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
+
+ mutex.WaitOne();
+
+ float scale = 15;
+ Pen penPreviousStrokes = new Pen(Brushes.Black);
+ foreach (var pts in InkMarks)
+ {
+ Point[] p = new Point[pts.Count];
+ int index = 0;
+ foreach (var l in pts)
+ {
+ p[index] = new Point((int)(l.X * pictureBox1.Width ) ,
+ (int)(l.Y * pictureBox1.Height));
+ index++;
+ }
+ if ( p.Length > 1)
+ g.DrawLines(penPreviousStrokes, p);
+ }
+
+
+ foreach (var pen in PensPoints)
+ {
+ //if (pen.Value.Count > 1)
+ // g.DrawLines(Pens[pen.Key], pen.Value.ToArray());
+
+ foreach (var point in pen.Value)
+ {
+ float x = pictureBox1.Width * point.X;
+ float y = pictureBox1.Height * point.Y;
+
+ g.FillEllipse(TranparentBlack, x, y, 4, 4);
+ }
+
+ if (pen.Value.Count != 0)
+ PopulateData("", "", (int)pen.Value.Last().X, (int)pen.Value.Last().Y, 0);
+ }
+
+
+ mutex.ReleaseMutex();
+ }
+
+
+ private void Form1_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ TheIvyBus.ivy.Stop();
+ }
+
+ private void listBoxHotAreas_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (listBoxHotAreas.SelectedItem != null)
+ {
+ PropertyAnotoHotArea.SelectedObject = (AnotoHotArea)listBoxHotAreas.SelectedItem;
+ }
+ }
+
+ private void buttonPlay_Click(object sender, EventArgs e)
+ {
+ SoundPenDown.Play();
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ SoundPenUp.Play();
+ }
+
+
+ }
+
+
+}