diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index e1d5360509..c7bbb5aeec 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -254,6 +254,7 @@ namespace Perspex.Cairo.Media var solid = brush as SolidColorBrush; var linearGradientBrush = brush as LinearGradientBrush; + var radialGradientBrush = brush as RadialGradientBrush; var imageBrush = brush as ImageBrush; var visualBrush = brush as VisualBrush; BrushImpl impl = null; @@ -265,8 +266,12 @@ namespace Perspex.Cairo.Media else if (linearGradientBrush != null) { impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize); - } - else if (imageBrush != null) + } + else if (radialGradientBrush != null) + { + impl = new RadialGradientBrushImpl(radialGradientBrush, destinationSize); + } + else if (imageBrush != null) { impl = new ImageBrushImpl(imageBrush, destinationSize); } diff --git a/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs b/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs new file mode 100644 index 0000000000..a345f1869d --- /dev/null +++ b/src/Gtk/Perspex.Cairo/Media/RadialGradientBrushImpl.cs @@ -0,0 +1,25 @@ +using System; +using global::Cairo; + +namespace Perspex.Cairo +{ + public class RadialGradientBrushImpl : BrushImpl + { + public RadialGradientBrushImpl(Perspex.Media.RadialGradientBrush brush, Size destinationSize) + { + var center = brush.Center.ToPixels(destinationSize); + var gradientOrigin = brush.GradientOrigin.ToPixels(destinationSize); + var radius = brush.Radius; + + this.PlatformBrush = new RadialGradient(center.X, center.Y, radius, gradientOrigin.X, gradientOrigin.Y, radius); + + foreach (var stop in brush.GradientStops) + { + ((LinearGradient)this.PlatformBrush).AddColorStop(stop.Offset, stop.Color.ToCairo()); + } + + ((LinearGradient)this.PlatformBrush).Extend = Extend.Pad; + } + } +} + diff --git a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj index baa60a428a..6e4155d610 100644 --- a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj +++ b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj @@ -61,6 +61,7 @@ + @@ -103,4 +104,4 @@ --> - + \ No newline at end of file diff --git a/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs b/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs index 1ebda2fe72..67cf73ce30 100644 --- a/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs +++ b/src/Perspex.SceneGraph/Media/LinearGradientBrush.cs @@ -6,7 +6,7 @@ namespace Perspex.Media /// /// A brush that draws with a linear gradient. /// - public class LinearGradientBrush : GradientBrush + public sealed class LinearGradientBrush : GradientBrush { /// /// Defines the property. diff --git a/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs b/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs new file mode 100644 index 0000000000..f985ec4115 --- /dev/null +++ b/src/Perspex.SceneGraph/Media/RadialGradientBrush.cs @@ -0,0 +1,63 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Perspex.Media +{ + /// + /// Paints an area with a radial gradient. A focal point defines the beginning of the gradient, + /// and a circle defines the end point of the gradient. + /// + public sealed class RadialGradientBrush : GradientBrush + { + /// + /// Defines the property. + /// + public static readonly PerspexProperty CenterProperty = + PerspexProperty.Register( + nameof(Center), + RelativePoint.Center); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty GradientOriginProperty = + PerspexProperty.Register( + nameof(GradientOrigin), + RelativePoint.Center); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty RadiusProperty = + PerspexProperty.Register( + nameof(Radius), + 0.5); + + /// + /// Gets or sets the start point for the gradient. + /// + public RelativePoint Center + { + get { return GetValue(CenterProperty); } + set { SetValue(CenterProperty, value); } + } + + /// + /// Gets or sets the location of the two-dimensional focal point that defines the beginning of the gradient. + /// + public RelativePoint GradientOrigin + { + get { return GetValue(GradientOriginProperty); } + set { SetValue(GradientOriginProperty, value); } + } + + /// + /// Gets or sets the horizontal and vertical radius of the outermost circle of the radial gradient. + /// + public double Radius + { + get { return GetValue(RadiusProperty); } + set { SetValue(RadiusProperty, value); } + } + } +} \ No newline at end of file diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 4c9d53437d..4cf3651824 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -67,6 +67,7 @@ + diff --git a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs index d0c2e4c254..58d884b18c 100644 --- a/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs @@ -303,6 +303,7 @@ namespace Perspex.Direct2D1.Media { var solidColorBrush = brush as Perspex.Media.SolidColorBrush; var linearGradientBrush = brush as Perspex.Media.LinearGradientBrush; + var radialGradientBrush = brush as Perspex.Media.RadialGradientBrush; var imageBrush = brush as ImageBrush; var visualBrush = brush as VisualBrush; @@ -314,6 +315,10 @@ namespace Perspex.Direct2D1.Media { return new LinearGradientBrushImpl(linearGradientBrush, _renderTarget, destinationSize); } + else if (radialGradientBrush != null) + { + return new RadialGradientBrushImpl(radialGradientBrush, _renderTarget, destinationSize); + } else if (imageBrush != null) { return new ImageBrushImpl(imageBrush, _renderTarget, destinationSize); diff --git a/src/Windows/Perspex.Direct2D1/Media/LinearGradientBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/LinearGradientBrushImpl.cs index 56ea0f422d..b67378990c 100644 --- a/src/Windows/Perspex.Direct2D1/Media/LinearGradientBrushImpl.cs +++ b/src/Windows/Perspex.Direct2D1/Media/LinearGradientBrushImpl.cs @@ -16,20 +16,17 @@ namespace Perspex.Direct2D1.Media SharpDX.Direct2D1.RenderTarget target, Size destinationSize) { - if (brush != null) - { - var gradientStops = brush.GradientStops.Select(s => new SharpDX.Direct2D1.GradientStop { Color = s.Color.ToDirect2D(), Position = (float)s.Offset }).ToArray(); + var gradientStops = brush.GradientStops.Select(s => new SharpDX.Direct2D1.GradientStop { Color = s.Color.ToDirect2D(), Position = (float)s.Offset }).ToArray(); - Point startPoint = brush.StartPoint.ToPixels(destinationSize); - Point endPoint = brush.EndPoint.ToPixels(destinationSize); + Point startPoint = brush.StartPoint.ToPixels(destinationSize); + Point endPoint = brush.EndPoint.ToPixels(destinationSize); - PlatformBrush = new SharpDX.Direct2D1.LinearGradientBrush( - target, - new SharpDX.Direct2D1.LinearGradientBrushProperties { StartPoint = startPoint.ToSharpDX(), EndPoint = endPoint.ToSharpDX() }, - new SharpDX.Direct2D1.BrushProperties { Opacity = (float)brush.Opacity, Transform = target.Transform }, - new SharpDX.Direct2D1.GradientStopCollection(target, gradientStops, brush.SpreadMethod.ToDirect2D()) - ); - } + PlatformBrush = new SharpDX.Direct2D1.LinearGradientBrush( + target, + new SharpDX.Direct2D1.LinearGradientBrushProperties { StartPoint = startPoint.ToSharpDX(), EndPoint = endPoint.ToSharpDX() }, + new SharpDX.Direct2D1.BrushProperties { Opacity = (float)brush.Opacity, Transform = target.Transform }, + new SharpDX.Direct2D1.GradientStopCollection(target, gradientStops, brush.SpreadMethod.ToDirect2D()) + ); } } } diff --git a/src/Windows/Perspex.Direct2D1/Media/RadialGradientBrushImpl.cs b/src/Windows/Perspex.Direct2D1/Media/RadialGradientBrushImpl.cs new file mode 100644 index 0000000000..f0b21c7ae7 --- /dev/null +++ b/src/Windows/Perspex.Direct2D1/Media/RadialGradientBrushImpl.cs @@ -0,0 +1,35 @@ +// Copyright (c) The Perspex Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perspex.Direct2D1.Media +{ + public class RadialGradientBrushImpl : BrushImpl + { + public RadialGradientBrushImpl( + Perspex.Media.RadialGradientBrush brush, + SharpDX.Direct2D1.RenderTarget target, + Size destinationSize) + { + var gradientStops = brush.GradientStops.Select(s => new SharpDX.Direct2D1.GradientStop { Color = s.Color.ToDirect2D(), Position = (float)s.Offset }).ToArray(); + + Point centerPoint = brush.Center.ToPixels(destinationSize); + Point GradientOriginOffset = brush.GradientOrigin.ToPixels(destinationSize); + // Note: Direct2D supports RadiusX and RadiusY but Cairo backend supports only Radius property + double radiusX = brush.Radius; + double radiusY = brush.Radius; + + PlatformBrush = new SharpDX.Direct2D1.RadialGradientBrush( + target, + new SharpDX.Direct2D1.RadialGradientBrushProperties { Center = centerPoint.ToSharpDX(), GradientOriginOffset = GradientOriginOffset.ToSharpDX(), RadiusX = (float)radiusX, RadiusY = (float)radiusY }, + new SharpDX.Direct2D1.BrushProperties { Opacity = (float)brush.Opacity, Transform = target.Transform }, + new SharpDX.Direct2D1.GradientStopCollection(target, gradientStops, brush.SpreadMethod.ToDirect2D()) + ); + } + } +} diff --git a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj index c90e4ffe6e..9a981c3bf1 100644 --- a/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj +++ b/src/Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj @@ -79,6 +79,7 @@ +