Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Transform property for Brush class #6344

Merged
merged 29 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cb9f1bc
Add Transform property for Brush class
wieslawsoltes Aug 1, 2021
4cea7a7
Add Transform property to IBrush interface
wieslawsoltes Aug 1, 2021
4a443f6
Move transform
wieslawsoltes Aug 1, 2021
d47c479
Do not use not pattern
wieslawsoltes Aug 1, 2021
13f137c
Fix deferred rendering by using immutable transform
wieslawsoltes Aug 1, 2021
90a027a
Rename
wieslawsoltes Aug 1, 2021
e3bfa12
Use ImmutableTransform
wieslawsoltes Aug 1, 2021
4f90ab4
Check for null
wieslawsoltes Aug 1, 2021
e361b82
Add transform
wieslawsoltes Aug 1, 2021
167ad6c
Use ImmutableTransform
wieslawsoltes Aug 1, 2021
81daa4f
Add Matrix interpolation
wieslawsoltes Aug 1, 2021
cca7b96
Mark field as private
wieslawsoltes Aug 1, 2021
9733282
Add MatrixAnimator
wieslawsoltes Aug 1, 2021
0beaa1c
Fix tests
wieslawsoltes Aug 2, 2021
7f50f1b
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Aug 2, 2021
a139eb9
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Aug 6, 2021
cbfa104
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Aug 16, 2021
a717628
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Aug 17, 2021
addf992
Revert
wieslawsoltes Mar 10, 2022
a887a41
Remove animator
wieslawsoltes Mar 10, 2022
3d56742
Revert
wieslawsoltes Mar 10, 2022
9fd00e1
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Mar 10, 2022
5efb448
Add nullable annotations
wieslawsoltes Mar 10, 2022
1228dc0
Make nullable
wieslawsoltes Mar 10, 2022
34833ad
Update TransformExtensions.cs
wieslawsoltes Mar 10, 2022
a5992d3
Fix
wieslawsoltes Mar 10, 2022
8b2730b
Update ApiCompatBaseline.txt
wieslawsoltes Mar 10, 2022
f72189f
Merge branch 'master' into BrushTransformProperty
wieslawsoltes Mar 10, 2022
d2caf12
Add demo page for brushes with transforms
wieslawsoltes Mar 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class GradientBrushAnimator : Animator<IGradientBrush?>
return new ImmutableRadialGradientBrush(
InterpolateStops(progress, oldValue.GradientStops, newValue.GradientStops),
s_doubleAnimator.Interpolate(progress, oldValue.Opacity, newValue.Opacity),
oldValue.Transform,
wieslawsoltes marked this conversation as resolved.
Show resolved Hide resolved
oldValue.SpreadMethod,
s_relativePointAnimator.Interpolate(progress, oldRadial.Center, newRadial.Center),
s_relativePointAnimator.Interpolate(progress, oldRadial.GradientOrigin, newRadial.GradientOrigin),
Expand All @@ -39,6 +40,7 @@ public class GradientBrushAnimator : Animator<IGradientBrush?>
return new ImmutableConicGradientBrush(
InterpolateStops(progress, oldValue.GradientStops, newValue.GradientStops),
s_doubleAnimator.Interpolate(progress, oldValue.Opacity, newValue.Opacity),
oldValue.Transform,
oldValue.SpreadMethod,
s_relativePointAnimator.Interpolate(progress, oldConic.Center, newConic.Center),
s_doubleAnimator.Interpolate(progress, oldConic.Angle, newConic.Angle));
Expand All @@ -47,6 +49,7 @@ public class GradientBrushAnimator : Animator<IGradientBrush?>
return new ImmutableLinearGradientBrush(
InterpolateStops(progress, oldValue.GradientStops, newValue.GradientStops),
s_doubleAnimator.Interpolate(progress, oldValue.Opacity, newValue.Opacity),
oldValue.Transform,
oldValue.SpreadMethod,
s_relativePointAnimator.Interpolate(progress, oldLinear.StartPoint, newLinear.StartPoint),
s_relativePointAnimator.Interpolate(progress, oldLinear.EndPoint, newLinear.EndPoint));
Expand Down Expand Up @@ -93,16 +96,19 @@ internal static IGradientBrush ConvertSolidColorBrushToGradient(IGradientBrush g
case IRadialGradientBrush oldRadial:
return new ImmutableRadialGradientBrush(
CreateStopsFromSolidColorBrush(solidColorBrush, oldRadial.GradientStops), solidColorBrush.Opacity,
oldRadial.Transform,
oldRadial.SpreadMethod, oldRadial.Center, oldRadial.GradientOrigin, oldRadial.Radius);

case IConicGradientBrush oldConic:
return new ImmutableConicGradientBrush(
CreateStopsFromSolidColorBrush(solidColorBrush, oldConic.GradientStops), solidColorBrush.Opacity,
oldConic.Transform,
oldConic.SpreadMethod, oldConic.Center, oldConic.Angle);

case ILinearGradientBrush oldLinear:
return new ImmutableLinearGradientBrush(
CreateStopsFromSolidColorBrush(solidColorBrush, oldLinear.GradientStops), solidColorBrush.Opacity,
oldLinear.Transform,
oldLinear.SpreadMethod, oldLinear.StartPoint, oldLinear.EndPoint);

default:
Expand Down
10 changes: 9 additions & 1 deletion src/Avalonia.Visuals/ApiCompatBaseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Task
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean, System.Threading.CancellationToken)' is present in the implementation but not in the contract.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.PageSlide.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Media.ITransform Avalonia.Media.IBrush.Transform' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Media.ITransform Avalonia.Media.IBrush.Transform.get()' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Media.ITransform Avalonia.Media.IMutableTransform.ToImmutable()' is present in the implementation but not in the contract.
MembersMustExist : Member 'public void Avalonia.Media.Immutable.ImmutableConicGradientBrush..ctor(System.Collections.Generic.IReadOnlyList<Avalonia.Media.Immutable.ImmutableGradientStop>, System.Double, Avalonia.Media.GradientSpreadMethod, System.Nullable<Avalonia.RelativePoint>, System.Double)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'protected void Avalonia.Media.Immutable.ImmutableGradientBrush..ctor(System.Collections.Generic.IReadOnlyList<Avalonia.Media.Immutable.ImmutableGradientStop>, System.Double, Avalonia.Media.GradientSpreadMethod)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Media.Immutable.ImmutableLinearGradientBrush..ctor(System.Collections.Generic.IReadOnlyList<Avalonia.Media.Immutable.ImmutableGradientStop>, System.Double, Avalonia.Media.GradientSpreadMethod, System.Nullable<Avalonia.RelativePoint>, System.Nullable<Avalonia.RelativePoint>)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Media.Immutable.ImmutableRadialGradientBrush..ctor(System.Collections.Generic.IReadOnlyList<Avalonia.Media.Immutable.ImmutableGradientStop>, System.Double, Avalonia.Media.GradientSpreadMethod, System.Nullable<Avalonia.RelativePoint>, System.Nullable<Avalonia.RelativePoint>, System.Double)' does not exist in the implementation but it does exist in the contract.
TypeCannotChangeClassification : Type 'Avalonia.Media.Immutable.ImmutableSolidColorBrush' is a 'class' in the implementation but is a 'struct' in the contract.
MembersMustExist : Member 'protected void Avalonia.Media.Immutable.ImmutableTileBrush..ctor(Avalonia.Media.AlignmentX, Avalonia.Media.AlignmentY, Avalonia.RelativeRect, System.Double, Avalonia.RelativeRect, Avalonia.Media.Stretch, Avalonia.Media.TileMode, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext)' does not exist in the implementation but it does exist in the contract.
CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' is abstract in the implementation but is missing in the contract.
CannotSealType : Type 'Avalonia.Media.TextFormatting.GenericTextParagraphProperties' is actually (has the sealed modifier) sealed in the implementation but not sealed in the contract.
Expand Down Expand Up @@ -74,4 +82,4 @@ InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWr
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmap(System.String)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToHeight(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToWidth(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
Total Issues: 75
Total Issues: 83
17 changes: 16 additions & 1 deletion src/Avalonia.Visuals/Media/Brush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ public abstract class Brush : Animatable, IMutableBrush
public static readonly StyledProperty<double> OpacityProperty =
AvaloniaProperty.Register<Brush, double>(nameof(Opacity), 1.0);

/// <summary>
/// Defines the <see cref="Transform"/> property.
/// </summary>
public static readonly StyledProperty<ITransform> TransformProperty =
AvaloniaProperty.Register<Brush, ITransform>(nameof(Transform));

/// <inheritdoc/>
public event EventHandler Invalidated;

static Brush()
{
Animation.Animation.RegisterAnimator<BaseBrushAnimator>(prop => typeof(IBrush).IsAssignableFrom(prop.PropertyType));
AffectsRender<Brush>(OpacityProperty);
AffectsRender<Brush>(OpacityProperty, TransformProperty);
}

/// <summary>
Expand All @@ -36,6 +42,15 @@ public double Opacity
set { SetValue(OpacityProperty, value); }
}

/// <summary>
/// Gets or sets the transform of the brush.
/// </summary>
public ITransform Transform
{
get { return GetValue(TransformProperty); }
set { SetValue(TransformProperty, value); }
}

/// <summary>
/// Parses a brush string.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Avalonia.Visuals/Media/IBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ public interface IBrush
/// Gets the opacity of the brush.
/// </summary>
double Opacity { get; }

/// <summary>
/// Gets the transform of the brush.
/// </summary>
ITransform Transform { get; }
}
}
6 changes: 6 additions & 0 deletions src/Avalonia.Visuals/Media/IMutableTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@ public interface IMutableTransform : ITransform
/// Raised when the transform changes.
/// </summary>
event EventHandler Changed;

