forked from AvaloniaUI/Avalonia
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
1,069 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using System; | ||
// ReSharper disable CheckNamespace | ||
namespace Avalonia.Media; | ||
|
||
public class BlurEffect : Effect, IBlurEffect, IMutableEffect | ||
{ | ||
public static readonly StyledProperty<double> RadiusProperty = AvaloniaProperty.Register<BlurEffect, double>( | ||
nameof(Radius), 5); | ||
|
||
public double Radius | ||
{ | ||
get => GetValue(RadiusProperty); | ||
set => SetValue(RadiusProperty, value); | ||
} | ||
|
||
static BlurEffect() | ||
{ | ||
AffectsRender<BlurEffect>(RadiusProperty); | ||
} | ||
|
||
public IImmutableEffect ToImmutable() => new ImmutableBlurEffect(Radius); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// ReSharper disable once CheckNamespace | ||
|
||
using System; | ||
// ReSharper disable CheckNamespace | ||
|
||
namespace Avalonia.Media; | ||
|
||
public abstract class DropShadowEffectBase : Effect | ||
{ | ||
public static readonly StyledProperty<double> BlurRadiusProperty = | ||
AvaloniaProperty.Register<DropShadowEffectBase, double>( | ||
nameof(BlurRadius), 5); | ||
|
||
public double BlurRadius | ||
{ | ||
get => GetValue(BlurRadiusProperty); | ||
set => SetValue(BlurRadiusProperty, value); | ||
} | ||
|
||
public static readonly StyledProperty<Color> ColorProperty = AvaloniaProperty.Register<DropShadowEffectBase, Color>( | ||
nameof(Color)); | ||
|
||
public Color Color | ||
{ | ||
get => GetValue(ColorProperty); | ||
set => SetValue(ColorProperty, value); | ||
} | ||
|
||
public static readonly StyledProperty<double> OpacityProperty = | ||
AvaloniaProperty.Register<DropShadowEffectBase, double>( | ||
nameof(Opacity), 1); | ||
|
||
public double Opacity | ||
{ | ||
get => GetValue(OpacityProperty); | ||
set => SetValue(OpacityProperty, value); | ||
} | ||
|
||
static DropShadowEffectBase() | ||
{ | ||
AffectsRender<DropShadowEffectBase>(BlurRadiusProperty, ColorProperty, OpacityProperty); | ||
} | ||
} | ||
|
||
public class DropShadowEffect : DropShadowEffectBase, IDropShadowEffect, IMutableEffect | ||
{ | ||
public static readonly StyledProperty<double> OffsetXProperty = AvaloniaProperty.Register<DropShadowEffect, double>( | ||
nameof(OffsetX), 3.5355); | ||
|
||
public double OffsetX | ||
{ | ||
get => GetValue(OffsetXProperty); | ||
set => SetValue(OffsetXProperty, value); | ||
} | ||
|
||
public static readonly StyledProperty<double> OffsetYProperty = AvaloniaProperty.Register<DropShadowEffect, double>( | ||
nameof(OffsetY), 3.5355); | ||
|
||
public double OffsetY | ||
{ | ||
get => GetValue(OffsetYProperty); | ||
set => SetValue(OffsetYProperty, value); | ||
} | ||
|
||
static DropShadowEffect() | ||
{ | ||
AffectsRender<DropShadowEffect>(OffsetXProperty, OffsetYProperty); | ||
} | ||
|
||
public IImmutableEffect ToImmutable() | ||
{ | ||
return new ImmutableDropShadowEffect(OffsetX, OffsetY, BlurRadius, Color, Opacity); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// This class is compatible with WPF's DropShadowEffect and provides Direction and ShadowDepth properties instead of OffsetX/OffsetY | ||
/// </summary> | ||
public class DropShadowDirectionEffect : DropShadowEffectBase, IDirectionDropShadowEffect, IMutableEffect | ||
{ | ||
public static readonly StyledProperty<double> ShadowDepthProperty = | ||
AvaloniaProperty.Register<DropShadowDirectionEffect, double>( | ||
nameof(ShadowDepth), 5); | ||
|
||
public double ShadowDepth | ||
{ | ||
get => GetValue(ShadowDepthProperty); | ||
set => SetValue(ShadowDepthProperty, value); | ||
} | ||
|
||
public static readonly StyledProperty<double> DirectionProperty = AvaloniaProperty.Register<DropShadowDirectionEffect, double>( | ||
nameof(Direction), 315); | ||
|
||
public double Direction | ||
{ | ||
get => GetValue(DirectionProperty); | ||
set => SetValue(DirectionProperty, value); | ||
} | ||
|
||
public double OffsetX => Math.Cos(Direction) * ShadowDepth; | ||
public double OffsetY => Math.Sin(Direction) * ShadowDepth; | ||
|
||
public IImmutableEffect ToImmutable() => new ImmutableDropShadowDirectionEffect(OffsetX, OffsetY, BlurRadius, Color, Opacity); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using System; | ||
using Avalonia.Animation; | ||
using Avalonia.Animation.Animators; | ||
using Avalonia.Reactive; | ||
using Avalonia.Rendering.Composition.Expressions; | ||
using Avalonia.Utilities; | ||
|
||
// ReSharper disable once CheckNamespace | ||
namespace Avalonia.Media; | ||
|
||
public class Effect : Animatable, IAffectsRender | ||
{ | ||
/// <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="Invalidated"/> event to be raised on the brush. | ||
/// </remarks> | ||
protected static void AffectsRender<T>(params AvaloniaProperty[] properties) | ||
where T : Effect | ||
{ | ||
var invalidateObserver = new AnonymousObserver<AvaloniaPropertyChangedEventArgs>( | ||
static e => (e.Sender as T)?.RaiseInvalidated(EventArgs.Empty)); | ||
|
||
foreach (var property in properties) | ||
{ | ||
property.Changed.Subscribe(invalidateObserver); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Raises the <see cref="Invalidated"/> event. | ||
/// </summary> | ||
/// <param name="e">The event args.</param> | ||
protected void RaiseInvalidated(EventArgs e) => Invalidated?.Invoke(this, e); | ||
|
||
/// <inheritdoc /> | ||
public event EventHandler? Invalidated; | ||
|
||
|
||
static Exception ParseError(string s) => throw new ArgumentException("Unable to parse effect: " + s); | ||
public static IEffect Parse(string s) | ||
{ | ||
var span = s.AsSpan(); | ||
var r = new TokenParser(span); | ||
if (r.TryConsume("blur")) | ||
{ | ||
if (!r.TryConsume('(') || !r.TryParseDouble(out var radius) || !r.TryConsume(')') || !r.IsEofWithWhitespace()) | ||
throw ParseError(s); | ||
return new ImmutableBlurEffect(radius); | ||
} | ||
|
||
|
||
if (r.TryConsume("drop-shadow")) | ||
{ | ||
if (!r.TryConsume('(') || !r.TryParseDouble(out var offsetX) | ||
|| !r.TryParseDouble(out var offsetY)) | ||
throw ParseError(s); | ||
double blurRadius = 0; | ||
var color = Colors.Black; | ||
if (!r.TryConsume(')')) | ||
{ | ||
if (!r.TryParseDouble(out blurRadius) || blurRadius < 0) | ||
throw ParseError(s); | ||
if (!r.TryConsume(')')) | ||
{ | ||
var endOfExpression = s.LastIndexOf(")", StringComparison.Ordinal); | ||
if (endOfExpression == -1) | ||
throw ParseError(s); | ||
|
||
if (!new TokenParser(span.Slice(endOfExpression + 1)).IsEofWithWhitespace()) | ||
throw ParseError(s); | ||
|
||
if (!Color.TryParse(span.Slice(r.Position, endOfExpression - r.Position).TrimEnd(), out color)) | ||
throw ParseError(s); | ||
return new ImmutableDropShadowEffect(offsetX, offsetY, blurRadius, color, 1); | ||
} | ||
} | ||
if (!r.IsEofWithWhitespace()) | ||
throw ParseError(s); | ||
return new ImmutableDropShadowEffect(offsetX, offsetY, blurRadius, color, 1); | ||
} | ||
|
||
throw ParseError(s); | ||
} | ||
|
||
static Effect() | ||
{ | ||
EffectAnimator.EnsureRegistered(); | ||
} | ||
} |
Oops, something went wrong.