using System; using System.Collections.Generic; using System.Drawing; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using bbiwarg.Recognition.TouchRecognition; using bbiwarg.Utility; using bbiwarg.Input.InputHandling; namespace bbiwarg.Output.DebugOutput { class TouchEventVisualizer { private Stopwatch timer; private Dictionary> activeTouches; private Dictionary> oldTouches; private Dictionary lastUpdates; private int nextFreeID; private int lastUpdated; private bool active; public TouchEventVisualizer() { reset(); } public void reset() { timer = new Stopwatch(); timer.Start(); nextFreeID = 1; lastUpdated = 0; activeTouches = new Dictionary>(); oldTouches = new Dictionary>(); lastUpdates = new Dictionary(); } public void handleNewFrameData(InputHandler sender, EventArgs e) { FrameData frameData = sender.FrameData; lock (frameData) { foreach (TouchEventArgs te in frameData.TouchEvents) { switch (te.Type) { case TouchEventType.Down: activeTouches.Add(te.TrackID, new List()); activeTouches[te.TrackID].Add(te.Touch.RelativePosition); break; case TouchEventType.Move: activeTouches[te.TrackID].Add(te.Touch.RelativePosition); break; case TouchEventType.Up: activeTouches[te.TrackID].Add(te.Touch.RelativePosition); oldTouches.Add(nextFreeID, activeTouches[te.TrackID]); lastUpdates.Add(nextFreeID, timer.ElapsedMilliseconds); activeTouches.Remove(te.TrackID); nextFreeID++; break; } } } } public OutputImage getOutputImage() { long currentTime = timer.ElapsedMilliseconds; removeOldPositions(currentTime - Parameters.TouchEventVisualizerFadeOutTime); int width = Parameters.ImageWidth; int height = Parameters.ImageHeight; OutputImage outputImage = new OutputImage(width, height); // border outputImage.drawRectangle(0, 0, width - 1, height - 1, Parameters.TouchEventVisualizerGridColor); // draw grid int numRows = Parameters.PalmGridNumRows; int numColumns = Parameters.PalmGridNumColumns; int widthPerColumn = width / numColumns; int heightPerRow = height / numRows; // find active blocks bool[,] activeBlocks = new bool[numRows, numColumns]; if (numRows * numColumns > 1) { foreach (List positions in activeTouches.Values) { Vector2D lastPosition = positions.Last(); int activeRow = (int)Math.Floor(lastPosition.Y * Parameters.PalmGridNumRows); int activeCol = (int)Math.Floor(lastPosition.X * Parameters.PalmGridNumColumns); activeBlocks[activeRow, activeCol] = true; } } // draw blocks for (int row = 0; row < numRows; row++) { for (int col = 0; col < numColumns; col++) { if (activeBlocks[row, col]) outputImage.fillRectangle(col * widthPerColumn, row * heightPerRow, widthPerColumn, heightPerRow, Parameters.TouchEventVisualizerActiveBlockColor); int x = (int)((col + 0.5f) * widthPerColumn) - 5; int y = (int)((row + 0.5f) * heightPerRow) + 5; outputImage.drawText(x, y, (1 + row * numColumns + col).ToString(), Parameters.TouchEventVisualizerTextColor); } } // draw grid for (int i = 0; i <= numColumns; i++) outputImage.drawLineSegment(new LineSegment2D(new Vector2D(i * widthPerColumn, 0), new Vector2D(i * widthPerColumn, height - 1)), Parameters.TouchEventVisualizerGridColor); for (int i = 0; i <= numRows; i++) outputImage.drawLineSegment(new LineSegment2D(new Vector2D(0, i * heightPerRow), new Vector2D(width - 1, i * heightPerRow)), Parameters.TouchEventVisualizerGridColor); // draw active touches foreach (List positions in activeTouches.Values) outputImage.drawTouchGesture(positions); // draw old touches (fade out) foreach (int id in oldTouches.Keys) { List positions = oldTouches[id]; long lastUpdate = lastUpdates[id]; float opacity = 1 - ((currentTime - lastUpdate) / (float)Parameters.TouchEventVisualizerFadeOutTime); outputImage.drawTouchGesture(positions, opacity); } return outputImage; } private void removeOldPositions(long breakTime) { long currentTime = timer.ElapsedMilliseconds; List ids = new List(lastUpdates.Keys); for (int i = ids.Count - 1; i >= 0; i--) { int id = ids[i]; if (breakTime > lastUpdates[id]) { oldTouches.Remove(id); lastUpdates.Remove(id); } } } } }