using System; using System.Collections.Generic; using OrderStacks.viewmodel; using SkiaSharp; using TouchTracking; using Xamarin.Essentials; namespace OrderStacks.view { /** * Classe permettant de gérer un objet dessiné dans un canvas */ public class TouchManipulationCard { public SKPoint InitialPoint { get; set; } SKPaint textPaint; SKPaint textPaint1; SKPaint textPaint2; Dictionary touchDictionary = new Dictionary(); public CardVM Value; public string display; private float width; private float height; public SKColor Color; /** * Objet dessiné * Carte qui est dessiné par le textPaint */ public TouchManipulationCard(SKPaint textPaint, CardVM value, float width) { this.textPaint = textPaint; Value = value; this.width = width; height = (0.2f * (float)DeviceDisplay.MainDisplayInfo.Height - textPaint.TextSize) * 0.5f; display = Value.ToString(); if (Value.GetType() == typeof(FractionCardVM)) { textPaint1 = new SKPaint(); textPaint2 = new SKPaint(); textPaint1.TextSize = textPaint.TextSize; textPaint2.TextSize = textPaint.TextSize; } else { if (!display.Contains(",") && !display.Contains(".") && !display.Contains("/")) { if (Value.Value.CompareTo(-10m) <= 0) { this.width -= textPaint.MeasureText("0") * 0.25f; } if (Value.Value.CompareTo(0m) >= 0 && Value.Value.CompareTo(10) < 0) { this.width += textPaint.MeasureText("0") * 0.5f; } } } Matrix = SKMatrix.MakeIdentity(); Mode = TouchManipulationMode.PanOnly; } public TouchManipulationMode Mode { set; get; } public SKMatrix Matrix { set; get; } public SKMatrix InitialMatrix { set; get; } /** * Fonction permettant de dessiner l'objet que contient l'instance dans un canvas donné avec une couleur donnée * Canvas où l'on souhaite dessiner l'objet contenu dans l'instance * Couleur qui sera prise par l'objet */ public void Paint(SKCanvas canvas) { canvas.Save(); SKMatrix matrix = Matrix; canvas.Concat(ref matrix); textPaint.Color = Color; textPaint.StrokeWidth = 5; textPaint.Style = SKPaintStyle.StrokeAndFill; SKRect card; if (Value.GetType() == typeof(FractionCardVM)) { card = new SKRect(-width, -height - textPaint.TextSize, width + textPaint.MeasureText(Math.Pow(10, ((FractionCardVM)(Value)).Fraction.SizeMax-1).ToString()), height); textPaint1.Color = Color; textPaint1.StrokeWidth = 5; textPaint1.Style = SKPaintStyle.StrokeAndFill; textPaint2.Color = Color; textPaint2.StrokeWidth = 5; textPaint2.Style = SKPaintStyle.StrokeAndFill; } else { card = new SKRect(-width, -height - textPaint.TextSize, width + textPaint.MeasureText(display), height); } if (Value.GetType() == typeof(FractionCardVM)) { int sizeMax = ((FractionCardVM)(Value)).Fraction.SizeMax; float xNum = textPaint.MeasureText(Math.Pow(10, sizeMax-2).ToString()); float xDen = textPaint.MeasureText(Math.Pow(10, sizeMax-2).ToString()); int tailleNum = Math.Abs(((FractionCardVM)(Value)).Fraction.Numerateur); int tailleDen = Math.Abs(((FractionCardVM)(Value)).Fraction.Denominateur); if (tailleNum == 0) { tailleNum += 1; } if (tailleDen == 0) { tailleDen += 1; } string fractionBarre = "___"; for (int i = 2; i < sizeMax; i++){ fractionBarre += "_"; } while (tailleNum > 9) { xNum -= textPaint.MeasureText("0"); tailleNum /= 10; } while (tailleDen > 9) { xDen -= textPaint2.MeasureText("0"); tailleDen /= 10; } if (((FractionCardVM)(Value)).Fraction.Numerateur < 0) { xNum -= textPaint.MeasureText("-"); } if (((FractionCardVM)(Value)).Fraction.Denominateur < 0) { xDen -= textPaint2.MeasureText("-"); } SKPaint paint = textPaint1; paint.Style = SKPaintStyle.Stroke; canvas.DrawRect(card, paint); canvas.DrawText(((FractionCardVM)Value).Fraction.Numerateur.ToString(), xNum, -height * 0.5f, textPaint); canvas.DrawText(fractionBarre, -textPaint1.MeasureText("_") * 0.5f, -textPaint1.TextSize * 0.5f, textPaint1); canvas.DrawText(((FractionCardVM)Value).Fraction.Denominateur.ToString(), xDen, height * 0.5f, textPaint2); } else { SKPaint paint = textPaint; paint.Style = SKPaintStyle.Stroke; canvas.DrawRect(card, paint); canvas.DrawText(display, 0, 0, textPaint); } canvas.Restore(); } /** * Fonction permettant de changer la couleur de l'objet contenu dans l'instance * Nouvelle couleur que l'on souhaite attribué à l'objet contenu dans l'instance */ public void ChangeColor(SKColor color) { textPaint.Color = color; } /** * Fonction permettant de savoir si le point qu'on lui passe est dans la zone où l'objet est dessiné * Point que l'on souhaite tester * Booléen qui indique si le point donné est dans la zone où l'objet en instance est dessiné */ 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; if (Value.GetType() == typeof(FractionCardVM)) { rect = new SKRect(-width, -height - textPaint.TextSize, width + textPaint.MeasureText(Math.Pow(10, ((FractionCardVM)(Value)).Fraction.SizeMax - 1).ToString()), height); } else { rect = new SKRect(-width, -height - textPaint.TextSize, width + textPaint.MeasureText(display), height); } return rect.Contains(transformedPoint); } return false; } /** * Evénement qui permet de gérer le Drag and Drop. * Il permet de traiter le clic, le mouvement, le relachement du clic et la fin de traitement d'un objet. * Index de la position que l'on souhaite traiter * Type d'évenement lancé * Nouveau point que l'on souhaite traiter */ public void ProcessTouchEvent(long id, TouchActionType type, SKPoint location) { 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: case TouchActionType.Cancelled: touchDictionary.Remove(id); break; } } /** * Fonction permettant de traiter un déplacement de l'objet en instance */ private void Manipulate() { TouchManipulationInfo[] infos = new TouchManipulationInfo[touchDictionary.Count]; touchDictionary.Values.CopyTo(infos, 0); if (Mode == TouchManipulationMode.PanOnly) { Matrix = SKMatrix.MakeTranslation(infos[0].NewPoint.X, infos[0].NewPoint.Y); } } } }