Browse Source

Make brushes raise a Changed event.

When their visual representation changes.
pull/1881/head
Steven Kirk 8 years ago
parent
commit
d531b36b96
  1. 36
      src/Avalonia.Visuals/Media/Brush.cs
  2. 65
      src/Avalonia.Visuals/Media/GradientBrush.cs
  3. 40
      src/Avalonia.Visuals/Media/GradientStop.cs
  4. 23
      src/Avalonia.Visuals/Media/GradientStops.cs
  5. 4
      src/Avalonia.Visuals/Media/IGradientBrush.cs
  6. 18
      src/Avalonia.Visuals/Media/IGradientStop.cs
  7. 9
      src/Avalonia.Visuals/Media/IMutableBrush.cs
  8. 12
      src/Avalonia.Visuals/Media/ImageBrush.cs
  9. 9
      src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs
  10. 20
      src/Avalonia.Visuals/Media/Immutable/ImmutableGradientStop.cs
  11. 4
      src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs
  12. 4
      src/Avalonia.Visuals/Media/Immutable/ImmutableRadialGradientBrush.cs
  13. 13
      src/Avalonia.Visuals/Media/LinearGradientBrush.cs
  14. 10
      src/Avalonia.Visuals/Media/RadialGradientBrush.cs
  15. 13
      src/Avalonia.Visuals/Media/SolidColorBrush.cs
  16. 7
      src/Avalonia.Visuals/Media/TileBrush.cs
  17. 12
      src/Avalonia.Visuals/Media/VisualBrush.cs
  18. 2
      tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs
  19. 4
      tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs
  20. 2
      tests/Avalonia.RenderTests/Media/RadialGradientBrushTests.cs
  21. 4
      tests/Avalonia.RenderTests/OpacityMaskTests.cs
  22. 27
      tests/Avalonia.Visuals.UnitTests/Media/ImageBrushTests.cs
  23. 86
      tests/Avalonia.Visuals.UnitTests/Media/LinearGradientBrushTests.cs
  24. 21
      tests/Avalonia.Visuals.UnitTests/Media/SolidColorBrushTests.cs

36
src/Avalonia.Visuals/Media/Brush.cs

@ -10,7 +10,7 @@ namespace Avalonia.Media
/// Describes how an area is painted.
/// </summary>
[TypeConverter(typeof(BrushConverter))]
public abstract class Brush : AvaloniaObject, IBrush
public abstract class Brush : AvaloniaObject, IMutableBrush
{
/// <summary>
/// Defines the <see cref="Opacity"/> property.
@ -18,6 +18,9 @@ namespace Avalonia.Media
public static readonly StyledProperty<double> OpacityProperty =
AvaloniaProperty.Register<Brush, double>(nameof(Opacity), 1.0);
/// <inheritdoc/>
public event EventHandler Changed;
/// <summary>
/// Gets or sets the opacity of the brush.
/// </summary>
@ -50,5 +53,36 @@ namespace Avalonia.Media
throw new FormatException($"Invalid brush string: '{s}'.");
}
/// <inheritdoc/>
public abstract IBrush ToImmutable();
/// <summary>
/// Marks a property as affecting the brush's visual representation.
/// </summary>
/// <param name="properties">The properties.</param>
/// <remarks>
/// After a call to this method in a brush's static constructor, any change to the
/// property will cause the <see cref="Changed"/> event to be raised on the brush.
/// </remarks>
protected static void AffectsRender<T>(params AvaloniaProperty[] properties)
where T : Brush
{
void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as T)?.RaiseChanged(EventArgs.Empty);
}
foreach (var property in properties)
{
property.Changed.Subscribe(Invalidate);
}
}
/// <summary>
/// Raises the <see cref="Changed"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected void RaiseChanged(EventArgs e) => Changed?.Invoke(this, e);
}
}

65
src/Avalonia.Visuals/Media/GradientBrush.cs

