Exemplo n.º 1
0
        /// <summary>
        /// Paint text
        /// </summary>
        private void OnPaintText(SKPaintSurfaceEventArgs e)
        {
            SKPaint textPaint = new SKPaint();

            textPaint.Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, TextColor, ToggledTextColor).ToSKColor();
            textPaint.TextSize    = (float)FontSize * DeviceScale;
            textPaint.TextAlign   = SKTextAlign.Left;
            textPaint.IsAntialias = true;

            SKFontStyleSlant  slant      = SkiaUtils.ConvertToSKFontStyle(FontStyle);
            SKFontStyleWeight fontWeight = SkiaUtils.ConvertToSKFontWeight(FontWeight);

            textPaint.Typeface = SKTypeface.FromFamilyName(FontFamily, fontWeight, SKFontStyleWidth.Normal, slant);

            SKRect skTextBounds = new SKRect();

            textPaint.MeasureText(Text, ref skTextBounds);

            float skNegativePadding = (float)EllipseDiameter * DeviceScale;

            float xText = skNegativePadding - skTextBounds.Left + (float)(TextMargin.Left * DeviceScale);
            float yText = -skTextBounds.Top + (e.Info.Height - skTextBounds.Height) / 2;

            double checkBoxWidth = _selectionViewSize.Width;

            if (_selectionViewLocation == HorizontalLocations.Left)
            {
                xText += (float)(checkBoxWidth * DeviceScale);
            }

            float lineHeight       = (float)FontSize * DeviceScale;
            float skAvailableWidth = (float)(Width - checkBoxWidth - TextMargin.HorizontalThickness) * DeviceScale;

            SkiaUtils.DrawTextArea(e.Surface.Canvas, textPaint, xText, yText, skAvailableWidth, lineHeight, IsTextWrapping, Text);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Get background color
 /// </summary>
 protected override Color GetActualBackgroundColor()
 {
     if (AnimationStyle == AnimationStyles.Ellipse)
     {
         if (IsEnabled)
         {
             if (IsOpen)
             {
                 return(AnimationUtils.ColorTransform(_toggledAnimationProcess, BackgroundColor, ToggledBackgroundColor));
             }
             else
             {
                 Color def   = AnimationUtils.ColorTransform(_toggledAnimationProcess, BackgroundColor, ToggledBackgroundColor);
                 Color hover = AnimationUtils.ColorTransform(_toggledAnimationProcess, BackgroundHoverColor, ToggledBackgroundHoverColor);
                 return(AnimationUtils.ColorTransform(_hoverAnimationProcess, def, hover));
             }
         }
         else
         {
             return(BackgroundDisabledColor);
         }
     }
     else
     {
         return(GetColor(
                    BackgroundColor,
                    BackgroundHoverColor,
                    BackgroundPressedColor,
                    ToggledBackgroundColor,
                    ToggledBackgroundHoverColor,
                    ToggledBackgroundPressedColor,
                    BackgroundDisabledColor));
     }
 }
