0

I have a custom control I am working on that uses SkiaSharp to draw some text, While that is working flawlessly the issue I am facing is to find which specific drawn text was Touched.

What I am trying to create is similar to a JumpList, which is able to detect which character was clicked/slid over,

Is there some method or something that tells me which Text was touched? Are there any other workarounds I could use to find this out? If not will I have to manually store this information while I draw text?

My custom control looks like this as of right now;

public class SkiaJumpList : ContentView, IDisposable
{
    private readonly SKCanvasView skiaView;

    public SkiaJumpList()
    {
        skiaView = new SKCanvasView();
        Content = skiaView;
        skiaView.PaintSurface += SkiaView_PaintSurface;
        skiaView.Touch += SkiaView_Touch;
        skiaView.InputTransparent = false;
        skiaView.EnableTouchEvents = true;
    }

    private void SkiaView_Touch(object sender, SKTouchEventArgs e)
    {
        e.Handled = true;
    }

    private void SkiaView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
    {
        e?.Surface?.Canvas?.Clear();
        DrawJumpList(e);
    }

    private void DrawJumpList(SKPaintSurfaceEventArgs e)
    {
        if (e == null)
        {
            throw new ArgumentNullException(nameof(e) + typeof(SKPaintSurfaceEventArgs) + " cannot be null");
        }
        var info = e.Info;
        var canvas = e.Surface?.Canvas;

        IAlphabetProvider provider = new EnglishAlphabetProvider();

        foreach (var alphabet in provider.GetAlphabet().WithIndex())
        {
            var currentAlphabet = alphabet.item.ToString();
            var currentIndex = alphabet.index + 1;
            using var textPaint = new SKPaint() { Color = SKColors.Black };
            textPaint.TextSize = 40;
            textPaint.TextAlign = SKTextAlign.Center;
            var textBounds = new SKRect();
            textPaint.MeasureText(currentAlphabet, ref textBounds);
            float xText = (float)((info.Width / 2.0) - textBounds.MidX);
            float yText = (float)((info.Height / 27.0) * currentIndex);
            canvas.DrawText(currentAlphabet, xText, yText, textPaint);
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~SkiaJumpList()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        skiaView.PaintSurface -= SkiaView_PaintSurface;
        skiaView.Touch -= SkiaView_Touch;
    }
}
FreakyAli
  • 13,349
  • 3
  • 23
  • 63
  • Create a list of ```textBounds``` and then intersect the bounds with Location from ```SkiaView_Touch``` – tval Aug 30 '23 at 14:06
  • Can you Elaborate on what you mean by text bounds? Do you mean the Point for each text that i am drawing? – FreakyAli Aug 30 '23 at 14:20
  • No, in your code posted, you have the bounding box of the text: ```var textBounds = new SKRect();```. SKRect has a 'Contains' method. Check if ```textBounds.Contains(e.Location)``` in your ```SkiaView_Touch``` method. – tval Aug 30 '23 at 14:34
  • 1
    So in theory i will have to create a Dictionary of my Character and its SKRect and then query the clicked location to that SkRect's bounds am i right? – FreakyAli Aug 30 '23 at 14:43
  • Sounds exactly right. – tval Aug 30 '23 at 14:57

0 Answers0