diff --git a/src/Controls/samples/Controls.Sample/Pages/Controls/BoxViewPage.xaml b/src/Controls/samples/Controls.Sample/Pages/Controls/BoxViewPage.xaml index 1f6776267a69..3e2578d82d7f 100644 --- a/src/Controls/samples/Controls.Sample/Pages/Controls/BoxViewPage.xaml +++ b/src/Controls/samples/Controls.Sample/Pages/Controls/BoxViewPage.xaml @@ -4,37 +4,51 @@ x:Class="Maui.Controls.Sample.Pages.BoxViewPage" xmlns:views="clr-namespace:Maui.Controls.Sample.Pages.Base" Title="BoxView"> - - + + + - + \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample/Pages/Controls/ShapesPage.xaml b/src/Controls/samples/Controls.Sample/Pages/Controls/ShapesPage.xaml index 44b96e41db8c..df6b0ff75438 100644 --- a/src/Controls/samples/Controls.Sample/Pages/Controls/ShapesPage.xaml +++ b/src/Controls/samples/Controls.Sample/Pages/Controls/ShapesPage.xaml @@ -4,76 +4,80 @@ x:Class="Maui.Controls.Sample.Pages.ShapesPage" xmlns:views="clr-namespace:Maui.Controls.Sample.Pages.Base" Title="Shapes"> - - - - - - + + + + + \ No newline at end of file diff --git a/src/Controls/src/Core/HandlerImpl/BoxView.Impl.cs b/src/Controls/src/Core/HandlerImpl/BoxView.Impl.cs index 04a55fa481dd..e8b33e61d5d6 100644 --- a/src/Controls/src/Core/HandlerImpl/BoxView.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/BoxView.Impl.cs @@ -1,7 +1,50 @@ -namespace Microsoft.Maui.Controls +#nullable enable +using System.Runtime.CompilerServices; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Controls { - public partial class BoxView : IBoxView + public partial class BoxView : IShapeView, IShape { + protected override void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + base.OnPropertyChanged(propertyName); + + if (propertyName == ColorProperty.PropertyName || + propertyName == CornerRadiusProperty.PropertyName) + Handler?.UpdateValue(nameof(IShapeView.Shape)); + } + + IShape? IShapeView.Shape => this; + + PathAspect IShapeView.Aspect => PathAspect.None; + + Paint? IShapeView.Fill => Color?.AsPaint() ?? ((IView)this).Background; + + Paint? IShapeView.Stroke => null; + + double IShapeView.StrokeThickness => 0; + + LineCap IShapeView.StrokeLineCap => LineCap.Butt; + + LineJoin IShapeView.StrokeLineJoin => LineJoin.Miter; + + float[]? IShapeView.StrokeDashPattern => null; + + float IShapeView.StrokeMiterLimit => 0; + + PathF IShape.PathForBounds(Rectangle bounds) + { + var path = new PathF(); + + path.AppendRoundedRectangle( + bounds, + (float)CornerRadius.TopLeft, + (float)CornerRadius.TopRight, + (float)CornerRadius.BottomLeft, + (float)CornerRadius.BottomRight); + return path; + } } } \ No newline at end of file diff --git a/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs b/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs index 5447a958daec..1084260fb801 100644 --- a/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs +++ b/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs @@ -14,7 +14,7 @@ public static partial class AppHostBuilderExtensions { typeof(Shell), typeof(ShellHandler) }, #endif { typeof(ActivityIndicator), typeof(ActivityIndicatorHandler) }, - { typeof(BoxView), typeof(BoxViewHandler) }, + { typeof(BoxView), typeof(ShapeViewHandler) }, { typeof(Button), typeof(ButtonHandler) }, { typeof(CheckBox), typeof(CheckBoxHandler) }, { typeof(DatePicker), typeof(DatePickerHandler) }, diff --git a/src/Core/src/Core/IBoxView.cs b/src/Core/src/Core/IBoxView.cs deleted file mode 100644 index 6af6403c98bb..000000000000 --- a/src/Core/src/Core/IBoxView.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.Maui.Graphics; - -namespace Microsoft.Maui -{ - /// - /// BoxView renders a simple rectangle of a specified width, height, and color. - /// - public interface IBoxView : IView - { - /// - /// Gets the color which will fill the rectangle. - /// - Color Color { get; } - - /// - /// Gets the corner radius for the box view. - /// - CornerRadius CornerRadius { get; } - } -} \ No newline at end of file diff --git a/src/Core/src/Graphics/IShapeView.cs b/src/Core/src/Core/IShapeView.cs similarity index 95% rename from src/Core/src/Graphics/IShapeView.cs rename to src/Core/src/Core/IShapeView.cs index d40e3f400c43..ac6919366e84 100644 --- a/src/Core/src/Graphics/IShapeView.cs +++ b/src/Core/src/Core/IShapeView.cs @@ -1,4 +1,6 @@ -namespace Microsoft.Maui.Graphics +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui { /// /// Represents a View that enables you to draw a shape to the screen. diff --git a/src/Core/src/Graphics/BoxViewDrawable.cs b/src/Core/src/Graphics/BoxViewDrawable.cs deleted file mode 100644 index 8361789d31a2..000000000000 --- a/src/Core/src/Graphics/BoxViewDrawable.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Microsoft.Maui.Graphics; - -namespace Microsoft.Maui.Graphics -{ - public class BoxViewDrawable : IDrawable - { - public BoxViewDrawable() - { - - } - - public BoxViewDrawable(IBoxView? boxView) - { - BoxView = boxView; - } - - public IBoxView? BoxView { get; set; } - - public void Draw(ICanvas canvas, RectangleF dirtyRect) - { - var rect = dirtyRect; - - var path = new PathF(); - - float x = dirtyRect.X; - float y = dirtyRect.Y; - float w = dirtyRect.Width; - float h = dirtyRect.Height; - - float topLeftCornerRadius = 0; - float topRightCornerRadius = 0; - float bottomLeftCornerRadius = 0; - float bottomRightCornerRadius = 0; - - if (BoxView?.CornerRadius != null) - { - topLeftCornerRadius = (float)BoxView.CornerRadius.TopLeft; - topRightCornerRadius = (float)BoxView.CornerRadius.TopRight; - bottomLeftCornerRadius = (float)BoxView.CornerRadius.BottomLeft; - bottomRightCornerRadius = (float)BoxView.CornerRadius.BottomRight; - } - - path.AppendRoundedRectangle(x, y, w, h, topLeftCornerRadius, topRightCornerRadius, bottomLeftCornerRadius, bottomRightCornerRadius); - - DrawBoxView(canvas, rect, path); - } - - void DrawBoxView(ICanvas canvas, RectangleF dirtyRect, PathF path) - { - if (BoxView == null) - return; - - if (!path.Closed) - return; - - canvas.SaveState(); - - // Set BackgroundColor - if (BoxView.Color != null) - canvas.FillColor = BoxView.Color; - else - canvas.SetFillPaint(BoxView.Background, dirtyRect); - - canvas.FillPath(path); - - canvas.RestoreState(); - } - } -} diff --git a/src/Core/src/Graphics/ShapeDrawable.cs b/src/Core/src/Graphics/ShapeDrawable.cs index 2b79de4550c6..58b361b88a59 100644 --- a/src/Core/src/Graphics/ShapeDrawable.cs +++ b/src/Core/src/Graphics/ShapeDrawable.cs @@ -34,7 +34,7 @@ public void Draw(ICanvas canvas, RectangleF dirtyRect) void DrawStrokePath(ICanvas canvas, RectangleF dirtyRect, PathF path) { - if (ShapeView == null || ShapeView.Shape == null) + if (ShapeView == null || ShapeView.Shape == null || ShapeView.StrokeThickness <= 0 || ShapeView.Stroke == null) return; canvas.SaveState(); diff --git a/src/Core/src/Handlers/BoxView/BoxViewHandler.Android.cs b/src/Core/src/Handlers/BoxView/BoxViewHandler.Android.cs deleted file mode 100644 index a2a13d4b975e..000000000000 --- a/src/Core/src/Handlers/BoxView/BoxViewHandler.Android.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Maui.Graphics; - -namespace Microsoft.Maui.Handlers -{ - public partial class BoxViewHandler : ViewHandler - { - protected override MauiBoxView CreateNativeView() - { - return new MauiBoxView(Context) - { - Drawable = new BoxViewDrawable(VirtualView) - }; - } - - public static void MapColor(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - - public static void MapCornerRadius(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - } -} \ No newline at end of file diff --git a/src/Core/src/Handlers/BoxView/BoxViewHandler.Standard.cs b/src/Core/src/Handlers/BoxView/BoxViewHandler.Standard.cs deleted file mode 100644 index 9014e6032439..000000000000 --- a/src/Core/src/Handlers/BoxView/BoxViewHandler.Standard.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Microsoft.Maui.Handlers -{ - public partial class BoxViewHandler : ViewHandler - { - protected override object CreateNativeView() => throw new NotImplementedException(); - - public static void MapColor(IViewHandler handler, IBoxView boxView) { } - public static void MapCornerRadius(IViewHandler handler, IBoxView boxView) { } - } -} \ No newline at end of file diff --git a/src/Core/src/Handlers/BoxView/BoxViewHandler.Windows.cs b/src/Core/src/Handlers/BoxView/BoxViewHandler.Windows.cs deleted file mode 100644 index c7ecd2935b0d..000000000000 --- a/src/Core/src/Handlers/BoxView/BoxViewHandler.Windows.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.Maui.Graphics; -using Microsoft.Maui.Graphics.Win2D; - -namespace Microsoft.Maui.Handlers -{ - public partial class BoxViewHandler : ViewHandler - { - protected override W2DGraphicsView CreateNativeView() - { - return new W2DGraphicsView - { - Drawable = new BoxViewDrawable(VirtualView) - }; - } - - public static void MapColor(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - - public static void MapCornerRadius(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - } -} diff --git a/src/Core/src/Handlers/BoxView/BoxViewHandler.cs b/src/Core/src/Handlers/BoxView/BoxViewHandler.cs deleted file mode 100644 index 78869226b697..000000000000 --- a/src/Core/src/Handlers/BoxView/BoxViewHandler.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Microsoft.Maui.Handlers -{ - public partial class BoxViewHandler - { - public static IPropertyMapper BoxViewMapper = new PropertyMapper(ViewHandler.ViewMapper) - { - [nameof(IBoxView.Color)] = MapColor, - [nameof(IBoxView.CornerRadius)] = MapCornerRadius - }; - - public BoxViewHandler() : base(BoxViewMapper) - { - - } - - public BoxViewHandler(IPropertyMapper mapper) : base(mapper ?? BoxViewMapper) - { - - } - } -} \ No newline at end of file diff --git a/src/Core/src/Handlers/BoxView/BoxViewHandler.iOS.cs b/src/Core/src/Handlers/BoxView/BoxViewHandler.iOS.cs deleted file mode 100644 index 0153085eb548..000000000000 --- a/src/Core/src/Handlers/BoxView/BoxViewHandler.iOS.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Maui.Graphics; - -namespace Microsoft.Maui.Handlers -{ - public partial class BoxViewHandler : ViewHandler - { - protected override MauiBoxView CreateNativeView() - { - return new MauiBoxView - { - Drawable = new BoxViewDrawable(VirtualView) - }; - } - - public static void MapColor(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - - public static void MapCornerRadius(BoxViewHandler handler, IBoxView boxView) - { - handler.NativeView?.InvalidateBoxView(boxView); - } - } -} diff --git a/src/Core/src/Platform/Android/BoxViewExtensions.cs b/src/Core/src/Platform/Android/BoxViewExtensions.cs deleted file mode 100644 index a1a3bd865e55..000000000000 --- a/src/Core/src/Platform/Android/BoxViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Microsoft.Maui -{ - public static class BoxViewExtensions - { - public static void InvalidateBoxView(this MauiBoxView nativeView, IBoxView boxView) - { - nativeView.Invalidate(); - } - } -} \ No newline at end of file diff --git a/src/Core/src/Platform/Windows/BoxViewExtensions.cs b/src/Core/src/Platform/Windows/BoxViewExtensions.cs deleted file mode 100644 index 062280d1e23c..000000000000 --- a/src/Core/src/Platform/Windows/BoxViewExtensions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.Maui.Graphics.Win2D; - -namespace Microsoft.Maui -{ - public static class BoxViewExtensions - { - public static void InvalidateBoxView(this W2DGraphicsView nativeView, IBoxView boxView) - { - nativeView.Invalidate(); - } - } -} \ No newline at end of file diff --git a/src/Core/src/Platform/iOS/BoxViewExtensions.cs b/src/Core/src/Platform/iOS/BoxViewExtensions.cs deleted file mode 100644 index 972862d9926e..000000000000 --- a/src/Core/src/Platform/iOS/BoxViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Microsoft.Maui -{ - public static class BoxViewExtensions - { - public static void InvalidateBoxView(this MauiBoxView nativeView, IBoxView boxView) - { - nativeView.InvalidateDrawable(); - } - } -} diff --git a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.Android.cs index 69d7389e89ac..8b0c62c2b0cb 100644 --- a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.Android.cs @@ -7,10 +7,10 @@ namespace Microsoft.Maui.DeviceTests { public partial class BoxViewHandlerTests { - MauiBoxView GetNativeBoxView(BoxViewHandler boxViewViewHandler) => + MauiShapeView GetNativeBoxView(ShapeViewHandler boxViewViewHandler) => boxViewViewHandler.NativeView; - Task ValidateHasColor(IBoxView boxView, Color color, Action action = null) + Task ValidateHasColor(IShapeView boxView, Color color, Action action = null) { return InvokeOnMainThreadAsync(() => { diff --git a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.cs index d9b65414af49..0175ea51c0d1 100644 --- a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.cs @@ -7,7 +7,7 @@ namespace Microsoft.Maui.DeviceTests { [Category(TestCategory.BoxView)] - public partial class BoxViewHandlerTests : HandlerTestBase + public partial class BoxViewHandlerTests : HandlerTestBase { [Theory(DisplayName = "BoxView Initializes Correctly")] [InlineData(0xFF0000)] diff --git a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.iOS.cs index b17e3b5a075d..3dc2b727ae81 100644 --- a/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Handlers/BoxView/BoxViewHandlerTests.iOS.cs @@ -7,10 +7,10 @@ namespace Microsoft.Maui.DeviceTests { public partial class BoxViewHandlerTests { - MauiBoxView GetNativeBoxView(BoxViewHandler boxViewHandler) => + MauiShapeView GetNativeBoxView(ShapeViewHandler boxViewHandler) => boxViewHandler.NativeView; - Task ValidateHasColor(IBoxView boxView, Color color, Action action = null) + Task ValidateHasColor(IShapeView boxView, Color color, Action action = null) { return InvokeOnMainThreadAsync(() => { diff --git a/src/Core/tests/DeviceTests/Stubs/BoxViewStub.cs b/src/Core/tests/DeviceTests/Stubs/BoxViewStub.cs index 9cae9b85300a..187f6ff438a4 100644 --- a/src/Core/tests/DeviceTests/Stubs/BoxViewStub.cs +++ b/src/Core/tests/DeviceTests/Stubs/BoxViewStub.cs @@ -2,10 +2,28 @@ namespace Microsoft.Maui.DeviceTests.Stubs { - public class BoxViewStub : StubBase, IBoxView + public class BoxViewStub : StubBase, IShapeView { public Color Color { get; set; } public CornerRadius CornerRadius { get; set; } + + public IShape Shape { get; set; } + + public PathAspect Aspect { get; set; } + + public Paint Fill { get; set; } + + public Paint Stroke { get; set; } + + public double StrokeThickness { get; set; } + + public LineCap StrokeLineCap { get; set; } + + public LineJoin StrokeLineJoin { get; set; } + + public float[] StrokeDashPattern { get; set; } + + public float StrokeMiterLimit { get; set; } } }