@ -1,7 +1,11 @@
// 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.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using Avalonia.Collections;
using Avalonia.Metadata;
namespace Avalonia.Media
@ -20,35 +24,74 @@ namespace Avalonia.Media
/// <summary>
/// Defines the <see cref="GradientStops"/> property.
/// </summary>
public static readonly StyledProperty<IList<GradientStop>> GradientStopsProperty =
AvaloniaProperty.Register<GradientBrush, IList<GradientStop>>(nameof(GradientStops));
public static readonly StyledProperty<GradientStops> GradientStopsProperty =
AvaloniaProperty.Register<GradientBrush, GradientStops>(nameof(GradientStops));
private IDisposable _gradientStopsSubscription;
static GradientBrush()
{
GradientStopsProperty.Changed.Subscribe(GradientStopsChanged);
AffectsRender<LinearGradientBrush>(SpreadMethodProperty);
}
/// <summary>
/// Initializes a new instance of the <see cref="GradientBrush"/> class.
/// </summary>
public GradientBrush()
{
this.GradientStops = new List<GradientStop>();
this.GradientStops = new GradientStops();
}
/// <summary>
/// Gets or sets the brush's spread method that defines how to draw a gradient that
/// doesn't fill the bounds of the destination control.
/// </summary>
/// <inheritdoc/>
public GradientSpreadMethod SpreadMethod
{
get { return GetValue(SpreadMethodProperty); }
set { SetValue(SpreadMethodProperty, value); }
}
/// <summary>
/// Gets or sets the brush's gradient stops.
/// </summary>
/// <inheritdoc/>
[Content]
public IList<GradientStop> GradientStops
public GradientStops GradientStops
{
get { return GetValue(GradientStopsProperty); }
set { SetValue(GradientStopsProperty, value); }
}
/// <inheritdoc/>
IReadOnlyList<IGradientStop> IGradientBrush.GradientStops => GradientStops;
private static void GradientStopsChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.Sender is GradientBrush brush)
{
var oldValue = (GradientStops)e.OldValue;
var newValue = (GradientStops)e.NewValue;
if (oldValue != null)
{
oldValue.CollectionChanged -= brush.GradientStopsChanged;
brush._gradientStopsSubscription.Dispose();
}
if (newValue != null)
{
newValue.CollectionChanged += brush.GradientStopsChanged;
brush._gradientStopsSubscription = newValue.TrackItemPropertyChanged(brush.GradientStopChanged);
}
brush.RaiseChanged(EventArgs.Empty);
}
}
private void GradientStopsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RaiseChanged(EventArgs.Empty);
}
private void GradientStopChanged(Tuple<object, PropertyChangedEventArgs> e)
{
RaiseChanged(EventArgs.Empty);
}
}
}

40
src/Avalonia.Visuals/Media/GradientStop.cs

@ -4,10 +4,22 @@
namespace Avalonia.Media
{
/// <summary>
/// GradientStop
/// Describes the location and color of a transition point in a gradient.
/// </summary>
public sealed class GradientStop
public sealed class GradientStop : AvaloniaObject, IGradientStop
{
/// <summary>
/// Describes the <see cref="Offset"/> property.
/// </summary>
public static StyledProperty<double> OffsetProperty =
AvaloniaProperty.Register<GradientStop, double>(nameof(Offset));
/// <summary>
/// Describes the <see cref="Color"/> property.
/// </summary>
public static StyledProperty<Color> ColorProperty =
AvaloniaProperty.Register<GradientStop, Color>(nameof(Color));
/// <summary>
/// Initializes a new instance of the <see cref="GradientStop"/> class.
/// </summary>
@ -24,16 +36,18 @@ namespace Avalonia.Media
Offset = offset;
}
// TODO: Make these dependency properties.
/// <summary>
/// The offset
/// </summary>
public double Offset { get; set; }
/// <inheritdoc/>
public double Offset
{
get => GetValue(OffsetProperty);
set => SetValue(OffsetProperty, value);
}
/// <summary>
/// The color
/// </summary>
public Color Color { get; set; }
/// <inheritdoc/>
public Color Color
{
get => GetValue(ColorProperty);
set => SetValue(ColorProperty, value);
}
}
}
}