Exemplo n.º 3
0
        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (string.IsNullOrEmpty(Darkness) == false)
            {
                double darkness = 0;
                double.TryParse(Darkness, out darkness);
                return(AnimationUtils.ColorTransform(Math.Min(1, darkness), Source, Color.Black));
            }
            else if (string.IsNullOrEmpty(Lightness) == false)
            {
                double lightness = 0;
                double.TryParse(Lightness, out lightness);

                Color c = AnimationUtils.ColorTransform(Math.Min(1, lightness), Source, Color.White);
                return(c);
            }
            else
            {
                return(Source);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Paint checkbox
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaintSelectionElement(SKPaintSurfaceEventArgs e)
        {
            if (_checkMarkSvg == null && string.IsNullOrEmpty(CheckMarkIconAssemblyName) == false && string.IsNullOrEmpty(CheckMarkIconResourceKey) == false)
            {
                _checkMarkSvg = SvgImage.GetSvgImage(CheckMarkIconAssemblyName, CheckMarkIconResourceKey);
            }

            Rectangle checkBoxAvailableLocation = new Rectangle();
            Rectangle availableSpace            = new Rectangle(EllipseDiameter, EllipseDiameter, Width, Height - Padding.VerticalThickness);

            if (CheckBoxLocation == HorizontalLocations.Left)
            {
                checkBoxAvailableLocation = availableSpace;
            }
            else
            {
                checkBoxAvailableLocation = new Rectangle(availableSpace.Width - CheckBoxWidthRequest - CheckBoxMargin.HorizontalThickness + EllipseDiameter, EllipseDiameter, availableSpace.Width, availableSpace.Height);
            }

            Rectangle checkBoxActualLocation = CheckBoxActualLocation(checkBoxAvailableLocation);

            float skCheckBoxBorderThickness = (float)CheckBoxBorderThickness * DeviceScale;
            float skCheckBoxX      = (float)checkBoxActualLocation.X * DeviceScale;
            float skCheckBoxY      = (float)checkBoxActualLocation.Y * DeviceScale;
            float skCheckBoxWidth  = (float)CheckBoxWidthRequest * DeviceScale;
            float skCheckBoxHeight = (float)CheckBoxHeightRequest * DeviceScale;
            float skCornerRadius   = (float)CheckBoxCornerRadius * DeviceScale;

            SKMatrix checkMarkMatrix   = new SKMatrix();
            SKPoint  checkMarkPosition = new SKPoint();

            Size checkMarkIconSize = new Size(CheckBoxWidthRequest - CheckMarkIconMargin.HorizontalThickness, CheckBoxHeightRequest - CheckMarkIconMargin.VerticalThickness);

            float scale = SvgImage.CalculateScale(_checkMarkSvg.Picture.CullRect.Size, checkMarkIconSize.Width, checkMarkIconSize.Height);

            Size actualCheckMarkIconSize = new Size(_checkMarkSvg.Picture.CullRect.Width * scale, _checkMarkSvg.Picture.CullRect.Height * scale);

            scale = scale * DeviceScale;

            checkMarkPosition.X = (float)skCheckBoxX + (float)((CheckBoxWidthRequest - actualCheckMarkIconSize.Width) / 2) * DeviceScale;
            checkMarkPosition.Y = (float)skCheckBoxY + (float)((CheckBoxHeightRequest - actualCheckMarkIconSize.Height) / 2) * DeviceScale;
            checkMarkMatrix.SetScaleTranslate(scale, scale, checkMarkPosition.X, checkMarkPosition.Y);

            SKRect checkBoxPaintRect = new SKRect(skCheckBoxX + skCheckBoxBorderThickness / 2,
                                                  skCheckBoxY + skCheckBoxBorderThickness / 2,
                                                  skCheckBoxX + skCheckBoxWidth - skCheckBoxBorderThickness / 2,
                                                  skCheckBoxY + skCheckBoxHeight - skCheckBoxBorderThickness / 2);

            if (EllipseDiameter > 0 && _toggledAnimationProcess > 0 && _toggledAnimationProcess < 1 && IsEllipseAnimationEnabled)
            {
                SKPaint ellipsePaint = new SKPaint()
                {
                    IsAntialias = true,
                    Style       = SKPaintStyle.Fill,
                };

                if (_toggledAnimationProcess <= 0.5)
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(_toggledAnimationProcessWithoutEasing * 2).ToSKColor();
                }
                else
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(1 - (_toggledAnimationProcessWithoutEasing - 0.5) * 2).ToSKColor();
                }

                e.Surface.Canvas.DrawCircle(new SKPoint(checkBoxPaintRect.MidX, checkBoxPaintRect.MidY), (float)(EllipseDiameter / 2) * DeviceScale, ellipsePaint);
            }

            Color backgroundColor = Color.Transparent;

            if (CheckBoxBackgroundColor != null && CheckBoxBackgroundColor != Color.Transparent && ToggledCheckBoxBackgroundColor != null && ToggledCheckBoxBackgroundColor != Color.Transparent)
            {
                backgroundColor = AnimationUtils.ColorTransform(_toggledAnimationProcess, CheckBoxBackgroundColor, ToggledCheckBoxBackgroundColor);
            }
            else if ((CheckBoxBackgroundColor == null || CheckBoxBackgroundColor == Color.Transparent) && ToggledCheckBoxBackgroundColor != null && ToggledCheckBoxBackgroundColor != Color.Transparent)
            {
                backgroundColor = ToggledCheckBoxBackgroundColor;
            }
            else
            {
                backgroundColor = CheckBoxBackgroundColor;
            }

            SKPaint checkBoxBackgroundPaint = new SKPaint
            {
                Style       = SKPaintStyle.Fill,
                IsAntialias = true,
                Color       = backgroundColor.ToSKColor(),
            };

            SKRect rect = new SKRect(
                skCheckBoxX + skCheckBoxBorderThickness,
                skCheckBoxY + skCheckBoxBorderThickness,
                skCheckBoxX + skCheckBoxWidth - skCheckBoxBorderThickness,
                skCheckBoxY + skCheckBoxHeight - skCheckBoxBorderThickness);

            e.Surface.Canvas.Save();

            SKRect r = SKRect.Create(rect.Left, rect.Top, rect.Width, rect.Height);

            if (_toggledAnimationProcess <= 0.75)
            {
                float v = (float)(_toggledAnimationProcess * (1 / 0.75));
                r.Inflate(-rect.Width * v / 2, -rect.Height * v / 2);
                e.Surface.Canvas.ClipRect(r, SKClipOperation.Difference);
            }

            e.Surface.Canvas.DrawRoundRect(checkBoxPaintRect, skCornerRadius, skCornerRadius, checkBoxBackgroundPaint);
            e.Surface.Canvas.Restore();

            SKPaint checkBoxBorderPaint = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                IsAntialias = true,
                StrokeWidth = skCheckBoxBorderThickness,
                Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, CheckBoxBorderColor, ToggledCheckBoxBorderColor).ToSKColor(),
            };

            e.Surface.Canvas.DrawRoundRect(checkBoxPaintRect, skCornerRadius, skCornerRadius, checkBoxBorderPaint);

            using (var paint = new SKPaint())
            {
                Color color = Color.Transparent;

                if (_toggledAnimationProcess > 0.75)
                {
                    float v = (float)((_toggledAnimationProcess - 0.75) * (1 / 0.25));
                    color = AnimationUtils.ColorTransform(v, CheckMarkIconColor, ToggledCheckMarkIconColor);
                }

                if (color != Color.Transparent)
                {
                    paint.ColorFilter = SKColorFilter.CreateBlendMode(color.ToSKColor(), SKBlendMode.SrcIn);
                    paint.Style       = SKPaintStyle.Fill;
                    paint.IsAntialias = true;

                    e.Surface.Canvas.DrawPicture(_checkMarkSvg.Picture, ref checkMarkMatrix, paint);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Get color based on IsPressed, IsToggled and animation process.
        /// </summary>
        protected virtual Color GetColor(
            Color defaultColor,
            Color hoverColor,
            Color pressedColor,
            Color toggledColor,
            Color toggledHoverColor,
            Color toggledPressedColor,
            Color disabledColor)
        {
            if (IsEnabled == false)
            {
                return(disabledColor);
            }
            else
            {
                if (_pressedAnimationProcess < 1 || _hoverAnimationProcess < 1 || (_toggledAnimationProcess < 1 && _toggledAnimationProcess > 0))
                {
                    Color def     = AnimationUtils.ColorTransform(_toggledAnimationProcess, defaultColor, toggledColor);
                    Color hover   = AnimationUtils.ColorTransform(_toggledAnimationProcess, hoverColor, toggledHoverColor);
                    Color pressed = AnimationUtils.ColorTransform(_toggledAnimationProcess, pressedColor, toggledPressedColor);

                    Color finalColor = def;

                    finalColor = AnimationUtils.ColorTransform(_hoverAnimationProcess, finalColor, hover);

                    if (_pressedAnimationProcess <= 0.5)
                    {
                        finalColor = AnimationUtils.ColorTransform((_pressedAnimationProcess * 2), finalColor, pressed);
                    }
                    else
                    {
                        finalColor = AnimationUtils.ColorTransform(((_pressedAnimationProcess - 0.5) * 2), pressed, finalColor);
                    }

                    return(finalColor);
                }
                else
                {
                    if (IsPressed)
                    {
                        if (IsToggled)
                        {
                            return(toggledPressedColor);
                        }
                        else
                        {
                            return(pressedColor);
                        }
                    }
                    else if (IsMouseOver)
                    {
                        if (IsToggled)
                        {
                            return(toggledHoverColor);
                        }
                        else
                        {
                            return(hoverColor);
                        }
                    }
                    else
                    {
                        if (IsToggled)
                        {
                            return(toggledColor);
                        }
                        else
                        {
                            return(defaultColor);
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Get actual ellipse background color
 /// </summary>
 protected override Color GetActualEllipseColor()
 {
     return(AnimationUtils.ColorTransform(_toggledAnimationProcess, BackgroundPressedColor, ToggledBackgroundPressedColor));
 }
Exemplo n.º 7
0
        /// <summary>
        /// Paint swich
        /// </summary>
        protected override void OnPaintSelectionElement(SKPaintSurfaceEventArgs e)
        {
            float skTrackCornerRadius    = (float)(_visualSettings.TrackCornerRadius * DeviceScale);
            float skTrackBorderThickness = (float)(_visualSettings.TrackBorderThickness * DeviceScale);
            float skActualTrackHeight    = (float)(_visualSettings.TrackHeightRequest * DeviceScale);
            float skActualTrackWidth     = (float)(_visualSettings.TrackWidthRequest * DeviceScale);

            float skThumbCornerRadius    = (float)(_visualSettings.ThumbCornerRadius * DeviceScale);
            float skThumbBorderThickness = (float)(_visualSettings.ThumbBorderThickness * DeviceScale);
            float skActualThumbHeight    = (float)(_visualSettings.ThumbHeightRequest * DeviceScale);
            float skActualThumbWidth     = (float)(_visualSettings.ThumbWidthRequest * DeviceScale);

            float skHorizontalTextMargin = string.IsNullOrEmpty(Text) == false ? (float)(TextMargin.HorizontalThickness * DeviceScale) : 0;

            float skNegativePadding = (float)NegativePadding * DeviceScale;
            float skWidth           = (float)e.Info.Width;
            float skHeight          = (float)e.Info.Height;

            //
            // Track location
            //

            float skActualTrackCornerRadius = Math.Min(skTrackCornerRadius, Math.Min(skActualTrackHeight, skActualTrackWidth));

            float skStartX = 0;

            if (SwitchLocation == HorizontalLocations.Right)
            {
                if (HorizontalOptions.Alignment == LayoutAlignment.Fill)
                {
                    skStartX = skWidth - skNegativePadding - skActualTrackWidth - (float)((Padding.Right + _visualSettings.ThumbHorizontalNegativeRightPadding) * DeviceScale);
                }
                else
                {
                    skStartX = (float)((_textSize.Width + _visualSettings.ThumbHorizontalNegativeLeftPadding) * DeviceScale) + skHorizontalTextMargin;
                }
            }
            else
            {
                skStartX = skNegativePadding + (float)(Padding.Right + _visualSettings.ThumbHorizontalNegativeRightPadding) * DeviceScale;
            }

            SKRect trackLocation = new SKRect();

            trackLocation.Left   = skStartX;
            trackLocation.Top    = (skHeight - skActualTrackHeight) / 2;
            trackLocation.Right  = trackLocation.Left + skActualTrackWidth;
            trackLocation.Bottom = trackLocation.Top + skActualTrackHeight;

            float skActualThumbCornerRadius = Math.Min(skThumbCornerRadius, Math.Min(skActualThumbHeight / 2, skActualThumbWidth / 2));

            //
            // Thumb location
            //

            SKRect thumbLocation = new SKRect();

            thumbLocation.Left   = trackLocation.Left + (float)(_visualSettings.ThumbPadding.Left * DeviceScale) + (float)_toggledAnimationProcess * (skActualTrackWidth - skActualThumbWidth - (float)(_visualSettings.ThumbPadding.HorizontalThickness * DeviceScale));
            thumbLocation.Top    = (skHeight - skActualThumbHeight + (float)(_visualSettings.ThumbPadding.VerticalThickness * DeviceScale)) / 2;
            thumbLocation.Right  = thumbLocation.Left + skActualThumbWidth;
            thumbLocation.Bottom = thumbLocation.Top + skActualThumbHeight;

            //
            // Draw Thumb ellipse
            //

            if (EllipseDiameter > 0 && _toggledAnimationProcess > 0 && _toggledAnimationProcess < 1 && IsEllipseAnimationEnabled)
            {
                SKPaint ellipsePaint = new SKPaint()
                {
                    IsAntialias = true,
                    Style       = SKPaintStyle.Fill,
                };

                if (_toggledAnimationProcess <= 0.5)
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(_toggledAnimationProcessWithoutEasing * 2).ToSKColor();
                }
                else
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(1 - (_toggledAnimationProcessWithoutEasing - 0.5) * 2).ToSKColor();
                }

                e.Surface.Canvas.DrawCircle(new SKPoint(thumbLocation.MidX, thumbLocation.MidY), (float)(EllipseDiameter / 2) * DeviceScale, ellipsePaint);
            }

            //
            // Draw track
            //

            SKPaint trackPaint = new SKPaint()
            {
                IsAntialias = true,
                Style       = SKPaintStyle.Fill,
                Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, TrackUnToggledColor, TrackToggledColor).ToSKColor(),
            };

            e.Surface.Canvas.DrawRoundRect(trackLocation, skActualTrackCornerRadius, skActualTrackCornerRadius, trackPaint);

            //
            // Draw track border
            //

            if (skTrackBorderThickness > 0)
            {
                SKRect trackBorderLocation = new SKRect();
                trackBorderLocation.Left   = trackLocation.Left + skTrackBorderThickness / 2;
                trackBorderLocation.Top    = trackLocation.Top + (skTrackBorderThickness / 2);
                trackBorderLocation.Right  = trackLocation.Right - (skTrackBorderThickness / 2);
                trackBorderLocation.Bottom = trackLocation.Bottom - (skTrackBorderThickness / 2);

                SKPaint trackBorderPaint = new SKPaint()
                {
                    IsAntialias = true,
                    Style       = SKPaintStyle.Stroke,
                    Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, TrackBorderUnToggledColor, TrackBorderToggledColor).ToSKColor(),
                    StrokeWidth = skTrackBorderThickness,
                };

                e.Surface.Canvas.DrawRoundRect(trackBorderLocation, skActualTrackCornerRadius, skActualTrackCornerRadius, trackBorderPaint);
            }

            //
            // Draw thumb shadow
            //

            if (IsThumbShadowEnabled)
            {
                SKRect shadowLocation = new SKRect();
                shadowLocation.Left   = thumbLocation.Left;
                shadowLocation.Right  = thumbLocation.Right;
                shadowLocation.Top    = thumbLocation.Top + _shadowLenght;
                shadowLocation.Bottom = thumbLocation.Bottom + _shadowLenght;
                SkiaUtils.DrawShadow(e, shadowLocation, skActualThumbCornerRadius, (float)(_shadowLenght * DeviceScale), Color.Black, 0.2, true);
            }

            //
            // Draw thumb
            //

            SKPaint thumbPaint = new SKPaint()
            {
                IsAntialias = true,
                Style       = SKPaintStyle.Fill,
                Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, ThumbUnToggledColor, ThumbToggledColor).ToSKColor(),
            };

            SKRect thumbBackgroundLocation = thumbLocation;

            thumbBackgroundLocation.Inflate(-skThumbBorderThickness / 2, -skThumbBorderThickness / 2);

            e.Surface.Canvas.DrawRoundRect(thumbBackgroundLocation, skActualThumbCornerRadius, skActualThumbCornerRadius, thumbPaint);

            //
            // Draw thumb border
            //

            if (skThumbBorderThickness > 0)
            {
                SKRect thumbBorderLocation = new SKRect();
                thumbBorderLocation.Left   = thumbLocation.Left + (skThumbBorderThickness / 2);
                thumbBorderLocation.Top    = thumbLocation.Top + (skThumbBorderThickness / 2);
                thumbBorderLocation.Right  = thumbLocation.Right - (skThumbBorderThickness / 2);
                thumbBorderLocation.Bottom = thumbLocation.Bottom - (skThumbBorderThickness / 2);

                SKPaint thumbBorderPaint = new SKPaint()
                {
                    IsAntialias = true,
                    Style       = SKPaintStyle.Stroke,
                    Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, ThumbBorderUnToggledColor, ThumbBorderToggledColor).ToSKColor(),
                    StrokeWidth = skThumbBorderThickness,
                };

                e.Surface.Canvas.DrawRoundRect(thumbBorderLocation, skActualThumbCornerRadius, skActualThumbCornerRadius, thumbBorderPaint);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Paint indicator
        /// </summary>
        protected override void OnPaintSelectionElement(SKPaintSurfaceEventArgs e)
        {
            Rectangle availableSpace = new Rectangle(EllipseDiameter, EllipseDiameter, Width, Height - Padding.VerticalThickness);

            Rectangle indicatorActualLocation    = IndicatorActualLocation(availableSpace);
            float     skIndicatorBorderThickness = (float)IndicatorBorderThickness * DeviceScale;
            float     skIndicatorX      = (float)indicatorActualLocation.X * DeviceScale;
            float     skIndicatorY      = (float)indicatorActualLocation.Y * DeviceScale;
            float     skIndicatorWidth  = (float)IndicatorWidthRequest * DeviceScale;
            float     skIndicatorHeight = (float)IndicatorHeightRequest * DeviceScale;

            SKRect indicatorPaintRect = new SKRect(skIndicatorX + skIndicatorBorderThickness / 2,
                                                   skIndicatorY + skIndicatorBorderThickness / 2,
                                                   skIndicatorX + skIndicatorWidth - skIndicatorBorderThickness / 2,
                                                   skIndicatorY + skIndicatorHeight - skIndicatorBorderThickness / 2);

            float skCornerRadius = indicatorPaintRect.Width / 2;

            //
            // Paint ellipse animation
            //

            if (EllipseDiameter > 0 && _ellipseAnimationProcess > 0 && _ellipseAnimationProcess < 1 && IsEllipseAnimationEnabled)
            {
                SKPaint ellipsePaint = new SKPaint()
                {
                    IsAntialias = true,
                    Style       = SKPaintStyle.Fill,
                };

                if (_ellipseAnimationProcess <= 0.5)
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(_ellipseAnimationProcess * 2).ToSKColor();
                }
                else
                {
                    ellipsePaint.Color = EllipseColor.MultiplyAlpha(1 - (_ellipseAnimationProcess - 0.5) * 2).ToSKColor();
                }

                e.Surface.Canvas.DrawCircle(new SKPoint(indicatorPaintRect.MidX, indicatorPaintRect.MidY), (float)(EllipseDiameter / 2) * DeviceScale, ellipsePaint);
            }

            //
            // Paint indicator  background
            //
            SKPaint indicatorBackgroundPaint = new SKPaint
            {
                Style       = SKPaintStyle.Fill,
                IsAntialias = true,
                Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, IndicatorBackgroundColor, ToggledIndicatorBackgroundColor).ToSKColor(),
            };

            e.Surface.Canvas.DrawRoundRect(indicatorPaintRect, skCornerRadius, skCornerRadius, indicatorBackgroundPaint);

            //
            // Paint border
            //
            SKPaint indicatorBorderPaint = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                IsAntialias = true,
                StrokeWidth = skIndicatorBorderThickness,
                Color       = AnimationUtils.ColorTransform(_toggledAnimationProcess, IndicatorBorderColor, ToggledIndicatorBorderColor).ToSKColor(),
            };

            e.Surface.Canvas.DrawRoundRect(indicatorPaintRect, skCornerRadius, skCornerRadius, indicatorBorderPaint);

            //
            // Paint inner indicator
            //

            Color toggledColor = ToggledIndicatorColor;

            if (IndicatorColor != null && IndicatorColor != Color.Transparent && ToggledIndicatorColor != null && ToggledIndicatorColor != Color.Transparent)
            {
                toggledColor = AnimationUtils.ColorTransform(_toggledAnimationProcess, IndicatorColor, ToggledIndicatorColor);
            }

            SKPaint innerIndicatorPaint = new SKPaint
            {
                Style       = SKPaintStyle.Fill,
                IsAntialias = true,
                Color       = toggledColor.ToSKColor(),
            };

            double radius = ((IndicatorWidthRequest / 2) - InnerIndicatorSpacing - IndicatorBorderThickness) * DeviceScale * _toggledAnimationProcess;

            e.Surface.Canvas.DrawCircle(indicatorPaintRect.MidX, indicatorPaintRect.MidY, (float)radius, innerIndicatorPaint);
        }