/// <summary>
/// Converts a transform to an immutable transform.
/// </summary>
/// <returns>The immutable transform</returns>
ITransform ToImmutable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ public class ImmutableConicGradientBrush : ImmutableGradientBrush, IConicGradien
/// </summary>
/// <param name="gradientStops">The gradient stops.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="transform">The transform of the brush.</param>
/// <param name="spreadMethod">The spread method.</param>
/// <param name="center">The center point for the gradient.</param>
/// <param name="angle">The starting angle for the gradient.</param>
public ImmutableConicGradientBrush(
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity = 1,
ITransform transform = null,
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad,
RelativePoint? center = null,
double angle = 0)
: base(gradientStops, opacity, spreadMethod)
: base(gradientStops, opacity, transform, spreadMethod)
{
Center = center ?? RelativePoint.Center;
Angle = angle;
Expand Down
10 changes: 9 additions & 1 deletion src/Avalonia.Visuals/Media/Immutable/ImmutableGradientBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ public abstract class ImmutableGradientBrush : IGradientBrush
/// </summary>
/// <param name="gradientStops">The gradient stops.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="transform">The transform of the brush.</param>
/// <param name="spreadMethod">The spread method.</param>
protected ImmutableGradientBrush(
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity,
ITransform transform,
GradientSpreadMethod spreadMethod)
{
GradientStops = gradientStops;
Opacity = opacity;
Transform = transform;
SpreadMethod = spreadMethod;
}

Expand All @@ -28,7 +31,7 @@ protected ImmutableGradientBrush(
/// </summary>
/// <param name="source">The brush from which this brush's properties should be copied.</param>
protected ImmutableGradientBrush(GradientBrush source)
: this(source.GradientStops.ToImmutable(), source.Opacity, source.SpreadMethod)
: this(source.GradientStops.ToImmutable(), source.Opacity, source.Transform.ToImmutable(), source.SpreadMethod)
{

}
Expand All @@ -39,6 +42,11 @@ protected ImmutableGradientBrush(GradientBrush source)
/// <inheritdoc/>
public double Opacity { get; }

/// <summary>
/// Gets the transform of the brush.
/// </summary>
public ITransform Transform { get; }

/// <inheritdoc/>
public GradientSpreadMethod SpreadMethod { get; }
}
Expand Down
3 changes: 3 additions & 0 deletions src/Avalonia.Visuals/Media/Immutable/ImmutableImageBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal class ImmutableImageBrush : ImmutableTileBrush, IImageBrush
/// <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="transform">The transform 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.
Expand All @@ -28,6 +29,7 @@ public ImmutableImageBrush(
AlignmentY alignmentY = AlignmentY.Center,
RelativeRect? destinationRect = null,
double opacity = 1,
ITransform transform = null,
RelativeRect? sourceRect = null,
Stretch stretch = Stretch.Uniform,
TileMode tileMode = TileMode.None,
Expand All @@ -37,6 +39,7 @@ public ImmutableImageBrush(
alignmentY,
destinationRect ?? RelativeRect.Fill,
opacity,
transform,
sourceRect ?? RelativeRect.Fill,
stretch,
tileMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ public class ImmutableLinearGradientBrush : ImmutableGradientBrush, ILinearGradi
/// </summary>
/// <param name="gradientStops">The gradient stops.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="transform">The transform 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<ImmutableGradientStop> gradientStops,
double opacity = 1,
ITransform transform = null,
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad,
RelativePoint? startPoint = null,
RelativePoint? endPoint = null)
: base(gradientStops, opacity, spreadMethod)
: base(gradientStops, opacity, transform, spreadMethod)
{
StartPoint = startPoint ?? RelativePoint.TopLeft;
EndPoint = endPoint ?? RelativePoint.BottomRight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class ImmutableRadialGradientBrush : ImmutableGradientBrush, IRadialGradi
/// </summary>
/// <param name="gradientStops">The gradient stops.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="transform">The transform of the brush.</param>
/// <param name="spreadMethod">The spread method.</param>
/// <param name="center">The start point for the gradient.</param>
/// <param name="gradientOrigin">
Expand All @@ -23,11 +24,12 @@ public class ImmutableRadialGradientBrush : ImmutableGradientBrush, IRadialGradi
public ImmutableRadialGradientBrush(
IReadOnlyList<ImmutableGradientStop> gradientStops,
double opacity = 1,
ITransform transform = null,
GradientSpreadMethod spreadMethod = GradientSpreadMethod.Pad,
RelativePoint? center = null,
RelativePoint? gradientOrigin = null,
double radius = 0.5)
: base(gradientStops, opacity, spreadMethod)
: base(gradientStops, opacity, transform, spreadMethod)
{
Center = center ?? RelativePoint.Center;
GradientOrigin = gradientOrigin ?? RelativePoint.Center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@ public ImmutableSolidColorBrush(ISolidColorBrush source)
/// </summary>
public double Opacity { get; }

/// <summary>
/// Gets the transform of the brush.
/// </summary>
public ITransform Transform { get; }

public bool Equals(ImmutableSolidColorBrush other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Color.Equals(other.Color) && Opacity.Equals(other.Opacity);
return Color.Equals(other.Color) && Opacity.Equals(other.Opacity) && (Transform == null && other.Transform == null ? true : Transform.Equals(other.Transform));
}

public override bool Equals(object obj)
Expand All @@ -62,7 +67,7 @@ public override int GetHashCode()
{
unchecked
{
return (Color.GetHashCode() * 397) ^ Opacity.GetHashCode();
return (Color.GetHashCode() * 397) ^ Opacity.GetHashCode() ^ (Transform is null ? 0 : Transform.GetHashCode());
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/Avalonia.Visuals/Media/Immutable/ImmutableTileBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public abstract class ImmutableTileBrush : ITileBrush
/// <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="transform">The transform 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.
Expand All @@ -25,6 +26,7 @@ protected ImmutableTileBrush(
AlignmentY alignmentY,
RelativeRect destinationRect,
double opacity,
ITransform transform,
RelativeRect sourceRect,
Stretch stretch,
TileMode tileMode,
Expand All @@ -34,6 +36,7 @@ protected ImmutableTileBrush(
AlignmentY = alignmentY;
DestinationRect = destinationRect;
Opacity = opacity;
Transform = transform;
SourceRect = sourceRect;
Stretch = stretch;
TileMode = tileMode;
Expand All @@ -50,6 +53,7 @@ protected ImmutableTileBrush(ITileBrush source)
source.AlignmentY,
source.DestinationRect,
source.Opacity,
source.Transform.ToImmutable(),
source.SourceRect,
source.Stretch,
source.TileMode,
Expand All @@ -69,6 +73,11 @@ protected ImmutableTileBrush(ITileBrush source)
/// <inheritdoc/>
public double Opacity { get; }

/// <summary>
/// Gets the transform of the brush.
/// </summary>
public ITransform Transform { get; }

/// <inheritdoc/>
public RelativeRect SourceRect { get; }

Expand Down
Loading