BoxView completed

This commit is contained in:
2026-01-16 05:31:09 +00:00
parent 85b3c22dc7
commit 538d4bad65
2 changed files with 70 additions and 15 deletions

View File

@@ -34,17 +34,13 @@ public partial class BoxViewHandler : ViewHandler<BoxView, SkiaBoxView>
{ {
if (boxView.Color != null) if (boxView.Color != null)
{ {
handler.PlatformView.Color = new SKColor( handler.PlatformView.Color = boxView.Color;
(byte)(boxView.Color.Red * 255),
(byte)(boxView.Color.Green * 255),
(byte)(boxView.Color.Blue * 255),
(byte)(boxView.Color.Alpha * 255));
} }
} }
public static void MapCornerRadius(BoxViewHandler handler, BoxView boxView) public static void MapCornerRadius(BoxViewHandler handler, BoxView boxView)
{ {
handler.PlatformView.CornerRadius = (float)boxView.CornerRadius.TopLeft; handler.PlatformView.CornerRadius = boxView.CornerRadius;
} }
public static void MapBackground(BoxViewHandler handler, BoxView boxView) public static void MapBackground(BoxViewHandler handler, BoxView boxView)

View File

@@ -2,47 +2,100 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Controls; using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
/// <summary> /// <summary>
/// Skia-rendered BoxView - a simple colored rectangle. /// Skia-rendered BoxView - a simple colored rectangle.
/// Implements MAUI IBoxView interface patterns.
/// </summary> /// </summary>
public class SkiaBoxView : SkiaView public class SkiaBoxView : SkiaView
{ {
#region BindableProperties
public static readonly BindableProperty ColorProperty = public static readonly BindableProperty ColorProperty =
BindableProperty.Create(nameof(Color), typeof(SKColor), typeof(SkiaBoxView), SKColors.Transparent, BindableProperty.Create(nameof(Color), typeof(Color), typeof(SkiaBoxView), Colors.Transparent,
BindingMode.TwoWay, propertyChanged: (b, o, n) => ((SkiaBoxView)b).Invalidate()); BindingMode.TwoWay, propertyChanged: (b, o, n) => ((SkiaBoxView)b).Invalidate());
public static readonly BindableProperty CornerRadiusProperty = public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create(nameof(CornerRadius), typeof(float), typeof(SkiaBoxView), 0f, BindableProperty.Create(nameof(CornerRadius), typeof(CornerRadius), typeof(SkiaBoxView), new CornerRadius(0),
BindingMode.TwoWay, propertyChanged: (b, o, n) => ((SkiaBoxView)b).Invalidate()); BindingMode.TwoWay, propertyChanged: (b, o, n) => ((SkiaBoxView)b).Invalidate());
public SKColor Color #endregion
#region Properties
public Color Color
{ {
get => (SKColor)GetValue(ColorProperty); get => (Color)GetValue(ColorProperty);
set => SetValue(ColorProperty, value); set => SetValue(ColorProperty, value);
} }
public float CornerRadius public CornerRadius CornerRadius
{ {
get => (float)GetValue(CornerRadiusProperty); get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value); set => SetValue(CornerRadiusProperty, value);
} }
#endregion
#region Helper Methods
/// <summary>
/// Converts a MAUI Color to SkiaSharp SKColor.
/// </summary>
private static SKColor ToSKColor(Color? color)
{
if (color == null) return SKColors.Transparent;
return new SKColor(
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
}
#endregion
#region Drawing
protected override void OnDraw(SKCanvas canvas, SKRect bounds) protected override void OnDraw(SKCanvas canvas, SKRect bounds)
{ {
SKColor fillColor = ToSKColor(Color);
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = Color, Color = fillColor,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
if (CornerRadius > 0) // Check if any corner radius is set
var cr = CornerRadius;
bool hasRadius = cr.TopLeft > 0 || cr.TopRight > 0 || cr.BottomLeft > 0 || cr.BottomRight > 0;
if (hasRadius)
{ {
canvas.DrawRoundRect(bounds, CornerRadius, CornerRadius, paint); // Check if all corners are the same (uniform radius)
if (cr.TopLeft == cr.TopRight && cr.TopRight == cr.BottomRight && cr.BottomRight == cr.BottomLeft)
{
canvas.DrawRoundRect(bounds, (float)cr.TopLeft, (float)cr.TopLeft, paint);
}
else
{
// Different corner radii - use SKRoundRect with individual radii
var radii = new SKPoint[]
{
new SKPoint((float)cr.TopLeft, (float)cr.TopLeft),
new SKPoint((float)cr.TopRight, (float)cr.TopRight),
new SKPoint((float)cr.BottomRight, (float)cr.BottomRight),
new SKPoint((float)cr.BottomLeft, (float)cr.BottomLeft)
};
var roundRect = new SKRoundRect();
roundRect.SetRectRadii(bounds, radii);
canvas.DrawRoundRect(roundRect, paint);
}
} }
else else
{ {
@@ -50,6 +103,10 @@ public class SkiaBoxView : SkiaView
} }
} }
#endregion
#region Measurement
protected override SKSize MeasureOverride(SKSize availableSize) protected override SKSize MeasureOverride(SKSize availableSize)
{ {
// BoxView uses explicit size or a default size when in unbounded context // BoxView uses explicit size or a default size when in unbounded context
@@ -64,4 +121,6 @@ public class SkiaBoxView : SkiaView
return new SKSize(width, height); return new SKSize(width, height);
} }
#endregion
} }