23
src/Avalonia.Visuals/Media/GradientStops.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Media.Immutable;
namespace Avalonia.Media
{
/// <summary>
/// A collection of <see cref="GradientStop"/>s.
/// </summary>
public class GradientStops : AvaloniaList<GradientStop>
{
public GradientStops()
{
ResetBehavior = ResetBehavior.Remove;
}
public IReadOnlyList<ImmutableGradientStop> ToImmutable()
{
return this.Select(x => new ImmutableGradientStop(x.Offset, x.Color)).ToList();
}
}
}

4
src/Avalonia.Visuals/Media/IGradientBrush.cs

@ -10,7 +10,7 @@ namespace Avalonia.Media
/// <summary>
/// Gets the brush's gradient stops.
/// </summary>
IList<GradientStop> GradientStops { get; }
IReadOnlyList<IGradientStop> GradientStops { get; }
/// <summary>
/// Gets the brush's spread method that defines how to draw a gradient that doesn't fill
@ -18,4 +18,4 @@ namespace Avalonia.Media
/// </summary>
GradientSpreadMethod SpreadMethod { get; }
}
}
}

18
src/Avalonia.Visuals/Media/IGradientStop.cs

@ -0,0 +1,18 @@
namespace Avalonia.Media
{
/// <summary>
/// Describes the location and color of a transition point in a gradient.
/// </summary>
public interface IGradientStop
{
/// <summary>
/// Gets the gradient stop color.
/// </summary>
Color Color { get; }
/// <summary>
/// Gets the gradient stop offset.
/// </summary>
double Offset { get; }
}
}

9
src/Avalonia.Visuals/Media/IMutableBrush.cs

