Browse Source
Make `SolidColorBrush` immutable, but make the static `Brushes` properties return immutable brushes. The immutable brushes will be needed by the deferred renderer.pull/920/head
19 changed files with 762 additions and 349 deletions
File diff suppressed because it is too large
@ -0,0 +1,16 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Media |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a mutable brush which can return an immutable clone of itself.
|
||||
|
/// </summary>
|
||||
|
public interface IMutableBrush : IBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates an immutable clone of the brush.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The immutable clone.</returns>
|
||||
|
IBrush ToImmutable(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A brush that draws with a gradient.
|
||||
|
/// </summary>
|
||||
|
public abstract class ImmutableGradientBrush : IGradientBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="gradientStops">The gradient stops.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="spreadMethod">The spread method.</param>
|
||||
|
protected ImmutableGradientBrush( |
||||
|
IReadOnlyList<GradientStop> gradientStops, |
||||
|
double opacity, |
||||
|
GradientSpreadMethod spreadMethod) |
||||
|
{ |
||||
|
GradientStops = gradientStops; |
||||
|
Opacity = opacity; |
||||
|
SpreadMethod = spreadMethod; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
protected ImmutableGradientBrush(IGradientBrush source) |
||||
|
: this(source.GradientStops.ToList(), source.Opacity, source.SpreadMethod) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IReadOnlyList<GradientStop> GradientStops { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public double Opacity { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public GradientSpreadMethod SpreadMethod { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Media.Imaging; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Paints an area with an <see cref="IBitmap"/>.
|
||||
|
/// </summary>
|
||||
|
internal class ImmutableImageBrush : ImmutableTileBrush, IImageBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image to draw.</param>
|
||||
|
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
|
||||
|
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
|
||||
|
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
|
||||
|
/// <param name="stretch">
|
||||
|
/// How the source rectangle will be stretched to fill the destination rect.
|
||||
|
/// </param>
|
||||
|
/// <param name="tileMode">The tile mode.</param>
|
||||
|
public ImmutableImageBrush( |
||||
|
IBitmap source, |
||||
|
AlignmentX alignmentX = AlignmentX.Center, |
||||
|
AlignmentY alignmentY = AlignmentY.Center, |
||||
|
RelativeRect? destinationRect = null, |
||||
|
double opacity = 1, |
||||
|
RelativeRect? sourceRect = null, |
||||
|
Stretch stretch = Stretch.Uniform, |
||||
|
TileMode tileMode = TileMode.None) |
||||
|
: base( |
||||
|
alignmentX, |
||||
|
alignmentY, |
||||
|
destinationRect ?? RelativeRect.Fill, |
||||
|
opacity, |
||||
|
sourceRect ?? RelativeRect.Fill, |
||||
|
stretch, |
||||
|
tileMode) |
||||
|
{ |
||||
|
Source = source; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
public ImmutableImageBrush(IImageBrush source) |
||||
|
: base(source) |
||||
|
{ |
||||
|
Source = source.Source; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IBitmap Source { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A brush that draws with a linear gradient.
|
||||
|
/// </summary>
|
||||
|
public class ImmutableLinearGradientBrush : ImmutableGradientBrush, ILinearGradientBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableLinearGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="gradientStops">The gradient stops.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="spreadMethod">The spread method.</param>
|
||||
|
/// <param name="startPoint">The start point for the gradient.</param>
|
||||
|
/// <param name="endPoint">The end point for the gradient.</param>
|
||||
|
public ImmutableLinearGradientBrush( |
||||
|
IReadOnlyList<GradientStop> gradientStops, |
||||
|
double opacity = 1, |
||||
|
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad, |
||||
|
RelativePoint? startPoint = null, |
||||
|
RelativePoint? endPoint = null) |
||||
|
: base(gradientStops, opacity, spreadMethod) |
||||
|
{ |
||||
|
StartPoint = startPoint ?? RelativePoint.TopLeft; |
||||
|
EndPoint = endPoint ?? RelativePoint.BottomRight; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableLinearGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
public ImmutableLinearGradientBrush(ILinearGradientBrush source) |
||||
|
: base(source) |
||||
|
{ |
||||
|
StartPoint = source.StartPoint; |
||||
|
EndPoint = source.EndPoint; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativePoint StartPoint { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativePoint EndPoint { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A brush that draws with a radial gradient.
|
||||
|
/// </summary>
|
||||
|
public class ImmutableRadialGradientBrush : ImmutableGradientBrush, IRadialGradientBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableRadialGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="gradientStops">The gradient stops.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="spreadMethod">The spread method.</param>
|
||||
|
/// <param name="center">The start point for the gradient.</param>
|
||||
|
/// <param name="gradientOrigin">
|
||||
|
/// The location of the two-dimensional focal point that defines the beginning of the gradient.
|
||||
|
/// </param>
|
||||
|
/// <param name="radius">
|
||||
|
/// The horizontal and vertical radius of the outermost circle of the radial gradient.
|
||||
|
/// </param>
|
||||
|
public ImmutableRadialGradientBrush( |
||||
|
IReadOnlyList<GradientStop> gradientStops, |
||||
|
double opacity = 1, |
||||
|
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad, |
||||
|
RelativePoint? center = null, |
||||
|
RelativePoint? gradientOrigin = null, |
||||
|
double radius = 0.5) |
||||
|
: base(gradientStops, opacity, spreadMethod) |
||||
|
{ |
||||
|
Center = center ?? RelativePoint.Center; |
||||
|
GradientOrigin = gradientOrigin ?? RelativePoint.Center; |
||||
|
Radius = radius; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableRadialGradientBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
public ImmutableRadialGradientBrush(IRadialGradientBrush source) |
||||
|
: base(source) |
||||
|
{ |
||||
|
Center = source.Center; |
||||
|
GradientOrigin = source.GradientOrigin; |
||||
|
Radius = source.Radius; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativePoint Center { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativePoint GradientOrigin { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public double Radius { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Fills an area with a solid color.
|
||||
|
/// </summary>
|
||||
|
public struct ImmutableSolidColorBrush : ISolidColorBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The color to use.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
public ImmutableSolidColorBrush(Color color, double opacity = 1) |
||||
|
{ |
||||
|
Color = color; |
||||
|
Opacity = opacity; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The color to use.</param>
|
||||
|
public ImmutableSolidColorBrush(uint color) |
||||
|
: this(Color.FromUInt32(color)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
public ImmutableSolidColorBrush(ISolidColorBrush source) |
||||
|
: this(source.Color, source.Opacity) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the color of the brush.
|
||||
|
/// </summary>
|
||||
|
public Color Color { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the opacity of the brush.
|
||||
|
/// </summary>
|
||||
|
public double Opacity { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a string representation of the brush.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A string representation of the brush.</returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return Color.ToString(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A brush which displays a repeating image.
|
||||
|
/// </summary>
|
||||
|
public abstract class ImmutableTileBrush : ITileBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
|
||||
|
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
|
||||
|
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
|
||||
|
/// <param name="stretch">
|
||||
|
/// How the source rectangle will be stretched to fill the destination rect.
|
||||
|
/// </param>
|
||||
|
/// <param name="tileMode">The tile mode.</param>
|
||||
|
protected ImmutableTileBrush( |
||||
|
AlignmentX alignmentX, |
||||
|
AlignmentY alignmentY, |
||||
|
RelativeRect destinationRect, |
||||
|
double opacity, |
||||
|
RelativeRect sourceRect, |
||||
|
Stretch stretch, |
||||
|
TileMode tileMode) |
||||
|
{ |
||||
|
AlignmentX = alignmentX; |
||||
|
AlignmentY = alignmentY; |
||||
|
DestinationRect = destinationRect; |
||||
|
Opacity = opacity; |
||||
|
SourceRect = sourceRect; |
||||
|
Stretch = stretch; |
||||
|
TileMode = tileMode; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
protected ImmutableTileBrush(ITileBrush source) |
||||
|
: this( |
||||
|
source.AlignmentX, |
||||
|
source.AlignmentY, |
||||
|
source.DestinationRect, |
||||
|
source.Opacity, |
||||
|
source.SourceRect, |
||||
|
source.Stretch, |
||||
|
source.TileMode) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public AlignmentX AlignmentX { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public AlignmentY AlignmentY { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativeRect DestinationRect { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public double Opacity { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public RelativeRect SourceRect { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public Stretch Stretch { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public TileMode TileMode { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using Avalonia.VisualTree; |
||||
|
|
||||
|
namespace Avalonia.Media.Immutable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Paints an area with an <see cref="IVisual"/>.
|
||||
|
/// </summary>
|
||||
|
internal class ImmutableVisualBrush : ImmutableTileBrush, IVisualBrush |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="visual">The visual to draw.</param>
|
||||
|
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
|
||||
|
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
|
||||
|
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
|
||||
|
/// <param name="opacity">The opacity of the brush.</param>
|
||||
|
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
|
||||
|
/// <param name="stretch">
|
||||
|
/// How the source rectangle will be stretched to fill the destination rect.
|
||||
|
/// </param>
|
||||
|
/// <param name="tileMode">The tile mode.</param>
|
||||
|
public ImmutableVisualBrush( |
||||
|
IVisual visual, |
||||
|
AlignmentX alignmentX = AlignmentX.Center, |
||||
|
AlignmentY alignmentY = AlignmentY.Center, |
||||
|
RelativeRect? destinationRect = null, |
||||
|
double opacity = 1, |
||||
|
RelativeRect? sourceRect = null, |
||||
|
Stretch stretch = Stretch.Uniform, |
||||
|
TileMode tileMode = TileMode.None) |
||||
|
: base( |
||||
|
alignmentX, |
||||
|
alignmentY, |
||||
|
destinationRect ?? RelativeRect.Fill, |
||||
|
opacity, |
||||
|
sourceRect ?? RelativeRect.Fill, |
||||
|
stretch, |
||||
|
tileMode) |
||||
|
{ |
||||
|
Visual = visual; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImmutableVisualBrush"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The brush from which this brush's properties should be copied.</param>
|
||||
|
public ImmutableVisualBrush(IVisualBrush source) |
||||
|
: base(source) |
||||
|
{ |
||||
|
Visual = source.Visual; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IVisual Visual { get; } |
||||
|
} |
||||
|
} |
||||
@ -1,35 +0,0 @@ |
|||||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
||||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
||||
|
|
||||
namespace Avalonia.Media.Mutable |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Fills an area with a solid color.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// This is a mutable version of the normal immutable <see cref="Avalonia.Media.SolidColorBrush"/>
|
|
||||
/// for use in XAML. XAML really needs support for immutable data...
|
|
||||
/// </remarks>
|
|
||||
public class SolidColorBrush : Brush, ISolidColorBrush |
|
||||
{ |
|
||||
public static readonly DirectProperty<SolidColorBrush, Color> ColorProperty = |
|
||||
AvaloniaProperty.RegisterDirect<SolidColorBrush, Color>( |
|
||||
"Color", |
|
||||
o => o.Color, |
|
||||
(o, v) => o.Color = v); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color of the brush.
|
|
||||
/// </summary>
|
|
||||
public Color Color { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns a string representation of the brush.
|
|
||||
/// </summary>
|
|
||||
/// <returns>A string representation of the brush.</returns>
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
return Color.ToString(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +1,8 @@ |
|||||
<Style xmlns="https://github.com/avaloniaui" |
<Style xmlns="https://github.com/avaloniaui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
xmlns:mut="https://github.com/avaloniaui/mutable"> |
|
||||
<Style.Resources> |
<Style.Resources> |
||||
<mut:SolidColorBrush x:Key="RedBrush" Color="{StyleResource Red}"/> |
<SolidColorBrush x:Key="RedBrush" Color="{StyleResource Red}"/> |
||||
<mut:SolidColorBrush x:Key="GreenBrush" Color="{StyleResource Green}"/> |
<SolidColorBrush x:Key="GreenBrush" Color="{StyleResource Green}"/> |
||||
<mut:SolidColorBrush x:Key="BlueBrush" Color="{StyleResource Blue}"/> |
<SolidColorBrush x:Key="BlueBrush" Color="{StyleResource Blue}"/> |
||||
</Style.Resources> |
</Style.Resources> |
||||
</Style> |
</Style> |
||||
Loading…
Reference in new issue