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.
104 lines
3.7 KiB
104 lines
3.7 KiB
using System;
|
|
using SkiaSharp;
|
|
|
|
namespace TheGameExtreme.view
|
|
{
|
|
public class MatrixDisplay
|
|
{
|
|
public SKPaint MatrixPaint { set; get; } = new SKPaint
|
|
{
|
|
Color = SKColors.Black,
|
|
TextSize = 48,
|
|
StrokeWidth = 2
|
|
};
|
|
|
|
public string PerspectiveFormat { set; get; } = "F0";
|
|
|
|
public SKSize Measure(SKMatrix matrix)
|
|
{
|
|
return MeasureAndPaint(null, matrix, new SKPoint(), false);
|
|
}
|
|
|
|
public void Paint(SKCanvas canvas, SKMatrix matrix, SKPoint location)
|
|
{
|
|
MeasureAndPaint(canvas, matrix, location, true);
|
|
}
|
|
|
|
SKSize MeasureAndPaint(SKCanvas canvas, SKMatrix matrix, SKPoint location, bool doPaint)
|
|
{
|
|
float[] values = matrix.Values;
|
|
string[] texts = new string[9];
|
|
SKRect[] bounds = new SKRect[9];
|
|
float[] widths = new float[3];
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
{
|
|
int row = i % 3;
|
|
int col = i / 3;
|
|
|
|
// Format string differently based on row
|
|
texts[i] = values[i].ToString(row == 2 ? "F0" : (col == 2 ? PerspectiveFormat : "F2"));
|
|
|
|
// Measure string with a '-' even if one is not present
|
|
bool isNegative = texts[i][0] == '-';
|
|
string text = (isNegative ? "" : "-") + texts[i];
|
|
MatrixPaint.MeasureText(text, ref bounds[i]);
|
|
|
|
// Get maximum width for each column
|
|
widths[col] = Math.Max(widths[col], bounds[i].Width);
|
|
|
|
// Measure the text again without the '-' in front
|
|
MatrixPaint.MeasureText(texts[i], ref bounds[i]);
|
|
}
|
|
|
|
// Some formatting constants
|
|
float horzGap = MatrixPaint.TextSize;
|
|
float horzMarg = MatrixPaint.TextSize;
|
|
float vertMarg = MatrixPaint.FontSpacing / 4;
|
|
|
|
// Calculate the total width and height of the matrix display
|
|
float totalWidth = widths[0] + widths[1] + widths[2] + 2 * horzGap + 2 * horzMarg;
|
|
float totalHeight = 3 * MatrixPaint.FontSpacing + 2 * vertMarg;
|
|
|
|
if (doPaint)
|
|
{
|
|
SKPaintStyle saveStyle = MatrixPaint.Style;
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
{
|
|
int row = i % 3;
|
|
int col = i / 3;
|
|
|
|
// Find x, y of upper-left corner of text
|
|
float x = location.X + horzMarg;
|
|
|
|
for (int c = 0; c < col; c++)
|
|
{
|
|
x += widths[c] + horzGap;
|
|
}
|
|
|
|
float y = location.Y + vertMarg + row * MatrixPaint.FontSpacing;
|
|
|
|
// Adjust for right-justified text
|
|
x += widths[col] - bounds[i].Width;
|
|
y += (MatrixPaint.FontSpacing - bounds[i].Height) / 2 - bounds[i].Top;
|
|
|
|
// Draw the text
|
|
MatrixPaint.Style = SKPaintStyle.Fill;
|
|
canvas.DrawText(texts[i], x, y, MatrixPaint);
|
|
}
|
|
|
|
// Display vertical lines at the sides of the matrix
|
|
MatrixPaint.Style = SKPaintStyle.Stroke;
|
|
canvas.DrawLine(location.X + horzMarg / 2, location.Y + vertMarg,
|
|
location.X + horzMarg / 2, location.Y + totalHeight - vertMarg, MatrixPaint);
|
|
canvas.DrawLine(location.X + totalWidth - horzMarg / 2, location.Y + vertMarg,
|
|
location.X + totalWidth - horzMarg / 2, location.Y + totalHeight - vertMarg, MatrixPaint);
|
|
|
|
MatrixPaint.Style = saveStyle;
|
|
}
|
|
return new SKSize(totalWidth, totalHeight);
|
|
}
|
|
}
|
|
}
|