@ -1,10 +1,17 @@
namespace Avalonia.Media
using System;
namespace Avalonia.Media
{
/// <summary>
/// Represents a mutable brush which can return an immutable clone of itself.
/// </summary>
public interface IMutableBrush : IBrush
{
/// <summary>
/// Raised when the brush changes visually.
/// </summary>
event EventHandler Changed;
/// <summary>
/// Creates an immutable clone of the brush.
/// </summary>

12
src/Avalonia.Visuals/Media/ImageBrush.cs

@ -2,13 +2,14 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Media.Imaging;
using Avalonia.Media.Immutable;
namespace Avalonia.Media
{
/// <summary>
/// Paints an area with an <see cref="IBitmap"/>.
/// </summary>
public class ImageBrush : TileBrush, IImageBrush, IMutableBrush
public class ImageBrush : TileBrush, IImageBrush
{
/// <summary>
/// Defines the <see cref="Visual"/> property.
@ -16,6 +17,11 @@ namespace Avalonia.Media
public static readonly StyledProperty<IBitmap> SourceProperty =
AvaloniaProperty.Register<ImageBrush, IBitmap>(nameof(Source));
static ImageBrush()
{
AffectsRender<ImageBrush>(SourceProperty);
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary>
@ -42,9 +48,9 @@ namespace Avalonia.Media
}
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
public override IBrush ToImmutable()
{
return new Immutable.ImmutableImageBrush(this);
return new ImmutableImageBrush(this);
}
}
}

9
src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
namespace Avalonia.Media.Immutable
{
@ -15,7 +14,7 @@ namespace Avalonia.Media.Immutable
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="spreadMethod">The spread method.</param>
protected ImmutableGradientBrush(
IList<GradientStop> gradientStops,
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity,
GradientSpreadMethod spreadMethod)
{
@ -28,14 +27,14 @@ namespace Avalonia.Media.Immutable
/// 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)
protected ImmutableGradientBrush(GradientBrush source)
: this(source.GradientStops.ToImmutable(), source.Opacity, source.SpreadMethod)
{
}
/// <inheritdoc/>
public IList<GradientStop> GradientStops { get; }
public IReadOnlyList<IGradientStop> GradientStops { get; }
/// <inheritdoc/>
public double Opacity { get; }

20
src/Avalonia.Visuals/Media/Immutable/ImmutableGradientStop.cs

@ -0,0 +1,20 @@
namespace Avalonia.Media.Immutable
{
/// <summary>
/// Describes the location and color of a transition point in a gradient.
/// </summary>
public class ImmutableGradientStop : IGradientStop
{
public ImmutableGradientStop(double offset, Color color)
{
Offset = offset;
Color = color;
}
/// <inheritdoc/>
public double Offset { get; }
/// <inheritdoc/>
public Color Color { get; }
}
}

4
src/Avalonia.Visuals/Media/Immutable/ImmutableLinearGradientBrush.cs

@ -16,7 +16,7 @@ namespace Avalonia.Media.Immutable
/// <param name="startPoint">The start point for the gradient.</param>
/// <param name="endPoint">The end point for the gradient.</param>
public ImmutableLinearGradientBrush(
IList<GradientStop> gradientStops,
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity = 1,
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad,
RelativePoint? startPoint = null,
@ -31,7 +31,7 @@ namespace Avalonia.Media.Immutable
/// 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)
public ImmutableLinearGradientBrush(LinearGradientBrush source)
: base(source)
{
StartPoint = source.StartPoint;

4
src/Avalonia.Visuals/Media/Immutable/ImmutableRadialGradientBrush.cs

@ -21,7 +21,7 @@ namespace Avalonia.Media.Immutable
/// The horizontal and vertical radius of the outermost circle of the radial gradient.
/// </param>
public ImmutableRadialGradientBrush(
IList<GradientStop> gradientStops,
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity = 1,
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad,
RelativePoint? center = null,
@ -38,7 +38,7 @@ namespace Avalonia.Media.Immutable
/// 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)
public ImmutableRadialGradientBrush(RadialGradientBrush source)
: base(source)
{
Center = source.Center;

13
src/Avalonia.Visuals/Media/LinearGradientBrush.cs

@ -1,12 +1,14 @@
// 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.
using Avalonia.Media.Immutable;
namespace Avalonia.Media
{
/// <summary>
/// A brush that draws with a linear gradient.
/// </summary>
public sealed class LinearGradientBrush : GradientBrush, ILinearGradientBrush, IMutableBrush
public sealed class LinearGradientBrush : GradientBrush, ILinearGradientBrush
{
/// <summary>
/// Defines the <see cref="StartPoint"/> property.
@ -24,6 +26,11 @@ namespace Avalonia.Media
nameof(EndPoint),
RelativePoint.BottomRight);
static LinearGradientBrush()
{
AffectsRender<LinearGradientBrush>(StartPointProperty, EndPointProperty);
}
/// <summary>
/// Gets or sets the start point for the gradient.
/// </summary>
@ -43,9 +50,9 @@ namespace Avalonia.Media
}
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
public override IBrush ToImmutable()
{
return new Immutable.ImmutableLinearGradientBrush(this);
return new ImmutableLinearGradientBrush(this);
}
}
}

10
src/Avalonia.Visuals/Media/RadialGradientBrush.cs

@ -1,12 +1,14 @@
// 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.
using Avalonia.Media.Immutable;
namespace Avalonia.Media
{
/// <summary>
/// Paints an area with a radial gradient.
/// </summary>
public sealed class RadialGradientBrush : GradientBrush, IRadialGradientBrush, IMutableBrush
public sealed class RadialGradientBrush : GradientBrush, IRadialGradientBrush
{
/// <summary>
/// Defines the <see cref="Center"/> property.
@ -63,9 +65,9 @@ namespace Avalonia.Media
}
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
public override IBrush ToImmutable()
{
return new Immutable.ImmutableRadialGradientBrush(this);
return new ImmutableRadialGradientBrush(this);
}
}
}
}

13
src/Avalonia.Visuals/Media/SolidColorBrush.cs

@ -1,12 +1,14 @@
// 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.
using Avalonia.Media.Immutable;
namespace Avalonia.Media
{
/// <summary>
/// Fills an area with a solid color.
/// </summary>
public class SolidColorBrush : Brush, ISolidColorBrush, IMutableBrush
public class SolidColorBrush : Brush, ISolidColorBrush
{
/// <summary>
/// Defines the <see cref="Color"/> property.
@ -14,6 +16,11 @@ namespace Avalonia.Media
public static readonly StyledProperty<Color> ColorProperty =
AvaloniaProperty.Register<SolidColorBrush, Color>(nameof(Color));
static SolidColorBrush()
{
AffectsRender<SolidColorBrush>(ColorProperty);
}
/// <summary>
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
/// </summary>
@ -75,9 +82,9 @@ namespace Avalonia.Media
}
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
public override IBrush ToImmutable()
{
return new Immutable.ImmutableSolidColorBrush(this);
return new ImmutableSolidColorBrush(this);
}
}
}

7
src/Avalonia.Visuals/Media/TileBrush.cs

@ -79,6 +79,13 @@ namespace Avalonia.Media
static TileBrush()
{
AffectsRender<TileBrush>(
AlignmentXProperty,
AlignmentYProperty,
DestinationRectProperty,
SourceRectProperty,
StretchProperty,
TileModeProperty);
RenderOptions.BitmapInterpolationModeProperty.OverrideDefaultValue<TileBrush>(BitmapInterpolationMode.Default);
}

12
src/Avalonia.Visuals/Media/VisualBrush.cs

@ -1,6 +1,7 @@
// 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.
using Avalonia.Media.Immutable;
using Avalonia.VisualTree;
namespace Avalonia.Media
@ -8,7 +9,7 @@ namespace Avalonia.Media
/// <summary>
/// Paints an area with an <see cref="IVisual"/>.
/// </summary>
public class VisualBrush : TileBrush, IVisualBrush, IMutableBrush
public class VisualBrush : TileBrush, IVisualBrush
{
/// <summary>
/// Defines the <see cref="Visual"/> property.
@ -16,6 +17,11 @@ namespace Avalonia.Media
public static readonly StyledProperty<IVisual> VisualProperty =
AvaloniaProperty.Register<VisualBrush, IVisual>(nameof(Visual));
static VisualBrush()
{
AffectsRender<VisualBrush>(VisualProperty);
}
/// <summary>
/// Initializes a new instance of the <see cref="VisualBrush"/> class.
/// </summary>
@ -42,9 +48,9 @@ namespace Avalonia.Media
}
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
public override IBrush ToImmutable()
{
return new Immutable.ImmutableVisualBrush(this);
return new ImmutableVisualBrush(this);
}
}
}

2
tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs

@ -124,7 +124,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
GradientStops = new[]
GradientStops =
{
new GradientStop(Color.FromUInt32(0xffffffff), 0),
new GradientStop(Color.FromUInt32(0x00ffffff), 1)

4
tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs

@ -36,7 +36,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
{
StartPoint = new RelativePoint(0, 0.5, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 0.5, RelativeUnit.Relative),
GradientStops = new[]
GradientStops =
{
new GradientStop { Color = Colors.Red, Offset = 0 },
new GradientStop { Color = Colors.Blue, Offset = 1 }
@ -63,7 +63,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
{
StartPoint = new RelativePoint(0.5, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0.5, 1, RelativeUnit.Relative),
GradientStops = new[]
GradientStops =
{
new GradientStop { Color = Colors.Red, Offset = 0 },
new GradientStop { Color = Colors.Blue, Offset = 1 }

2
tests/Avalonia.RenderTests/Media/RadialGradientBrushTests.cs

@ -34,7 +34,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
{
Background = new RadialGradientBrush
{
GradientStops = new[]
GradientStops =
{
new GradientStop { Color = Colors.Red, Offset = 0 },
new GradientStop { Color = Colors.Blue, Offset = 1 }

4
tests/Avalonia.RenderTests/OpacityMaskTests.cs

@ -29,7 +29,7 @@ namespace Avalonia.Direct2D1.RenderTests
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
GradientStops = new List<GradientStop>
GradientStops =
{
new GradientStop(Color.FromUInt32(0xffffffff), 0),
new GradientStop(Color.FromUInt32(0x00ffffff), 1)
@ -65,7 +65,7 @@ namespace Avalonia.Direct2D1.RenderTests
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
GradientStops = new List<GradientStop>
GradientStops =
{
new GradientStop(Color.FromUInt32(0xffffffff), 0),
new GradientStop(Color.FromUInt32(0x00ffffff), 1)

27
tests/Avalonia.Visuals.UnitTests/Media/ImageBrushTests.cs

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Moq;
using Xunit;
namespace Avalonia.Visuals.UnitTests.Media
{
public class ImageBrushTests
{
[Fact]
public void Changing_Source_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new ImageBrush(bitmap1);
var raised = false;
target.Changed += (s, e) => raised = true;
target.Source = bitmap2;
Assert.True(raised);
}
}
}

86
tests/Avalonia.Visuals.UnitTests/Media/LinearGradientBrushTests.cs

@ -0,0 +1,86 @@
using System;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Moq;
using Xunit;
namespace Avalonia.Visuals.UnitTests.Media
{
public class LinearGradientBrushTests
{
[Fact]
public void Changing_StartPoint_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new LinearGradientBrush();
var raised = false;
target.StartPoint = new RelativePoint();
target.Changed += (s, e) => raised = true;
target.StartPoint = new RelativePoint(10, 10, RelativeUnit.Absolute);
Assert.True(raised);
}
[Fact]
public void Changing_EndPoint_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new LinearGradientBrush();
var raised = false;
target.EndPoint = new RelativePoint();
target.Changed += (s, e) => raised = true;
target.EndPoint = new RelativePoint(10, 10, RelativeUnit.Absolute);
Assert.True(raised);
}
[Fact]
public void Changing_GradientStops_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new LinearGradientBrush();
var raised = false;
target.GradientStops = new GradientStops { new GradientStop(Colors.Red, 0) };
target.Changed += (s, e) => raised = true;
target.GradientStops = new GradientStops { new GradientStop(Colors.Green, 0) };
Assert.True(raised);
}
[Fact]
public void Adding_GradientStop_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new LinearGradientBrush();
var raised = false;
target.GradientStops = new GradientStops { new GradientStop(Colors.Red, 0) };
target.Changed += (s, e) => raised = true;
target.GradientStops.Add(new GradientStop(Colors.Green, 1));
Assert.True(raised);
}
[Fact]
public void Changing_GradientStop_Offset_Raises_Changed()
{
var bitmap1 = Mock.Of<IBitmap>();
var bitmap2 = Mock.Of<IBitmap>();
var target = new LinearGradientBrush();
var raised = false;
target.GradientStops = new GradientStops { new GradientStop(Colors.Red, 0) };
target.Changed += (s, e) => raised = true;
target.GradientStops[0].Offset = 0.5;
Assert.True(raised);
}
}
}

21
tests/Avalonia.Visuals.UnitTests/Media/SolidColorBrushTests.cs

@ -0,0 +1,21 @@
using System;
using Avalonia.Media;
using Xunit;
namespace Avalonia.Visuals.UnitTests.Media
{
public class SolidColorBrushTests
{
[Fact]
public void Changing_Color_Raises_Changed()
{
var target = new SolidColorBrush(Colors.Red);
var raised = false;
target.Changed += (s, e) => raised = true;
target.Color = Colors.Green;
Assert.True(raised);
}
}
}
Loading…
Cancel
Save