using System.Collections.Generic; using SkiaSharp; using TouchTracking; namespace TheGameExtreme.view { public class TouchManipulationBitmap { public SKPoint InitialPoint { get; set; } SKPaint textPaint; Dictionary touchDictionary = new Dictionary(); string value; SKCanvas canvas; public TouchManipulationBitmap(SKPaint textPaint, int value) { this.textPaint = textPaint; if (value > 0 && value < 10) { this.value = "0" + value.ToString(); } else { this.value = value.ToString(); } Matrix = SKMatrix.MakeIdentity(); TouchManager = new TouchManipulationManager { Mode = TouchManipulationMode.PanOnly }; } public TouchManipulationManager TouchManager { set; get; } public SKMatrix Matrix { set; get; } public void Paint(SKCanvas canvas) { this.canvas = canvas; canvas.Save(); SKMatrix matrix = Matrix; canvas.Concat(ref matrix); textPaint.Color = SKColors.DarkRed; textPaint.StrokeWidth = 5; textPaint.Style = SKPaintStyle.Stroke; SKRect textBounds = new SKRect(); textPaint.MeasureText(value, ref textBounds); SKRoundRect card = new SKRoundRect(textBounds); card.Inflate(35, 35); canvas.DrawRoundRect(card, textPaint); canvas.DrawText(value, 0, 0, textPaint); canvas.Restore(); } public bool HitTest(SKPoint location) { // Invert the matrix SKMatrix inverseMatrix; if (Matrix.TryInvert(out inverseMatrix)) { // Transform the point using the inverted matrix SKPoint transformedPoint = inverseMatrix.MapPoint(location); // Check if it's in the untransformed bitmap rectangle SKRect rect = new SKRect(0, 0, textPaint.MeasureText(value), textPaint.TextSize); return rect.Contains(transformedPoint); } return false; } public void ProcessTouchEvent(long id, TouchActionType type, SKPoint location, List stackCollection) { switch (type) { case TouchActionType.Pressed: touchDictionary.Add(id, new TouchManipulationInfo { PreviousPoint = location, NewPoint = location }); break; case TouchActionType.Moved: TouchManipulationInfo info = touchDictionary[id]; info.NewPoint = location; Manipulate(); info.PreviousPoint = info.NewPoint; break; case TouchActionType.Released: bool find = false; foreach (TouchManipulationBitmap stack in stackCollection) { if (stack.HitTest(location)) { touchDictionary[id].NewPoint = stack.InitialPoint; Manipulate(); touchDictionary[id].PreviousPoint = touchDictionary[id].NewPoint; stackCollection[stackCollection.IndexOf(stack)] = this; //canvas.Flush(); find = true; break; } } if (!find) { touchDictionary[id].NewPoint = InitialPoint; Manipulate(); touchDictionary[id].PreviousPoint = touchDictionary[id].NewPoint; } break; case TouchActionType.Cancelled: touchDictionary.Remove(id); break; } } void Manipulate() { TouchManipulationInfo[] infos = new TouchManipulationInfo[touchDictionary.Count]; touchDictionary.Values.CopyTo(infos, 0); SKMatrix touchMatrix = SKMatrix.MakeIdentity(); if (infos.Length == 1) { SKPoint prevPoint = infos[0].PreviousPoint; SKPoint newPoint = infos[0].NewPoint; SKPoint pivotPoint = Matrix.MapPoint(textPaint.MeasureText(value) / 2, textPaint.TextSize / 2); touchMatrix = TouchManager.OneFingerManipulate(prevPoint, newPoint, pivotPoint); } else if (infos.Length >= 2) { int pivotIndex = infos[0].NewPoint == infos[0].PreviousPoint ? 0 : 1; SKPoint pivotPoint = infos[pivotIndex].NewPoint; SKPoint newPoint = infos[1 - pivotIndex].NewPoint; SKPoint prevPoint = infos[1 - pivotIndex].PreviousPoint; touchMatrix = TouchManager.TwoFingerManipulate(prevPoint, newPoint, pivotPoint); } SKMatrix matrix = Matrix; SKMatrix.PostConcat(ref matrix, touchMatrix); Matrix = matrix; } } }