diff --git a/src/AlohaKit.UI.Gallery/Views/XAML/MainPage.xaml b/src/AlohaKit.UI.Gallery/Views/XAML/MainPage.xaml index b7cf02a..1f00731 100644 --- a/src/AlohaKit.UI.Gallery/Views/XAML/MainPage.xaml +++ b/src/AlohaKit.UI.Gallery/Views/XAML/MainPage.xaml @@ -15,6 +15,17 @@ ScaleX="0.5" ScaleY="0.5" Opacity="0.25" Fill="Green" /> + + + + + (float)ScaleX; set => ScaleX = value; } float IVisualElement.ScaleY { get => (float)ScaleY; set => ScaleY = value; } IElement IElement.Parent { get => null; set => throw new NotImplementedException(); } + Geometry IVisualElement.Clip { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void AttachParent(IElement parent) { diff --git a/src/AlohaKit.UI/Controls/Path.cs b/src/AlohaKit.UI/Controls/Path.cs index d0b572a..0739bfb 100644 --- a/src/AlohaKit.UI/Controls/Path.cs +++ b/src/AlohaKit.UI/Controls/Path.cs @@ -66,7 +66,7 @@ PathF GetPath() { var path = new PathF(); - Data?.AppendPath(path); + Data?.AppendPath(path, Rect.Zero); return path; } diff --git a/src/AlohaKit.UI/Controls/View.cs b/src/AlohaKit.UI/Controls/View.cs index 552b91f..c5d71e8 100644 --- a/src/AlohaKit.UI/Controls/View.cs +++ b/src/AlohaKit.UI/Controls/View.cs @@ -95,7 +95,8 @@ public override void Draw(ICanvas canvas, RectF bounds) canvas.Alpha = (float)Opacity; canvas.Transform(Rotation, TranslationX, TranslationY, ScaleX, ScaleY); - + + DrawClip(canvas, bounds); DrawShadow(canvas, bounds); base.Draw(canvas, bounds); @@ -126,16 +127,27 @@ void DrawBackground(ICanvas canvas, RectF bounds) canvas.FillRectangle(bounds); } + void DrawClip(ICanvas canvas, RectF bounds) + { + if (Clip != null) + { + var viewBounds = new Rect(X, Y, WidthRequest, HeightRequest); + var path = (Clip as IGeometry)?.GetPath(viewBounds); + + canvas.ClipPath(path); + } + } + void DrawShadow(ICanvas canvas, RectF bounds) { - if (Shadow != null) - { - var offset = new SizeF((float)Shadow.Offset.X, (float)Shadow.Offset.Y); - var radius = Shadow.Radius; - var color = Shadow.Color; + if (Shadow != null) + { + var offset = new SizeF((float)Shadow.Offset.X, (float)Shadow.Offset.Y); + var radius = Shadow.Radius; + var color = Shadow.Color; - canvas.SetShadow(offset, radius, color); - } + canvas.SetShadow(offset, radius, color); + } } } } \ No newline at end of file diff --git a/src/AlohaKit.UI/Controls/VisualElement.cs b/src/AlohaKit.UI/Controls/VisualElement.cs index b8803a6..f4c9e42 100644 --- a/src/AlohaKit.UI/Controls/VisualElement.cs +++ b/src/AlohaKit.UI/Controls/VisualElement.cs @@ -11,6 +11,7 @@ public interface IVisualElement float HeightRequest { get; set; } Shadow Shadow { get; set; } + Geometry Clip { get; set; } float TranslationX { get; set; } float TranslationY { get; set; } @@ -51,8 +52,12 @@ public abstract class VisualElement : BindableObject, IVisualElement public static readonly BindableProperty ShadowProperty = BindableProperty.Create(nameof(Shadow), typeof(Shadow), typeof(VisualElement), null, propertyChanged: InvalidatePropertyChanged); + + public static readonly BindableProperty ClipProperty = + BindableProperty.Create(nameof(Clip), typeof(Geometry), typeof(VisualElement), null, + propertyChanged: InvalidatePropertyChanged); - public static readonly BindableProperty RotationProperty = + public static readonly BindableProperty RotationProperty = BindableProperty.Create(nameof(Rotation), typeof(float), typeof(VisualElement), 0f, propertyChanged: InvalidatePropertyChanged); @@ -117,7 +122,13 @@ public Shadow Shadow set => SetValue(ShadowProperty, value); } - public float Rotation + public Geometry Clip + { + get => (Geometry)GetValue(ClipProperty); + set => SetValue(ClipProperty, value); + } + + public float Rotation { get => (float)GetValue(RotationProperty); set => SetValue(RotationProperty, value); diff --git a/src/AlohaKit.UI/EllipseGeometry.cs b/src/AlohaKit.UI/EllipseGeometry.cs new file mode 100644 index 0000000..d21b9f1 --- /dev/null +++ b/src/AlohaKit.UI/EllipseGeometry.cs @@ -0,0 +1,55 @@ +namespace AlohaKit.UI +{ + public class EllipseGeometry : Geometry + { + public EllipseGeometry() + { + + } + + public EllipseGeometry(Point center, double radiusX, double radiusY) + { + Center = center; + RadiusX = radiusX; + RadiusY = radiusY; + } + + public static readonly BindableProperty CenterProperty = + BindableProperty.Create(nameof(Center), typeof(Point), typeof(EllipseGeometry), new Point()); + + public static readonly BindableProperty RadiusXProperty = + BindableProperty.Create(nameof(RadiusX), typeof(double), typeof(EllipseGeometry), 0.0); + + public static readonly BindableProperty RadiusYProperty = + BindableProperty.Create(nameof(RadiusY), typeof(double), typeof(EllipseGeometry), 0.0); + + public Point Center + { + set { SetValue(CenterProperty, value); } + get { return (Point)GetValue(CenterProperty); } + } + + public double RadiusX + { + set { SetValue(RadiusXProperty, value); } + get { return (double)GetValue(RadiusXProperty); } + } + + public double RadiusY + { + set { SetValue(RadiusYProperty, value); } + get { return (double)GetValue(RadiusYProperty); } + } + + public override void AppendPath(PathF path, Rect viewBounds) + { + var centerX = (float)(viewBounds.X + Center.X); + var centerY = (float)(viewBounds.Y + Center.Y); + + var radiusX = (float)RadiusX; + var radiusY = (float)RadiusY; + + path.AppendEllipse(centerX - radiusX, centerY - radiusY, radiusX * 2f, radiusY * 2f); + } + } +} \ No newline at end of file diff --git a/src/AlohaKit.UI/Extensions/ViewExtensions.cs b/src/AlohaKit.UI/Extensions/ViewExtensions.cs index 9127f7f..45f9947 100644 --- a/src/AlohaKit.UI/Extensions/ViewExtensions.cs +++ b/src/AlohaKit.UI/Extensions/ViewExtensions.cs @@ -44,10 +44,17 @@ public static T Background(this T view, Brush background) where T : View return view; } + public static T Clip(this T view, Geometry clip) where T : View + { + view.Clip = clip; + + return view; + } + public static T Shadow(this T view, Shadow shadow) where T : View { view.Shadow = shadow; - + return view; } } diff --git a/src/AlohaKit.UI/Geometry.cs b/src/AlohaKit.UI/Geometry.cs new file mode 100644 index 0000000..c6c1fb2 --- /dev/null +++ b/src/AlohaKit.UI/Geometry.cs @@ -0,0 +1,21 @@ +namespace AlohaKit.UI +{ + public interface IGeometry + { + PathF GetPath(Rect bounds); + } + + public abstract class Geometry : BindableObject, IGeometry + { + public abstract void AppendPath(PathF path, Rect viewBounds); + + PathF IGeometry.GetPath(Rect bounds) + { + var path = new PathF(); + + AppendPath(path, bounds); + + return path; + } + } +} \ No newline at end of file diff --git a/src/AlohaKit.UI/LineGeometry.cs b/src/AlohaKit.UI/LineGeometry.cs new file mode 100644 index 0000000..79c158b --- /dev/null +++ b/src/AlohaKit.UI/LineGeometry.cs @@ -0,0 +1,46 @@ +namespace AlohaKit.UI +{ + public class LineGeometry : Geometry + { + public LineGeometry() + { + + } + + public LineGeometry(Point startPoint, Point endPoint) + { + StartPoint = startPoint; + EndPoint = endPoint; + } + + public static readonly BindableProperty StartPointProperty = + BindableProperty.Create(nameof(StartPoint), typeof(Point), typeof(LineGeometry), new Point()); + + public static readonly BindableProperty EndPointProperty = + BindableProperty.Create(nameof(EndPoint), typeof(Point), typeof(LineGeometry), new Point()); + + public Point StartPoint + { + set { SetValue(StartPointProperty, value); } + get { return (Point)GetValue(StartPointProperty); } + } + + public Point EndPoint + { + set { SetValue(EndPointProperty, value); } + get { return (Point)GetValue(EndPointProperty); } + } + + public override void AppendPath(PathF path, Rect viewBounds) + { + float startPointX = (float)(viewBounds.X + StartPoint.X); + float startPointY = (float)(viewBounds.Y + StartPoint.Y); + + float endPointX = (float)(viewBounds.X + EndPoint.X); + float endPointY = (float)(viewBounds.Y + EndPoint.Y); + + path.Move(startPointX, startPointY); + path.LineTo(endPointX, endPointY); + } + } +} \ No newline at end of file diff --git a/src/AlohaKit.UI/RectangleGeometry.cs b/src/AlohaKit.UI/RectangleGeometry.cs new file mode 100644 index 0000000..fce5e26 --- /dev/null +++ b/src/AlohaKit.UI/RectangleGeometry.cs @@ -0,0 +1,34 @@ +namespace AlohaKit.UI +{ + public class RectangleGeometry : Geometry + { + public RectangleGeometry() + { + + } + + public RectangleGeometry(Rect rect) + { + Rect = rect; + } + + public static readonly BindableProperty RectProperty = + BindableProperty.Create(nameof(Rect), typeof(Rect), typeof(RectangleGeometry), new Rect()); + + public Rect Rect + { + set { SetValue(RectProperty, value); } + get { return (Rect)GetValue(RectProperty); } + } + + public override void AppendPath(PathF path, Rect viewBounds) + { + float x = (float)(viewBounds.X + Rect.X); + float y = (float)(viewBounds.Y + Rect.Y); + float w = (float)Rect.Width; + float h = (float)Rect.Height; + + path.AppendRectangle(x, y, w, h); + } + } +}