/// <summary> /// Add submenu icon /// </summary> protected override void OnPaintForeground(SKPaintSurfaceEventArgs e, Rectangle availableSpace) { Size actualSubMenuIconSize = new Size(); if (ItemsSource != null && ItemsSource.Count > 0 && IsSubMenuIconVisible && string.IsNullOrEmpty(SubMenuIconAssemblyName) == false && string.IsNullOrEmpty(SubMenuIconResourceKey) == false) { if (m_subMenuIconSvg == null) { m_subMenuIconSvg = SvgImage.GetSvgImage(SubMenuIconAssemblyName, SubMenuIconResourceKey); } Rectangle subMenuIconActualLocation = new Rectangle( availableSpace.Width - _subMenuIconSize.Width - SubMenuIconMargin.Right, (availableSpace.Height - _subMenuIconSize.Height) / 2, _subMenuIconSize.Height, _subMenuIconSize.Width); float skSubMenuIconX = (float)subMenuIconActualLocation.X * DeviceScale; float skSubMenuIconY = (float)subMenuIconActualLocation.Y * DeviceScale; SKMatrix subMenuIconMatrix = new SKMatrix(); SKPoint subMenuIconPosition = new SKPoint(); float scale = SvgImage.CalculateScale(m_subMenuIconSvg.Picture.CullRect.Size, SubMenuIconWidthRequest, SubMenuIconHeightRequest) * DeviceScale; subMenuIconPosition.X = (float)skSubMenuIconX + (float)((SubMenuIconWidthRequest - _subMenuIconSize.Width) / 2) * DeviceScale; subMenuIconPosition.Y = (float)skSubMenuIconY + (float)((SubMenuIconHeightRequest - _subMenuIconSize.Height) / 2) * DeviceScale; subMenuIconMatrix.SetScaleTranslate(scale, scale, subMenuIconPosition.X, subMenuIconPosition.Y); using (var paint = new SKPaint()) { Color color = GetActualSubMenuIconColor(); paint.ColorFilter = SKColorFilter.CreateBlendMode(color.ToSKColor(), SKBlendMode.SrcIn); paint.Style = SKPaintStyle.Fill; paint.IsAntialias = true; e.Surface.Canvas.DrawPicture(m_subMenuIconSvg.Picture, ref subMenuIconMatrix, paint); } actualSubMenuIconSize = _subMenuIconSize; } base.OnPaintForeground(e, new Rectangle(availableSpace.X + _checkBoxSize.Width, availableSpace.Y, availableSpace.Width - actualSubMenuIconSize.Width - _checkBoxSize.Width, availableSpace.Height)); }
/// <summary> /// Measure icon size /// </summary> private Size MeasureSubMenuIcon(double widthConstraint, double heightConstraint) { if (SubMenuIconWidthRequest >= 0 && SubMenuIconHeightRequest >= 0) { return(new Size(SubMenuIconWidthRequest, SubMenuIconHeightRequest)); } else { if (m_subMenuIconSvg == null) { m_subMenuIconSvg = SvgImage.GetSvgImage(SubMenuIconAssemblyName, SubMenuIconResourceKey); } float scale = SvgImage.CalculateScale(m_subMenuIconSvg.Picture.CullRect.Size, IconWidthRequest, IconHeightRequest); return(new Size(m_subMenuIconSvg.Picture.CullRect.Width * scale, m_subMenuIconSvg.Picture.CullRect.Height * scale)); } }
/// <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); } } }