public void HighlightElement(View viewToHighlight, SKCanvasView skCanvasView, Layout <View> formLayout) { IList <View> layoutChildren = formLayout.Children; if (_highlightState == null) { var path = HighlightPath.Create(skCanvasView, layoutChildren, _highlightSettings.StrokeWidth); _highlightState = new HighlightState() { HighlightPath = path }; } HighlightPath highlightPath = _highlightState.HighlightPath; int currHighlightViewId = _highlightState.CurrHighlightedViewId; int iViewIdToHighlight = highlightPath.GetViewId(layoutChildren, viewToHighlight); if (currHighlightViewId == iViewIdToHighlight) { return; } StrokeDash fromDash; if (currHighlightViewId != -1) { fromDash = _highlightState.StrokeDash; } else { fromDash = new StrokeDash(highlightPath.GetDashForView(layoutChildren, iViewIdToHighlight)); } _highlightState.CurrHighlightedViewId = iViewIdToHighlight; StrokeDash 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 (View view in layoutChildren) { int iStrokeDashCount = highlightPath.DashCount; Rectangle 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( x: (float)viewBounds.X, y: (float)viewBounds.Y + (float)viewBounds.Height + (float)strokeWidth / 2); } float xCurr = path.LastPoint.X; float yCurr = path.LastPoint.Y; // Add arch for views except first one if (iStrokeDashCount > 0) { float d = iStrokeDashCount % 2 == 0 ? -1 : 1; float 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); } float 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 float d = iStrokeDashCount % 2 == 0 ? -1 : 1; float 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); } float solidDashLength = new SKPathMeasure(path).Length - dashOffset; var strokeDash = new StrokeDash( intervals: new float[] { solidDashLength, 0 }, phase: -dashOffset); highlightPath.SetDashForView(layoutChildren, view, strokeDash); } // Compute the 2nd value of interval, which is the length of remaining path float pathLength = new SKPathMeasure(path).Length; for (int i = 0; i < highlightPath.DashCount; ++i) { StrokeDash 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 }; float firstDashIntervalOn = highlightPath.FirstDash.Intervals[0]; skPaint.Shader = SKShader.CreateLinearGradient( start: new SKPoint(firstDashIntervalOn * 0.30f, 0), end: new SKPoint(firstDashIntervalOn, 0), colors: new SKColor[] { highlightSettings.StrokeStartColor.ToSKColor(), highlightSettings.StrokeEndColor.ToSKColor() }, colorPos: new float[] { 0, 1 }, mode: SKShaderTileMode.Clamp); return(skPaint); }