protected virtual void OnTouchPointTouched(GestureTouchPoint gtp)
 {
     if (this.Vibrate && CrossVibrate.Current.CanVibrate)
     {
         CrossVibrate.Current.Vibration(TimeSpan.FromMilliseconds(100));
     }
     this.TouchPointTouched?.Invoke(this, new TouchPointTouchedEventArgs(gtp));
 }
        private bool TouchedTouchPoint(Point location, GestureTouchPoint touchPoint)
        {
            // Touch point touched?
            if (location.X >= touchPoint.Location.X &&
                location.X <= (touchPoint.Location.X + touchPoint.Width) &&
                location.Y >= touchPoint.Location.Y &&
                location.Y <= (touchPoint.Location.Y + touchPoint.Height))
            {
                return(true);
            }

            // Touch point touched by drawing line?
            if (_fixedPoints.Any())
            {
                Point lineStartPoint = _fixedPoints.Last();
                Point lineEndPoint   = location;

                return(this.PointOnLineSegment(lineStartPoint, lineEndPoint, touchPoint.Center, _tpRadius * 1.6));
            }
            return(false);
        }
 public TouchPointTouchedEventArgs(GestureTouchPoint gtp)
 {
     this.TouchPoint = gtp;
 }
        private void CanvasOnPaintSurface(object o, SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;

            canvas.Clear();

            bool recreateTouchPoints = false;

            if (_width != canvas.LocalClipBounds.Width || _heigth != canvas.LocalClipBounds.Height)
            {
                _width              = canvas.LocalClipBounds.Width;
                _heigth             = canvas.LocalClipBounds.Height;
                recreateTouchPoints = true;
            }

            var cellWidth  = _width / this.HorizontalTouchPoints;
            var cellHeight = _heigth / this.VerticalTouchPoints;

            if (recreateTouchPoints)
            {
                _touchPoints.Clear();

                for (int yAxisIndex = 0; yAxisIndex < this.VerticalTouchPoints; yAxisIndex++)
                {
                    for (int xAxisIndex = 0; xAxisIndex < this.HorizontalTouchPoints; xAxisIndex++)
                    {
                        double x = (cellWidth / 8) + (cellWidth * xAxisIndex);
                        double y = (cellWidth / 8) + (cellHeight * yAxisIndex);

                        double centerX = x + (cellWidth / 2);
                        double centerY = y + (cellHeight / 2);

                        var gtp = new GestureTouchPoint()
                        {
                            Value     = (_touchPoints.Count + 1).ToString(),
                            Width     = cellWidth / 4,
                            Height    = cellHeight / 4,
                            IsTouched = false,
                            Location  = new Point(centerX - (cellWidth / 4), centerY - (cellHeight / 4))
                        };
                        _touchPoints.Add(gtp);
                    }
                }
            }

            SKPaint skPaintTouchPoint = new SKPaint
            {
                Style       = SKPaintStyle.StrokeAndFill,
                Color       = this.TouchPointColor.ToSKColor(),
                StrokeWidth = this.TouchPointStrokeWidth
            };
            SKPaint skPaintTouchPointTouched = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                Color       = this.TouchPointHighlightColor.ToSKColor(),
                StrokeWidth = this.TouchPointTouchedStrokeWidth
            };
            SKPaint skPaintTouchPointTouchedInnerCircle = new SKPaint
            {
                Style       = SKPaintStyle.StrokeAndFill,
                Color       = this.LineDrawnColor.ToSKColor(),
                StrokeWidth = this.TouchPointInnerCircleStrokeWidth
            };
            SKPaint skPaintLineDrawing = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                Color       = this.LineDrawingColor.ToSKColor(),
                StrokeWidth = this.LineDrawingStrokeWidth
            };
            SKPaint skPaintLineDrawn = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                Color       = this.LineDrawnColor.ToSKColor(),
                StrokeWidth = this.LineDrawnStrokeWidth
            };

            // Paint the touchpoints.
            _tpRadius = ((cellHeight + cellWidth) / 2) * 0.05;
            foreach (var touchPoint in _touchPoints)
            {
                // DEBUG: draw the touchpoint location
                //canvas.DrawLine((float)touchPoint.Location.X, (float)touchPoint.Location.Y, (float)(touchPoint.Location.X + touchPoint.Width), (float)touchPoint.Location.Y, skPaintLineDrawing);
                //canvas.DrawLine((float)touchPoint.Location.X, (float)touchPoint.Location.Y, (float)touchPoint.Location.X, (float)(touchPoint.Location.Y + touchPoint.Height), skPaintLineDrawing);

                canvas.DrawCircle((float)touchPoint.Center.X, (float)touchPoint.Center.Y, (float)_tpRadius, skPaintTouchPoint);
            }

            // Any touched points?
            if (_fixedPoints.Count == 0)
            {
                return;
            }

            // Paint the fixed points.
            double tpInnerRadius = _tpRadius / 3;
            double tpOuterRadius = _tpRadius * 3;

            canvas.DrawCircle((float)_fixedPoints.First().X, (float)_fixedPoints.First().Y, (float)tpOuterRadius, skPaintTouchPointTouched);
            canvas.DrawCircle((float)_fixedPoints.First().X, (float)_fixedPoints.First().Y, (float)tpInnerRadius, skPaintTouchPointTouchedInnerCircle);
            for (int i = 1; i < _fixedPoints.Count; i++)
            {
                float xStart = (float)_fixedPoints[i - 1].X;
                float yStart = (float)_fixedPoints[i - 1].Y;
                float xEnd   = (float)_fixedPoints[i].X;
                float yEnd   = (float)_fixedPoints[i].Y;
                canvas.DrawLine(xStart, yStart, xEnd, yEnd, skPaintLineDrawn);
                canvas.DrawCircle((float)_fixedPoints[i].X, (float)_fixedPoints[i].Y, (float)tpOuterRadius, skPaintTouchPointTouched);
                canvas.DrawCircle((float)_fixedPoints[i].X, (float)_fixedPoints[i].Y, (float)tpInnerRadius, skPaintTouchPointTouchedInnerCircle);
            }
            // Paint the pending point.
            if (_pendingPoint != Point.Zero)
            {
                float xStart = (float)_fixedPoints.Last().X;
                float yStart = (float)_fixedPoints.Last().Y;
                float xEnd   = (float)_pendingPoint.X;
                float yEnd   = (float)_pendingPoint.Y;
                canvas.DrawLine(xStart, yStart, xEnd, yEnd, skPaintLineDrawing);
            }
        }