You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
9.5 KiB

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<long, TouchManipulationInfo> touchDictionary = new Dictionary<long, TouchManipulationInfo>();
public CardVM Value;
public string display;
private float width;
private float height;
public SKColor Color;
/**
* <param name="textPaint">Objet à dessiner</param>
* <param name="value">Carte dessinée dans le textPaint</param>
* <param name="width">Taille de l'espace entre le centre de la carte et la bordure sur l'axe des x</param>
*
* Constructeur
*/
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();
// Permet de traiter les fractions
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; }
/**
* <param name="canvas">Canvas où l'on souhaite dessiner l'objet contenu dans l'instance</param>
*
* Fonction permettant de dessiner l'objet que contient l'instance dans un canvas donné
*/
public void Paint(SKCanvas canvas)
{
canvas.Save();
SKMatrix matrix = Matrix;
canvas.Concat(ref matrix);
textPaint.Color = Color;
textPaint.StrokeWidth = 5;
textPaint.Style = SKPaintStyle.Fill;
SKRect card;
// Permet de traiter les fractions
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.Fill;
}
else
{
card = new SKRect(-width, -height - textPaint.TextSize, width + textPaint.MeasureText(display), height);
}
SKPaint paint = new SKPaint();
paint.Color = Color;
paint.StrokeWidth = 5;
paint.Style = SKPaintStyle.Stroke;
// Permet de traiter les fractions
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("-");
}
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
{
canvas.DrawRect(card, paint);
canvas.DrawText(display, 0, 0, textPaint);
}
canvas.Restore();
}
/**
* <param name="color">Nouvelle couleur que l'on souhaite attribué à l'objet contenu dans l'instance</param>
*
* Fonction permettant de changer la couleur de l'objet contenu dans l'instance
*/
public void ChangeColor(SKColor color)
{
textPaint.Color = color;
}
/**
* <param name="location">Point que l'on souhaite tester</param>
*
* Fonction permettant de savoir si le point qu'on lui passe est dans la zone où l'objet est dessiné
*
* <returns>Booléen qui indique si le point donné est dans la zone où l'objet en instance est dessiné</returns>
*/
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;
// Permet de traiter les fractions
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;
}
/**
* <param name="id">Index que l'on souhaite traiter</param>
* <param name="type">Type d'évenement lancé</param>
* <param name="location">Nouveau point</param>
*
* 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.
*/
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);
}
}
}
}