public void HighlightElement(View viewToHighlight, SKCanvasView skCanvasView, Layout <View> formLayout) { var layoutChildren = formLayout.Children; if (_highlightState == null) { _highlightState = new HighlightState() { HighlightPath = HighlightPath.Create(skCanvasView, layoutChildren, _highlightSettings.StrokeWidth) }; } var highlightPath = _highlightState.HighlightPath; var currHighlightViewId = _highlightState.CurrHighlightedViewId; var iViewIdToHighlight = highlightPath.GetViewId(layoutChildren, viewToHighlight); if (currHighlightViewId == iViewIdToHighlight) { return; } var fromDash = currHighlightViewId != -1 ? _highlightState.StrokeDash : new StrokeDash(highlightPath.GetDashForView(layoutChildren, iViewIdToHighlight)); _highlightState.CurrHighlightedViewId = iViewIdToHighlight; var toDash = new StrokeDash(highlightPath.GetDashForView(layoutChildren, viewToHighlight)); DrawDash(skCanvasView, fromDash, toDash); }
public static HighlightPath Create(SKCanvasView skCanvasView, IList <View> layoutChildren, double strokeWidth) { var path = new SKPath(); var highlightPath = new HighlightPath() { Path = path }; strokeWidth = (float)skCanvasView.FromPixels(new Point(0, strokeWidth)).Y; foreach (var view in layoutChildren) { var iStrokeDashCount = highlightPath.DashCount; var viewBounds = skCanvasView.FromPixels(view.Bounds); if (!(view is Entry) && !(view is Button)) { continue; } if (path.Points.Length == 0) { // Move path point at the left and below of the view path.MoveTo((float)viewBounds.X, (float)viewBounds.Y + (float)viewBounds.Height + (float)strokeWidth / 2); } var xCurr = path.LastPoint.X; var yCurr = path.LastPoint.Y; // Add arch for views except first one if (iStrokeDashCount > 0) { var d = iStrokeDashCount % 2 == 0 ? -1 : 1; var arcHeight = (float)viewBounds.Y + (float)viewBounds.Height - path.LastPoint.Y + (float)strokeWidth / 2; path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr, xCurr + arcHeight / 2, yCurr + arcHeight), -90, 180 * d, false); } var dashOffset = new SKPathMeasure(path).Length; // Add line below the view // If it's not the first view, the start point is the end from arc end point // and line direction is either to view start or view end path.LineTo((float)viewBounds.X + (float)viewBounds.Width * (iStrokeDashCount % 2 == 0 ? 1 : 0), path.LastPoint.Y); if (view is Button) { xCurr = path.LastPoint.X; yCurr = path.LastPoint.Y; // Draw arc from below button to above button var d = iStrokeDashCount % 2 == 0 ? -1 : 1; var arcHeight = (float)viewBounds.Height + (float)strokeWidth; path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr - arcHeight, xCurr + arcHeight / 2, yCurr), 90, 180 * d, false); // Draw horizontal line above the button path.LineTo(xCurr + (float)viewBounds.Width * d, path.LastPoint.Y); // Draw arc pointing down xCurr = path.LastPoint.X; yCurr = path.LastPoint.Y; path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr, xCurr + arcHeight / 2, yCurr + arcHeight), -90, 180 * d, false); } var solidDashLength = new SKPathMeasure(path).Length - dashOffset; var strokeDash = new StrokeDash(new float[] { solidDashLength, 0 }, -dashOffset); highlightPath.SetDashForView(layoutChildren, view, strokeDash); } // Compute the 2nd value of interval, which is the length of remaining path var pathLength = new SKPathMeasure(path).Length; for (int i = 0; i < highlightPath.DashCount; ++i) { var d = highlightPath.GetDash(i); d.Intervals[1] = pathLength - d.Intervals[0]; } return(highlightPath); }
static SKPaint CreateHighlightSkPaint(SKCanvasView skCanvasView, HighlightSettings highlightSettings, HighlightPath highlightPath) { var skPaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = (float)skCanvasView.FromPixels(new Point(0, highlightSettings.StrokeWidth)).Y }; var firstDashIntervalOn = highlightPath.FirstDash.Intervals[0]; skPaint.Shader = SKShader.CreateLinearGradient( new SKPoint(firstDashIntervalOn * 0.30f, 0), new SKPoint(firstDashIntervalOn, 0), new SKColor[] { highlightSettings.StrokeStartColor.ToSKColor(), highlightSettings.StrokeEndColor.ToSKColor() }, new float[] { 0, 1 }, SKShaderTileMode.Clamp ); return(skPaint); }