diff --git a/AtomUI.sln b/AtomUI.sln index 64ef0fb..f2d431b 100644 --- a/AtomUI.sln +++ b/AtomUI.sln @@ -7,22 +7,33 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Theme", "src\AtomUI. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Base", "src\AtomUI.Base\AtomUI.Base.csproj", "{8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon", "src\AtomUI.Icon\AtomUI.Icon.csproj", "{B2A7349B-4B38-45CB-8D22-3E06D1E3650F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon.Generator", "src\AtomUI.Icon.Generator\AtomUI.Icon.Generator.csproj", "{954FB7F2-7706-4E2B-86D1-624F66C1EFF0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon.AntDesign", "src\AtomUI.Icon.AntDesign\AtomUI.Icon.AntDesign.csproj", "{021AE0B0-B148-4925-9C22-EBD5A7B43E95}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Generator", "src\AtomUI.Generator\AtomUI.Generator.csproj", "{30910056-F8F6-4429-B25E-722C57440210}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Demo.Desktop", "Samples\AtomUI.Demo.Desktop\AtomUI.Demo.Desktop.csproj", "{59931F42-8DD8-4DFC-9060-563841F39669}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.TestBase", "tests\AtomUI.TestBase\AtomUI.TestBase.csproj", "{EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Base.Tests", "tests\AtomUI.Base.Tests\AtomUI.Base.Tests.csproj", "{E41D737A-5CF0-4B33-9F51-2C1B1541659C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Controls", "src\AtomUI.Controls\AtomUI.Controls.csproj", "{A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{279BC2C9-A818-4D6C-9274-678649932057}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", "{B4C46C3E-0CCC-4861-95B6-CA08D501A46F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI", "packages\AtomUI\AtomUI.csproj", "{89A98C0D-B6F7-48CD-91C4-79FC0FED3615}" + ProjectSection(ProjectDependencies) = postProject + {87085491-3C99-4C8F-8FA6-F179B9569CE8} = {87085491-3C99-4C8F-8FA6-F179B9569CE8} + {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} = {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} + {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} = {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Platform.Win32", "src\AtomUI.Platform.Win32\AtomUI.Platform.Win32.csproj", "{9BF7EF51-4100-4EAE-8A95-FC5F1BD4A1E4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.IconPkg", "src\AtomUI.IconPkg\AtomUI.IconPkg.csproj", "{70AC4A1D-2D88-4703-9AB2-89E753E1A04B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.IconPkg.AntDesign", "src\AtomUI.IconPkg.AntDesign\AtomUI.IconPkg.AntDesign.csproj", "{796AC3CF-7A12-4183-9096-291738A62292}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.IconPkg.Generator", "src\AtomUI.IconPkg.Generator\AtomUI.IconPkg.Generator.csproj", "{C8BFCDBE-0DC2-411F-B2E4-439A0A8E1752}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{5EB2524C-30A5-4031-B424-4510E36C753E}" ProjectSection(SolutionItems) = preProject build\Common.props = build\Common.props @@ -37,19 +48,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{5EB2524C build\Version.props = build\Version.props EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{279BC2C9-A818-4D6C-9274-678649932057}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", "{B4C46C3E-0CCC-4861-95B6-CA08D501A46F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI", "packages\AtomUI\AtomUI.csproj", "{89A98C0D-B6F7-48CD-91C4-79FC0FED3615}" - ProjectSection(ProjectDependencies) = postProject - {021AE0B0-B148-4925-9C22-EBD5A7B43E95} = {021AE0B0-B148-4925-9C22-EBD5A7B43E95} - {87085491-3C99-4C8F-8FA6-F179B9569CE8} = {87085491-3C99-4C8F-8FA6-F179B9569CE8} - {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} = {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} - {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} = {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} - {B2A7349B-4B38-45CB-8D22-3E06D1E3650F} = {B2A7349B-4B38-45CB-8D22-3E06D1E3650F} - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -64,25 +62,10 @@ Global {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}.Debug|Any CPU.Build.0 = Debug|Any CPU {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}.Release|Any CPU.Build.0 = Release|Any CPU - {B2A7349B-4B38-45CB-8D22-3E06D1E3650F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2A7349B-4B38-45CB-8D22-3E06D1E3650F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2A7349B-4B38-45CB-8D22-3E06D1E3650F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B2A7349B-4B38-45CB-8D22-3E06D1E3650F}.Release|Any CPU.Build.0 = Release|Any CPU - {954FB7F2-7706-4E2B-86D1-624F66C1EFF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {954FB7F2-7706-4E2B-86D1-624F66C1EFF0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {954FB7F2-7706-4E2B-86D1-624F66C1EFF0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {954FB7F2-7706-4E2B-86D1-624F66C1EFF0}.Release|Any CPU.Build.0 = Release|Any CPU - {021AE0B0-B148-4925-9C22-EBD5A7B43E95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {021AE0B0-B148-4925-9C22-EBD5A7B43E95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {021AE0B0-B148-4925-9C22-EBD5A7B43E95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {021AE0B0-B148-4925-9C22-EBD5A7B43E95}.Release|Any CPU.Build.0 = Release|Any CPU {30910056-F8F6-4429-B25E-722C57440210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {30910056-F8F6-4429-B25E-722C57440210}.Debug|Any CPU.Build.0 = Debug|Any CPU {30910056-F8F6-4429-B25E-722C57440210}.Release|Any CPU.ActiveCfg = Release|Any CPU {30910056-F8F6-4429-B25E-722C57440210}.Release|Any CPU.Build.0 = Release|Any CPU - {59931F42-8DD8-4DFC-9060-563841F39669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {59931F42-8DD8-4DFC-9060-563841F39669}.Debug|Any CPU.Build.0 = Debug|Any CPU - {59931F42-8DD8-4DFC-9060-563841F39669}.Release|Any CPU.ActiveCfg = Release|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -96,14 +79,28 @@ Global {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Debug|Any CPU.Build.0 = Debug|Any CPU {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BF7EF51-4100-4EAE-8A95-FC5F1BD4A1E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BF7EF51-4100-4EAE-8A95-FC5F1BD4A1E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BF7EF51-4100-4EAE-8A95-FC5F1BD4A1E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BF7EF51-4100-4EAE-8A95-FC5F1BD4A1E4}.Release|Any CPU.Build.0 = Release|Any CPU + {70AC4A1D-2D88-4703-9AB2-89E753E1A04B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70AC4A1D-2D88-4703-9AB2-89E753E1A04B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70AC4A1D-2D88-4703-9AB2-89E753E1A04B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70AC4A1D-2D88-4703-9AB2-89E753E1A04B}.Release|Any CPU.Build.0 = Release|Any CPU + {796AC3CF-7A12-4183-9096-291738A62292}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {796AC3CF-7A12-4183-9096-291738A62292}.Debug|Any CPU.Build.0 = Debug|Any CPU + {796AC3CF-7A12-4183-9096-291738A62292}.Release|Any CPU.ActiveCfg = Release|Any CPU + {796AC3CF-7A12-4183-9096-291738A62292}.Release|Any CPU.Build.0 = Release|Any CPU + {C8BFCDBE-0DC2-411F-B2E4-439A0A8E1752}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8BFCDBE-0DC2-411F-B2E4-439A0A8E1752}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8BFCDBE-0DC2-411F-B2E4-439A0A8E1752}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8BFCDBE-0DC2-411F-B2E4-439A0A8E1752}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {954FB7F2-7706-4E2B-86D1-624F66C1EFF0} = {B4C46C3E-0CCC-4861-95B6-CA08D501A46F} {30910056-F8F6-4429-B25E-722C57440210} = {B4C46C3E-0CCC-4861-95B6-CA08D501A46F} - {59931F42-8DD8-4DFC-9060-563841F39669} = {279BC2C9-A818-4D6C-9274-678649932057} {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB} = {279BC2C9-A818-4D6C-9274-678649932057} {E41D737A-5CF0-4B33-9F51-2C1B1541659C} = {279BC2C9-A818-4D6C-9274-678649932057} EndGlobalSection diff --git a/packages/AtomUI/AtomUI.csproj b/packages/AtomUI/AtomUI.csproj index 36a5d9f..047b707 100644 --- a/packages/AtomUI/AtomUI.csproj +++ b/packages/AtomUI/AtomUI.csproj @@ -6,37 +6,43 @@ - - - - - - + + + + + + + + + - - - - - + + + + + + - - - - + - - + + + + + + + diff --git a/src/AtomUI.Base/AtomUI.Base.csproj b/src/AtomUI.Base/AtomUI.Base.csproj index f7f2ebc..72e1829 100644 --- a/src/AtomUI.Base/AtomUI.Base.csproj +++ b/src/AtomUI.Base/AtomUI.Base.csproj @@ -18,4 +18,8 @@ + + + + diff --git a/src/AtomUI.Base/MotionScene/AbstractMotion.cs b/src/AtomUI.Base/MotionScene/AbstractMotion.cs index 48c9092..fafce1e 100644 --- a/src/AtomUI.Base/MotionScene/AbstractMotion.cs +++ b/src/AtomUI.Base/MotionScene/AbstractMotion.cs @@ -1,188 +1,73 @@ -using System.Diagnostics; -using System.Reactive.Linq; -using AtomUI.Media; -using Avalonia; +using Avalonia; using Avalonia.Animation; using Avalonia.Animation.Easings; using Avalonia.Controls; -using Avalonia.Layout; -using Avalonia.Media; using Avalonia.Media.Transformation; +using Avalonia.Threading; namespace AtomUI.MotionScene; -public enum TransitionKind +internal class AbstractMotion : IMotion { - Double, - TransformOperations -} + public bool IsRunning { get; } -public record class MotionConfig -{ - public AvaloniaProperty Property { get; set; } - public object? StartValue { get; set; } - public object? EndValue { get; set; } - public Easing MotionEasing { get; set; } = new LinearEasing(); - public TimeSpan MotionDuration { get; set; } = TimeSpan.FromMilliseconds(300); - public TransitionKind TransitionKind { get; set; } + public RelativePoint RenderTransformOrigin { get; protected set; } + public IList Animations { get; } + public TimeSpan Duration { get; } + public Easing Easing { get; } + public FillMode PropertyValueFillMode { get; } - public MotionConfig(AvaloniaProperty targetProperty, object? startValue = null, object? endValue = null) + public AbstractMotion(TimeSpan duration, Easing? easing = null, FillMode fillMode = FillMode.Forward) { - Property = targetProperty; - StartValue = startValue; - EndValue = endValue; - } -} - -public abstract class AbstractMotion : AvaloniaObject, IMotion -{ - public bool IsRunning { get; } = false; - - private readonly Dictionary _motionConfigs; - private readonly List _transitions; - public IObservable? CompletedObservable { get; private set; } - - // 定义我们目前支持的动效属性 - public static readonly StyledProperty MotionOpacityProperty = - Visual.OpacityProperty.AddOwner(); - - public static readonly StyledProperty MotionWidthProperty = - Layoutable.WidthProperty.AddOwner(); - - public static readonly StyledProperty MotionHeightProperty = - Layoutable.HeightProperty.AddOwner(); - - public static readonly StyledProperty MotionRenderTransformOriginProperty = - Visual.RenderTransformOriginProperty.AddOwner(); - - public static readonly StyledProperty MotionRenderTransformProperty = - Visual.RenderTransformProperty.AddOwner(); - - protected double MotionOpacity - { - get => GetValue(MotionOpacityProperty); - set => SetValue(MotionOpacityProperty, value); + Animations = new List(); + Duration = duration; + Easing = easing ?? new LinearEasing(); + PropertyValueFillMode = fillMode; } - protected double MotionWidth + public async Task RunAsync(MotionActorControl actor, + Action? aboutToStart = null, + Action? completedAction = null, + CancellationToken cancellationToken = default) { - get => GetValue(MotionWidthProperty); - set => SetValue(MotionWidthProperty, value); - } - - protected double MotionHeight - { - get => GetValue(MotionHeightProperty); - set => SetValue(MotionHeightProperty, value); - } - - internal RelativePoint MotionRenderTransformOrigin - { - get => GetValue(MotionRenderTransformOriginProperty); - set => SetValue(MotionRenderTransformOriginProperty, value); - } - - protected ITransform? MotionRenderTransform - { - get => GetValue(MotionRenderTransformProperty); - set => SetValue(MotionRenderTransformProperty, value); - } - - public AbstractMotion() - { - _motionConfigs = new Dictionary(); - _transitions = new List(); - } - - /// - /// 创建动效动画对象 - /// - /// - /// - internal List BuildTransitions(Control motionTarget) - { - foreach (var entry in _motionConfigs) + Configure(); + await Dispatcher.UIThread.InvokeAsync(async () => { - var config = entry.Value; - NotifyPreBuildTransition(config, motionTarget); - var transition = NotifyBuildTransition(config); - _transitions.Add(transition); - } - - var completedObservables = new IObservable[_transitions.Count]; - for (var i = 0; i < _transitions.Count; ++i) - { - var transition = _transitions[i]; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) + using var originRestore = new RenderTransformOriginRestore(actor); + actor.RenderTransformOrigin = RenderTransformOrigin; + actor.NotifyMotionPreStart(); + NotifyPreStart(); + if (aboutToStart is not null) { - completedObservables[i] = notifyTransitionCompleted.CompletedObservable; + aboutToStart(); } - } - - CompletedObservable = - Observable.CombineLatest(completedObservables).Select(list => { return list.All(v => v); }); - return _transitions; + actor.IsVisible = true; + foreach (var animation in Animations) + { + await animation.RunAsync(actor, cancellationToken); + } + + actor.NotifyMotionCompleted(); + NotifyCompleted(); + if (completedAction is not null) + { + completedAction(); + } + }); } - // 生命周期接口 - internal virtual void NotifyPreStart() + protected virtual void Configure() { } - internal virtual void NotifyStarted() + protected virtual void NotifyPreStart() { } - internal virtual void NotifyCompleted() + protected virtual void NotifyCompleted() { } - internal virtual void NotifyConfigMotionTarget(Control motionTarget) - { - } - - internal virtual void NotifyRestoreMotionTarget(Control motionTarget) - { - } - - protected virtual void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - } - - protected virtual ITransition NotifyBuildTransition(MotionConfig config) - { - TransitionBase transition = default!; - if (config.TransitionKind == TransitionKind.Double) - { - transition = new NotifiableDoubleTransition(); - } - else if (config.TransitionKind == TransitionKind.TransformOperations) - { - transition = new NotifiableTransformOperationsTransition(); - } - - transition.Property = config.Property; - transition.Duration = config.MotionDuration; - transition.Easing = config.MotionEasing; - return transition; - } - - protected MotionConfig? GetMotionConfig(AvaloniaProperty property) - { - if (_motionConfigs.TryGetValue(property, out var motionConfig)) - { - return motionConfig; - } - - return null; - } - - protected void AddMotionConfig(MotionConfig config) - { - Debug.Assert(!_motionConfigs.ContainsKey(config.Property)); - _motionConfigs.Add(config.Property, config); - } - /// /// 计算顶层动画渲染层的大小 /// @@ -208,42 +93,69 @@ public abstract class AbstractMotion : AvaloniaObject, IMotion return motionTargetPosition; } - public IList GetActivatedProperties() - { - return _motionConfigs.Keys.ToList(); - } - - public IList GetMotionConfigs() - { - return _motionConfigs.Values.ToList(); - } - - protected TransformOperations BuildScaleTransform(double scaleX, double scaleY) + protected static TransformOperations BuildScaleTransform(double scaleX, double scaleY) { var builder = new TransformOperations.Builder(1); builder.AppendScale(scaleX, scaleY); return builder.Build(); } - protected TransformOperations BuildScaleTransform(double scale) + protected static TransformOperations BuildScaleTransform(double scale) { return BuildScaleTransform(scale, scale); } - protected TransformOperations BuildScaleXTransform(double scale) + protected static TransformOperations BuildScaleXTransform(double scale) { return BuildScaleTransform(scale, 1.0); } - protected TransformOperations BuildScaleYTransform(double scale) + protected static TransformOperations BuildScaleYTransform(double scale) { return BuildScaleTransform(1.0, scale); } - protected TransformOperations BuildTranslateTransform(double offsetX, double offsetY) + protected static TransformOperations BuildTranslateTransform(double offsetX, double offsetY) { var builder = new TransformOperations.Builder(1); builder.AppendTranslate(offsetX, offsetY); return builder.Build(); } + + protected static TransformOperations BuildTranslateScaleAndTransform( + double scaleX, double scaleY, double offsetX, double offsetY) + { + var builder = new TransformOperations.Builder(2); + builder.AppendScale(scaleX, scaleY); + builder.AppendTranslate(offsetX, offsetY); + return builder.Build(); + } + + protected Animation CreateAnimation() + { + var animation = new Animation + { + Duration = Duration, + Easing = Easing, + FillMode = PropertyValueFillMode + }; + return animation; + } +} + +internal class RenderTransformOriginRestore : IDisposable +{ + RelativePoint _origin; + Control _target; + + public RenderTransformOriginRestore(Control target) + { + _target = target; + _origin = target.RenderTransformOrigin; + } + + public void Dispose() + { + _target.RenderTransformOrigin = _origin; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/CollapseMotion.cs b/src/AtomUI.Base/MotionScene/CollapseMotion.cs deleted file mode 100644 index 8367802..0000000 --- a/src/AtomUI.Base/MotionScene/CollapseMotion.cs +++ /dev/null @@ -1,139 +0,0 @@ -using Avalonia.Animation.Easings; -using Avalonia.Controls; -using Avalonia.Layout; - -namespace AtomUI.MotionScene; - -public class CollapseMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); - - /// - /// 收起的方向,垂直还是水平方向 - /// - public Orientation Orientation { get; set; } = Orientation.Vertical; - - public void ConfigureHeight(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(Orientation == Orientation.Vertical - ? MotionHeightProperty - : MotionWidthProperty) - { - TransitionKind = TransitionKind.Double, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionHeightProperty) - { - if (!double.IsNaN(motionTarget.Height)) - { - config.StartValue = Math.Ceiling(motionTarget.Height); - } - else - { - config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Height); - } - } - else if (config.Property == MotionWidthProperty) - { - if (!double.IsNaN(motionTarget.Width)) - { - config.StartValue = Math.Ceiling(motionTarget.Width); - } - else - { - config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Width); - } - } - } -} - -public class ExpandMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); - - /// - /// 展开的方向,垂直还是水平方向 - /// - public Orientation Orientation { get; set; } = Orientation.Vertical; - - public void ConfigureHeight(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(Orientation == Orientation.Vertical - ? MotionHeightProperty - : MotionWidthProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionHeightProperty) - { - if (!double.IsNaN(motionTarget.Height)) - { - config.EndValue = Math.Ceiling(motionTarget.Height); - } - else - { - config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Height); - } - } - else if (config.Property == MotionWidthProperty) - { - if (!double.IsNaN(motionTarget.Width)) - { - config.EndValue = Math.Ceiling(motionTarget.Width); - } - else - { - config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Width); - } - } - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/CollapseMotionFactory.cs b/src/AtomUI.Base/MotionScene/CollapseMotions.cs similarity index 64% rename from src/AtomUI.Base/MotionScene/CollapseMotionFactory.cs rename to src/AtomUI.Base/MotionScene/CollapseMotions.cs index 1ebe96a..3be60c3 100644 --- a/src/AtomUI.Base/MotionScene/CollapseMotionFactory.cs +++ b/src/AtomUI.Base/MotionScene/CollapseMotions.cs @@ -5,21 +5,23 @@ using Avalonia.Styling; namespace AtomUI.MotionScene; -internal static partial class MotionFactory +internal class CollapseMotion : AbstractMotion { - public static MotionConfigX BuildCollapseMotion(Direction direction, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + public Direction Direction { get; } + + public CollapseMotion(Direction direction, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseOut(), fillMode) { - easing ??= new CubicEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var isHorizontal = direction == Direction.Left || direction == Direction.Right; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + Direction = direction; + } + + protected override void Configure() + { + var isHorizontal = Direction == Direction.Left || Direction == Direction.Right; + var animation = CreateAnimation(); var startFrame = new KeyFrame { @@ -85,41 +87,44 @@ internal static partial class MotionFactory } animation.Children.Add(endFrame); - if (direction == Direction.Left) + if (Direction == Direction.Left) { - transformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); } - else if (direction == Direction.Right) + else if (Direction == Direction.Right) { - transformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); } - else if (direction == Direction.Top) + else if (Direction == Direction.Top) { - transformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); } else { - transformOrigin = new RelativePoint(0.5, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 0.0, RelativeUnit.Relative); } - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class ExpandMotion : AbstractMotion +{ + public Direction Direction { get; } + + public ExpandMotion(Direction direction, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseIn(), fillMode) + { + Direction = direction; } - public static MotionConfigX BuildExpandMotion(Direction direction, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var isHorizontal = direction == Direction.Left || direction == Direction.Right; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var isHorizontal = Direction == Direction.Left || Direction == Direction.Right; + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -185,24 +190,23 @@ internal static partial class MotionFactory animation.Children.Add(endFrame); - if (direction == Direction.Left) + if (Direction == Direction.Left) { - transformOrigin = new RelativePoint(1.0, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(1.0, 0.5, RelativeUnit.Relative); } - else if (direction == Direction.Right) + else if (Direction == Direction.Right) { - transformOrigin = new RelativePoint(0.0, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.5, RelativeUnit.Relative); } - else if (direction == Direction.Top) + else if (Direction == Direction.Top) { - transformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); } else { - transformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); } - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/Director.cs b/src/AtomUI.Base/MotionScene/Director.cs deleted file mode 100644 index b4a7d0f..0000000 --- a/src/AtomUI.Base/MotionScene/Director.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System.Reactive.Disposables; -using AtomUI.MotionScene; -using Avalonia; -using Avalonia.Threading; - -namespace AtomUI.Controls.MotionScene; - -public class Director : IDirector -{ - public event EventHandler? MotionPreStart; - public event EventHandler? MotionStarted; - public event EventHandler? MotionCompleted; - - public static IDirector? Instance => AvaloniaLocator.Current.GetService(); - private readonly Dictionary _states; - private CompositeDisposable? _compositeDisposable; - - public Director() - { - _states = new Dictionary(); - } - - /// - /// 目前的实现暂时一个 Actor 只能投递一次,后面可以实现一个等待队列 - /// - /// - public void Schedule(MotionActor actor) - { - if (_states.ContainsKey(actor)) - { - return; - } - - actor.NotifyPostedToDirector(); - SceneLayer? sceneLayer = default; - if (actor.DispatchInSceneLayer) - { - sceneLayer = PrepareSceneLayer(actor); - } - - _compositeDisposable = new CompositeDisposable(); - _compositeDisposable.Add(Disposable.Create(sceneLayer, state => - { - if (sceneLayer is not null) - { - Dispatcher.UIThread.InvokeAsync(async () => - { - await Task.Delay(300); - sceneLayer.Hide(); - sceneLayer.Dispose(); - }); - } - })); - var state = new MotionActorState(actor, _compositeDisposable); - _states.Add(actor, state); - - if (actor.DispatchInSceneLayer) - { - state.SceneLayer = sceneLayer; - var ghost = actor.GetAnimatableGhost(); - sceneLayer!.SetMotionTarget(ghost); - actor.NotifyMotionTargetAddedToScene(ghost); - sceneLayer.Show(); - sceneLayer.Topmost = true; - actor.NotifySceneShowed(); - } - - HandleMotionPreStart(actor); - ExecuteMotionAction(actor); - HandleMotionStarted(actor); - } - - private SceneLayer PrepareSceneLayer(MotionActor actor) - { - if (actor.SceneParent is null) - { - throw new ArgumentException( - "When the DispatchInSceneLayer property is true, the SceneParent property cannot be null."); - } - - // TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类 - // 暂时先处理 Popup 这种情况 - var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!); - actor.NotifySceneLayerCreated(sceneLayer); - return sceneLayer; - } - - private void ExecuteMotionAction(MotionActor actor) - { - // 根据 Motion 配置的对 Actor 对象的属性赋值 - actor.EnableMotion(); - foreach (var motionConfig in actor.Motion.GetMotionConfigs()) - { - var property = motionConfig.Property; - var endValue = motionConfig.EndValue; - actor.SetValue(property, endValue); - } - } - - private class MotionActorState : IDisposable - { - private readonly IDisposable _cleanup; - - public IMotionActor MotionActor { get; } - public SceneLayer? SceneLayer; - - public MotionActorState(IMotionActor motionActor, IDisposable cleanup) - { - MotionActor = motionActor; - _cleanup = cleanup; - } - - public void Dispose() - { - _cleanup.Dispose(); - } - } - - private void HandleMotionPreStart(MotionActor actor) - { - actor.NotifyMotionPreStart(); - MotionPreStart?.Invoke(this, new MotionEventArgs(actor)); - if (actor.Motion.CompletedObservable is null) - { - throw new InvalidOperationException("The CompletedObservable property of the Motion is empty."); - } - - // 设置相关的完成检测 - _compositeDisposable?.Add(actor.Motion.CompletedObservable.Subscribe( - status => { actor.CompletedStatus = status; }, () => { HandleMotionCompleted(actor); })); - - // 设置动画对象初始值 - foreach (var motionConfig in actor.Motion.GetMotionConfigs()) - { - var property = motionConfig.Property; - var startValue = motionConfig.StartValue; - actor.SetValue(property, startValue); - } - } - - private void HandleMotionStarted(MotionActor actor) - { - actor.NotifyMotionStarted(); - MotionStarted?.Invoke(this, new MotionEventArgs(actor)); - } - - private void HandleMotionCompleted(MotionActor actor) - { - if (_states.TryGetValue(actor, out var state)) - { - if (state.SceneLayer is not null) - { - state.SceneLayer.Opacity = 0; - } - - actor.NotifyMotionCompleted(); - MotionCompleted?.Invoke(this, new MotionEventArgs(actor)); - state.Dispose(); - _states.Remove(actor); - } - } -} - -public class MotionEventArgs : EventArgs -{ - public MotionActor MotionActor; - - public MotionEventArgs(MotionActor motionActor) - { - MotionActor = motionActor; - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/FadeMotion.cs b/src/AtomUI.Base/MotionScene/FadeMotion.cs deleted file mode 100644 index 0be8a20..0000000 --- a/src/AtomUI.Base/MotionScene/FadeMotion.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Avalonia.Animation.Easings; - -namespace AtomUI.MotionScene; - -public class FadeInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - - public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) - { - easing ??= new LinearEasing(); - originOpacity = Math.Clamp(originOpacity, 0d, 1d); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = originOpacity, - EndValue = 1.0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class FadeOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - - public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) - { - easing ??= new LinearEasing(); - originOpacity = Math.Clamp(originOpacity, 0d, 1d); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = originOpacity, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/FadeMotions.cs b/src/AtomUI.Base/MotionScene/FadeMotions.cs new file mode 100644 index 0000000..b6817e9 --- /dev/null +++ b/src/AtomUI.Base/MotionScene/FadeMotions.cs @@ -0,0 +1,96 @@ +using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; +using Avalonia.Styling; + +namespace AtomUI.MotionScene; + +internal class FadeInMotion : AbstractMotion +{ + public FadeInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new LinearEasing(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + + Animations.Add(animation); + } +} + +internal class FadeOutMotion : AbstractMotion +{ + public FadeOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new LinearEasing(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + + Animations.Add(animation); + } +} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IDirector.cs b/src/AtomUI.Base/MotionScene/IDirector.cs deleted file mode 100644 index 001fcfe..0000000 --- a/src/AtomUI.Base/MotionScene/IDirector.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AtomUI.MotionScene; - -public interface IDirector -{ - public void Schedule(MotionActor actor); -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IMotion.cs b/src/AtomUI.Base/MotionScene/IMotion.cs index 6ff1853..4bf0227 100644 --- a/src/AtomUI.Base/MotionScene/IMotion.cs +++ b/src/AtomUI.Base/MotionScene/IMotion.cs @@ -1,17 +1,20 @@ using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; namespace AtomUI.MotionScene; -public interface IMotion +internal interface IMotion { public bool IsRunning { get; } + public RelativePoint RenderTransformOrigin { get; } + public IList Animations { get; } + public TimeSpan Duration { get; } + public Easing Easing { get; } + public FillMode PropertyValueFillMode { get; } - /// - /// 获取当前动效激活的动画属性列表 - /// - /// - public IList GetActivatedProperties(); - - public IList GetMotionConfigs(); - public IObservable? CompletedObservable { get; } + public Task RunAsync(MotionActorControl actor, + Action? aboutToStart = null, + Action? completedAction = null, + CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IMotionActor.cs b/src/AtomUI.Base/MotionScene/IMotionActor.cs deleted file mode 100644 index 90b86f8..0000000 --- a/src/AtomUI.Base/MotionScene/IMotionActor.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.MotionScene; - -internal interface IMotionActor -{ - public event EventHandler? PreStart; - public event EventHandler? Started; - public event EventHandler? Completed; - - public bool CompletedStatus { get; } - - public Control MotionTarget { get; set; } - public IMotion Motion { get; } - public bool DispatchInSceneLayer { get; set; } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs b/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs index 3477e1b..d9a0663 100644 --- a/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs +++ b/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs @@ -3,4 +3,5 @@ internal interface INotifyCaptureGhostBitmap { public void NotifyCaptureGhostBitmap(); + public void NotifyClearGhostBitmap(); } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionActor.cs b/src/AtomUI.Base/MotionScene/MotionActor.cs deleted file mode 100644 index 0239e72..0000000 --- a/src/AtomUI.Base/MotionScene/MotionActor.cs +++ /dev/null @@ -1,393 +0,0 @@ -using System.Reflection; -using AtomUI.Media; -using AtomUI.Utils; -using Avalonia; -using Avalonia.Animation; -using Avalonia.Controls; -using Avalonia.Data; -using Avalonia.Layout; -using Avalonia.Media; -using Avalonia.VisualTree; - -namespace AtomUI.MotionScene; - -/// -/// 动效配置类,只要给 Director 提供动效相关信息 -/// 动效驱动 Actor 的属性,然后由 Actor 驱动动画控件,防止污染动画控件的 Transitions 配置 -/// -public class MotionActor : Animatable, IMotionActor -{ - public event EventHandler? PreStart; - public event EventHandler? Started; - public event EventHandler? Completed; - public event EventHandler? SceneShowed; - - public static readonly StyledProperty MotionOpacityProperty = - Visual.OpacityProperty.AddOwner(); - - public static readonly StyledProperty MotionWidthProperty = - Layoutable.WidthProperty.AddOwner(); - - public static readonly StyledProperty MotionHeightProperty = - Layoutable.HeightProperty.AddOwner(); - - public static readonly StyledProperty MotionRenderTransformProperty = - Visual.RenderTransformProperty.AddOwner(); - - private static readonly MethodInfo EnableTransitionsMethodInfo; - private static readonly MethodInfo DisableTransitionsMethodInfo; - - public bool CompletedStatus { get; internal set; } = true; - - protected double MotionOpacity - { - get => GetValue(MotionOpacityProperty); - set => SetValue(MotionOpacityProperty, value); - } - - protected double MotionWidth - { - get => GetValue(MotionWidthProperty); - set => SetValue(MotionWidthProperty, value); - } - - protected double MotionHeight - { - get => GetValue(MotionHeightProperty); - set => SetValue(MotionHeightProperty, value); - } - - protected ITransform? MotionRenderTransform - { - get => GetValue(MotionRenderTransformProperty); - set => SetValue(MotionRenderTransformProperty, value); - } - - private double _originOpacity; - private double _originWidth; - private double _originHeight; - private ITransform? _originRenderTransform; - private RelativePoint _originRenderTransformOrigin; - private readonly Dictionary _transitionsMap; - - private class AnimationState - { - public ITransition? Transition { get; set; } - public object? StartValue { get; set; } - public object? EndValue { get; set; } - } - - /// - /// 动画实体 - /// - public Control MotionTarget { get; set; } - - /// - /// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup - /// - public TopLevel? SceneParent { get; set; } - - public IMotion Motion => _motion; - public bool DispatchInSceneLayer { get; set; } = true; - - protected Control? _ghost; - protected AbstractMotion _motion; - - static MotionActor() - { - EnableTransitionsMethodInfo = - typeof(Animatable).GetMethod("EnableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!; - DisableTransitionsMethodInfo = - typeof(Animatable).GetMethod("DisableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!; - MotionWidthProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionHeightProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionOpacityProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionRenderTransformProperty.Changed.AddClassHandler(HandlePropertyChanged); - } - - private static void HandlePropertyChanged(MotionActor actor, AvaloniaPropertyChangedEventArgs args) - { - var property = args.Property; - var oldValue = args.OldValue; - var newValue = args.NewValue; - var priority = args.Priority; - if (!actor._transitionsMap.ContainsKey(property)) - { - return; - } - - var state = actor._transitionsMap[property]; - if (actor.IsAnimating(property) && priority == BindingPriority.Animation) - { - // 判断新值是否相等 - if (property.PropertyType == typeof(double)) - { - var currentValue = (double)newValue!; - var endValue = (double)state.EndValue!; - if (MathUtils.AreClose(currentValue, endValue)) - { - var transition = state.Transition; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) - { - notifyTransitionCompleted.NotifyTransitionCompleted(true); - } - } - } - else if (property.PropertyType.IsAssignableTo(typeof(ITransform))) - { - var currentValue = (ITransform)newValue!; - var endValue = (ITransform)state.EndValue!; - if (currentValue.Value == endValue.Value) - { - var transition = state.Transition; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) - { - notifyTransitionCompleted.NotifyTransitionCompleted(true); - } - } - } - } - } - - public MotionActor(Control motionTarget, AbstractMotion motion) - { - MotionTarget = motionTarget; - _motion = motion; - _transitionsMap = new Dictionary(); - } - - public bool IsSupportMotionProperty(AvaloniaProperty property) - { - if (property == AbstractMotion.MotionOpacityProperty || - property == AbstractMotion.MotionWidthProperty || - property == AbstractMotion.MotionHeightProperty || - property == AbstractMotion.MotionRenderTransformProperty) - { - return true; - } - - return false; - } - - protected virtual void BuildGhost() - { - } - - public Control GetAnimatableGhost() - { - return _ghost ?? MotionTarget; - } - - /// - /// 当在 DispatchInSceneLayer 渲染的时候,Ghost 的全局坐标 - /// - /// - public Point CalculateGhostPosition() - { - Point point = default; - if (!DispatchInSceneLayer) - { - var visualParent = MotionTarget.GetVisualParent(); - if (visualParent is not null) - { - var parentPoint = MotionTarget.TranslatePoint(new Point(0, 0), visualParent); - if (parentPoint.HasValue) - { - point = parentPoint.Value; - } - else - { - point = MotionTarget.Bounds.Position; - } - } - } - else - { - point = CalculateTopLevelGhostPosition(); - } - - return point; - } - - protected virtual Point CalculateTopLevelGhostPosition() - { - return default; - } - - /// - /// 在这个接口中,Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小 - /// - /// - public virtual void NotifySceneLayerCreated(SceneLayer sceneLayer) - { - if (!DispatchInSceneLayer) - { - return; - } - - var ghost = GetAnimatableGhost(); - - Size motionTargetSize; - // Popup.Child can't be null here, it was set in ShowAtCore. - if (ghost.DesiredSize == default) - { - // Popup may not have been shown yet. Measure content - motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness()); - } - else - { - motionTargetSize = ghost.DesiredSize; - } - - var sceneSize = _motion.CalculateSceneSize(motionTargetSize); - var scenePosition = _motion.CalculateScenePosition(motionTargetSize, CalculateGhostPosition()); - sceneLayer.MoveAndResize(scenePosition, sceneSize); - } - - public virtual void NotifyPostedToDirector() - { - DisableMotion(); - BuildGhost(); - var transitions = new Transitions(); - foreach (var transition in _motion.BuildTransitions(GetAnimatableGhost())) - { - transitions.Add(transition); - } - - Transitions = transitions; - } - - /// - /// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小 - /// - /// - public virtual void NotifyMotionTargetAddedToScene(Control motionTarget) - { - Canvas.SetLeft(motionTarget, 0); - Canvas.SetTop(motionTarget, 0); - } - - public virtual void NotifySceneShowed() - { - SceneShowed?.Invoke(this, EventArgs.Empty); - } - - internal void EnableMotion() - { - EnableTransitionsMethodInfo.Invoke(this, new object[] { }); - } - - internal void DisableMotion() - { - DisableTransitionsMethodInfo.Invoke(this, new object[] { }); - } - - internal virtual void NotifyMotionPreStart() - { - if (Transitions is not null) - { - foreach (var transition in Transitions) - { - _transitionsMap.Add(transition.Property, new AnimationState - { - Transition = transition - }); - } - } - - foreach (var motionConfig in _motion.GetMotionConfigs()) - { - var property = motionConfig.Property; - var state = _transitionsMap[property]; - state.StartValue = motionConfig.StartValue; - state.EndValue = motionConfig.EndValue; - } - - SaveMotionTargetState(); - _motion.NotifyPreStart(); - _motion.NotifyConfigMotionTarget(GetAnimatableGhost()); - PreStart?.Invoke(this, EventArgs.Empty); - } - - internal virtual void NotifyMotionStarted() - { - _motion.NotifyStarted(); - Started?.Invoke(this, EventArgs.Empty); - } - - internal virtual void NotifyMotionCompleted() - { - RestoreMotionTargetState(); - Completed?.Invoke(this, EventArgs.Empty); - _motion.NotifyCompleted(); - _motion.NotifyRestoreMotionTarget(GetAnimatableGhost()); - _transitionsMap.Clear(); - } - - private void SaveMotionTargetState() - { - var target = GetAnimatableGhost(); - foreach (var motionConfig in _motion.GetMotionConfigs()) - { - if (motionConfig.Property == MotionHeightProperty) - { - _originHeight = target.Height; - } - else if (motionConfig.Property == MotionWidthProperty) - { - _originWidth = target.Width; - } - else if (motionConfig.Property == MotionOpacityProperty) - { - _originOpacity = target.Opacity; - } - else if (motionConfig.Property == MotionRenderTransformProperty) - { - _originRenderTransform = target.RenderTransform; - _originRenderTransformOrigin = target.RenderTransformOrigin; - } - } - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - if (change.Property == MotionWidthProperty || - change.Property == MotionHeightProperty || - change.Property == MotionOpacityProperty || - change.Property == MotionRenderTransformProperty) - { - var ghost = GetAnimatableGhost(); - ghost.SetCurrentValue(change.Property, change.NewValue); - } - } - - private void RestoreMotionTargetState() - { - var target = GetAnimatableGhost(); - if (target == MotionTarget) - { - foreach (var motionConfig in _motion.GetMotionConfigs()) - { - if (motionConfig.Property == MotionHeightProperty) - { - target.SetValue(MotionHeightProperty, _originHeight); - } - else if (motionConfig.Property == MotionWidthProperty) - { - target.SetValue(MotionWidthProperty, _originWidth); - } - else if (motionConfig.Property == MotionOpacityProperty) - { - target.SetValue(MotionOpacityProperty, _originOpacity); - } - else if (motionConfig.Property == MotionRenderTransformProperty) - { - target.SetValue(MotionRenderTransformProperty, _originRenderTransform); - target.SetValue(MotionRenderTransformProperty, _originRenderTransform); - target.SetValue(Visual.RenderTransformOriginProperty, _originRenderTransformOrigin); - } - } - } - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionActorControl.cs b/src/AtomUI.Base/MotionScene/MotionActorControl.cs index ff10357..66aa246 100644 --- a/src/AtomUI.Base/MotionScene/MotionActorControl.cs +++ b/src/AtomUI.Base/MotionScene/MotionActorControl.cs @@ -6,13 +6,13 @@ using Avalonia.Media.Transformation; namespace AtomUI.MotionScene; -public class MotionActorControl : Decorator +internal class MotionActorControl : Decorator { #region 公共属性定义 public static readonly StyledProperty MotionTransformProperty = AvaloniaProperty.Register(nameof(MotionTransform)); - + public static readonly StyledProperty UseRenderTransformProperty = AvaloniaProperty.Register(nameof(UseRenderTransform)); @@ -27,11 +27,18 @@ public class MotionActorControl : Decorator get => GetValue(UseRenderTransformProperty); set => SetValue(UseRenderTransformProperty, value); } - + public Control? MotionTransformRoot => Child; #endregion + #region 公共事件定义 + + public event EventHandler? PreStart; + public event EventHandler? Completed; + + #endregion + /// /// RenderTransform/MatrixTransform applied to MotionTransformRoot. /// @@ -58,6 +65,11 @@ public class MotionActorControl : Decorator /// Actual DesiredSize of Child element (the value it returned from its MeasureOverride method). /// private Size _childActualSize; + + /// + /// 动画是否在 + /// + private bool _animating = false; static MotionActorControl() { @@ -96,6 +108,7 @@ public class MotionActorControl : Decorator MotionTransformRoot.RenderTransform = _matrixTransform; MotionTransformRoot.RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Absolute); } + ApplyMotionTransform(); } @@ -116,7 +129,7 @@ public class MotionActorControl : Decorator { return; } - + _transformation = matrix; _matrixTransform.Matrix = UseRenderTransform ? matrix : FilterScaleTransform(matrix); RenderTransform = _matrixTransform; @@ -162,7 +175,7 @@ public class MotionActorControl : Decorator // Determine the largest available size after the transformation Size finalSizeTransformed = ComputeLargestTransformedSize(finalSize); - + if (IsSizeSmaller(finalSizeTransformed, MotionTransformRoot.DesiredSize)) { // Some elements do not like being given less space than they asked for (ex: TextBlock) @@ -211,7 +224,7 @@ public class MotionActorControl : Decorator return base.MeasureOverride(availableSize); } - Size measureSize ; + Size measureSize; if (_childActualSize == default) { // Determine the largest size after the transformation @@ -224,7 +237,7 @@ public class MotionActorControl : Decorator } // Perform a measure on the MotionTransformRoot (containing Child) - if (MotionTransformRoot.DesiredSize == default) + if (MotionTransformRoot.DesiredSize == default || _animating == false) { MotionTransformRoot.Measure(measureSize); } @@ -393,4 +406,17 @@ public class MotionActorControl : Decorator { return (a.Width + AcceptableDelta < b.Width) || (a.Height + AcceptableDelta < b.Height); } + + internal virtual void NotifyMotionPreStart() + { + PreStart?.Invoke(this, EventArgs.Empty); + _animating = true; + } + + internal virtual void NotifyMotionCompleted() + { + _animating = false; + InvalidateMeasure(); + Completed?.Invoke(this, EventArgs.Empty); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionFactory.cs b/src/AtomUI.Base/MotionScene/MotionFactory.cs deleted file mode 100644 index 935995d..0000000 --- a/src/AtomUI.Base/MotionScene/MotionFactory.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Avalonia; -using Avalonia.Animation; -using Avalonia.Media.Transformation; - -namespace AtomUI.MotionScene; - -internal record MotionConfigX -{ - public RelativePoint RenderTransformOrigin { get; } - public IList Animations { get; } - - public MotionConfigX(RelativePoint renderTransformOrigin, IList animations) - { - RenderTransformOrigin = renderTransformOrigin; - Animations = animations; - } -} - -internal static partial class MotionFactory -{ - public static TransformOperations BuildScaleTransform(double scaleX, double scaleY) - { - var builder = new TransformOperations.Builder(1); - builder.AppendScale(scaleX, scaleY); - return builder.Build(); - } - - public static TransformOperations BuildScaleTransform(double scale) - { - return BuildScaleTransform(scale, scale); - } - - public static TransformOperations BuildScaleXTransform(double scale) - { - return BuildScaleTransform(scale, 1.0); - } - - public static TransformOperations BuildScaleYTransform(double scale) - { - return BuildScaleTransform(1.0, scale); - } - - public static TransformOperations BuildTranslateTransform(double offsetX, double offsetY) - { - var builder = new TransformOperations.Builder(1); - builder.AppendTranslate(offsetX, offsetY); - return builder.Build(); - } - - public static TransformOperations BuildTranslateScaleAndTransform(double scaleX, double scaleY, double offsetX, double offsetY) - { - var builder = new TransformOperations.Builder(2); - builder.AppendScale(scaleX, scaleY); - builder.AppendTranslate(offsetX, offsetY); - return builder.Build(); - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionInvoker.cs b/src/AtomUI.Base/MotionScene/MotionInvoker.cs index 7d2b579..b549c8f 100644 --- a/src/AtomUI.Base/MotionScene/MotionInvoker.cs +++ b/src/AtomUI.Base/MotionScene/MotionInvoker.cs @@ -1,52 +1,90 @@ -using Avalonia; -using Avalonia.Controls; +using System.Reactive.Disposables; using Avalonia.Threading; namespace AtomUI.MotionScene; internal static class MotionInvoker { - public static void Invoke(MotionActorControl target, - MotionConfigX motionConfig, + public static void Invoke(MotionActorControl actor, + AbstractMotion motion, Action? aboutToStart = null, Action? completedAction = null, CancellationToken cancellationToken = default) { - Dispatcher.UIThread.InvokeAsync(async () => + Dispatcher.UIThread.Invoke(async () => { - using var originRestore = new RenderTransformOriginRestore(target); - target.RenderTransformOrigin = motionConfig.RenderTransformOrigin; - if (aboutToStart != null) - { - aboutToStart(); - } + await motion.RunAsync(actor, aboutToStart, completedAction, cancellationToken); + }); + } - foreach (var animation in motionConfig.Animations) - { - await animation.RunAsync(target, cancellationToken); - } + public static async Task InvokeAsync(MotionActorControl actor, + AbstractMotion motion, + Action? aboutToStart = null, + Action? completedAction = null, + CancellationToken cancellationToken = default) + { + await motion.RunAsync(actor, aboutToStart, completedAction, cancellationToken); + } - if (completedAction != null) + public static void InvokeInPopupLayer(SceneMotionActorControl actor, + AbstractMotion motion, + Action? aboutToStart = null, + Action? completedAction = null, + CancellationToken cancellationToken = default) + { + Dispatcher.UIThread.Invoke(async () => + { + await InvokeInPopupLayerAsync(actor, motion, aboutToStart, completedAction, cancellationToken); + }); + } + + public static async Task InvokeInPopupLayerAsync(SceneMotionActorControl actor, + AbstractMotion motion, + Action? aboutToStart = null, + Action? completedAction = null, + CancellationToken cancellationToken = default) + { + actor.BuildGhost(); + SceneLayer sceneLayer = PrepareSceneLayer(motion, actor); + var compositeDisposable = new CompositeDisposable(); + compositeDisposable.Add(Disposable.Create(sceneLayer, (state) => + { + Dispatcher.UIThread.Invoke(async () => + { + await Task.Delay(300); + sceneLayer.Hide(); + sceneLayer.Dispose(); + }); + })); + sceneLayer.SetMotionActor(actor); + actor.NotifyMotionTargetAddedToScene(); + sceneLayer.Show(); + sceneLayer.Topmost = true; + actor.NotifySceneShowed(); + actor.IsVisible = false; + + await motion.RunAsync(actor, aboutToStart, () => + { + compositeDisposable.Dispose(); + if (completedAction is not null) { completedAction(); } - }); - } -} - -internal class RenderTransformOriginRestore : IDisposable -{ - RelativePoint _origin; - Control _target; - - public RenderTransformOriginRestore(Control target) - { - _target = target; - _origin = target.RenderTransformOrigin; + }, cancellationToken); } - public void Dispose() + private static SceneLayer PrepareSceneLayer(AbstractMotion motion, SceneMotionActorControl actor) { - _target.RenderTransformOrigin = _origin; + if (actor.SceneParent is null) + { + throw new ArgumentException( + "When the DispatchInSceneLayer property is true, the SceneParent property cannot be null."); + } + + // TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类 + // 暂时先处理 Popup 这种情况 + var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!); + actor.NotifySceneLayerCreated(motion, sceneLayer); + return sceneLayer; } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MoveMotion.cs b/src/AtomUI.Base/MotionScene/MoveMotion.cs deleted file mode 100644 index fa58b5b..0000000 --- a/src/AtomUI.Base/MotionScene/MoveMotion.cs +++ /dev/null @@ -1,407 +0,0 @@ -using Avalonia; -using Avalonia.Animation.Easings; -using Avalonia.Controls; - -namespace AtomUI.MotionScene; - -public class MoveDownInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.StartValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); - } -} - -public class MoveDownOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.EndValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); - } -} - -public class MoveLeftInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.StartValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); - } -} - -public class MoveLeftOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.EndValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); - } -} - -public class MoveRightInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.StartValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } -} - -public class MoveRightOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.EndValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } -} - -public class MoveUpInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.StartValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } -} - -public class MoveUpOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) - { - config.EndValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MoveMotionFactory.cs b/src/AtomUI.Base/MotionScene/MoveMotions.cs similarity index 69% rename from src/AtomUI.Base/MotionScene/MoveMotionFactory.cs rename to src/AtomUI.Base/MotionScene/MoveMotions.cs index fec1766..1a990ec 100644 --- a/src/AtomUI.Base/MotionScene/MoveMotionFactory.cs +++ b/src/AtomUI.Base/MotionScene/MoveMotions.cs @@ -6,23 +6,22 @@ using Avalonia.Styling; namespace AtomUI.MotionScene; -internal static partial class MotionFactory +internal class MoveDownInMotion : AbstractMotion { - public static MotionConfigX BuildMoveDownInMotion(double offset, - TimeSpan duration, - Easing? easing = null, - FillMode fillMode = FillMode.None) - { - easing ??= new QuinticEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + public double Offset { get; } + public MoveDownInMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseOut(), fillMode) + { + Offset = offset; + } + + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -38,7 +37,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.01, 0.0, offset) + Value = BuildTranslateScaleAndTransform(1.0, 0.01, 0.0, Offset) }; startFrame.Setters.Add(transformSetter); } @@ -59,7 +58,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, offset / 4) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, Offset / 4) }; middleFrame.Setters.Add(transformSetter); } @@ -85,27 +84,38 @@ internal static partial class MotionFactory endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Height * 2); } - public static MotionConfigX BuildMoveDownOutMotion(double offset, - TimeSpan duration, - Easing? easing = null, - FillMode fillMode = FillMode.None) + internal override Point CalculateScenePosition(Size actorSize, Point actorPosition) { - easing ??= new QuinticEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + return actorPosition.WithY(actorPosition.Y + actorSize.Height); + } +} +internal class MoveDownOutMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveDownOutMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseIn(), fillMode) + { + Offset = offset; + } + + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -143,7 +153,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, offset / 4) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, Offset / 4) }; middleFrame.Setters.Add(transformSetter); } @@ -164,30 +174,38 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.0, 0.0, offset) + Value = BuildTranslateScaleAndTransform(1.0, 0.0, 0.0, Offset) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Height * 2); + } +} + +internal class MoveUpInMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveUpInMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseOut(), fillMode) + { + Offset = offset; } - public static MotionConfigX BuildMoveUpInMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new QuinticEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -203,7 +221,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.01, 0.0, -offset) + Value = BuildTranslateScaleAndTransform(1.0, 0.01, 0.0, -Offset) }; startFrame.Setters.Add(transformSetter); } @@ -224,7 +242,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, -offset / 4) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, -Offset / 4) }; middleFrame.Setters.Add(transformSetter); } @@ -250,25 +268,38 @@ internal static partial class MotionFactory endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Height * 2); + } + + internal override Point CalculateScenePosition(Size actorSize, Point actorPosition) + { + return actorPosition.WithY(actorPosition.Y - actorSize.Height); + } +} + +internal class MoveUpOutMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveUpOutMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseIn(), fillMode) + { + Offset = offset; } - public static MotionConfigX BuildMoveUpOutMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new QuinticEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -313,7 +344,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, -offset / 4) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, 0.0, -Offset / 4) }; middleFrame.Setters.Add(transformSetter); @@ -335,31 +366,39 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.0, 0.0, -offset) + Value = BuildTranslateScaleAndTransform(1.0, 0.0, 0.0, -Offset) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Height * 2); + } +} + +internal class MoveLeftInMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveLeftInMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseOut(), fillMode) + { + Offset = offset; } - public static MotionConfigX BuildMoveLeftInMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new QuinticEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -375,7 +414,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.01, -offset, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 0.01, -Offset, 0.0) }; startFrame.Setters.Add(transformSetter); @@ -397,7 +436,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, -offset / 2, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, -Offset / 2, 0.0) }; middleFrame.Setters.Add(transformSetter); @@ -425,25 +464,38 @@ internal static partial class MotionFactory endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithWidth(actorSize.Width * 2); } - public static MotionConfigX BuildMoveLeftOutMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + internal override Point CalculateScenePosition(Size actorSize, Point actorPosition) { - easing ??= new QuinticEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + return actorPosition.WithX(actorPosition.X - actorSize.Width); + } +} +internal class MoveLeftOutMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveLeftOutMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseIn(), fillMode) + { + Offset = offset; + } + + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -479,7 +531,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, -offset / 2, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, -Offset / 2, 0.0) }; middleFrame.Setters.Add(transformSetter); } @@ -500,29 +552,38 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.0, -offset, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 0.0, -Offset, 0.0) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Width * 2); + } +} + +internal class MoveRightInMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveRightInMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseOut(), fillMode) + { + Offset = offset; } - public static MotionConfigX BuildMoveRightInMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new QuinticEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + var animation = CreateAnimation(); var startFrame = new KeyFrame { @@ -539,7 +600,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.01, offset, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 0.01, Offset, 0.0) }; startFrame.Setters.Add(transformSetter); } @@ -560,7 +621,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, offset / 2, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, Offset / 2, 0.0) }; middleFrame.Setters.Add(transformSetter); } @@ -586,25 +647,38 @@ internal static partial class MotionFactory endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Width * 2); + } + + internal override Point CalculateScenePosition(Size actorSize, Point actorPosition) + { + return actorPosition.WithY(actorPosition.X + actorSize.Height); + } +} + +internal class MoveRightOutMotion : AbstractMotion +{ + public double Offset { get; } + + public MoveRightOutMotion(double offset, + TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new QuinticEaseIn(), fillMode) + { + Offset = offset; } - public static MotionConfigX BuildMoveRightOutMotion(double offset, TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new QuinticEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -641,7 +715,7 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 1.0, offset / 2, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 1.0, Offset / 2, 0.0) }; middleFrame.Setters.Add(transformSetter); } @@ -662,14 +736,18 @@ internal static partial class MotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = BuildTranslateScaleAndTransform(1.0, 0.0, offset, 0.0) + Value = BuildTranslateScaleAndTransform(1.0, 0.0, Offset, 0.0) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } + + internal override Size CalculateSceneSize(Size actorSize) + { + return actorSize.WithHeight(actorSize.Width * 2); } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SceneLayer.cs b/src/AtomUI.Base/MotionScene/SceneLayer.cs index 6228e9d..002707a 100644 --- a/src/AtomUI.Base/MotionScene/SceneLayer.cs +++ b/src/AtomUI.Base/MotionScene/SceneLayer.cs @@ -1,19 +1,20 @@ using System.Reflection; -using AtomUI.Platform.Windows; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Media; using Avalonia.Platform; using Avalonia.VisualTree; +using AtomUI.Platform.Windows; namespace AtomUI.MotionScene; -public class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable +internal class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable { private readonly IManagedPopupPositionerPopup? _managedPopupPositionerPopup; private static readonly FieldInfo ManagedPopupPositionerPopupInfo; private readonly Canvas _layout; + private SceneMotionActorControl? _motionActorControl; static SceneLayer() { @@ -88,9 +89,10 @@ public class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable PlatformImpl?.Dispose(); } - public void SetMotionTarget(Control motionTarget) + public void SetMotionActor(SceneMotionActorControl actorControl) { - _layout.Children.Add(motionTarget); + _motionActorControl = actorControl; + _layout.Children.Add(actorControl); } // 这个地方我们可以需要定制 @@ -149,12 +151,9 @@ public class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable protected override void OnOpened(EventArgs e) { base.OnOpened(e); - foreach (var child in _layout.Children) + if (_motionActorControl is not null) { - if (child is INotifyCaptureGhostBitmap captureGhost) - { - captureGhost.NotifyCaptureGhostBitmap(); - } + _motionActorControl.NotifySceneLayerHostWinOpened(); } } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SceneMotionActorControl.cs b/src/AtomUI.Base/MotionScene/SceneMotionActorControl.cs new file mode 100644 index 0000000..471cca1 --- /dev/null +++ b/src/AtomUI.Base/MotionScene/SceneMotionActorControl.cs @@ -0,0 +1,107 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; + +namespace AtomUI.MotionScene; + +internal class SceneMotionActorControl : MotionActorControl +{ + public event EventHandler? SceneShowed; + + #region 公共属性定义 + + /// + /// 动画实体 + /// + public Control MotionTarget { get; set; } + + #endregion + + #region 内部属性定义 + + /// + /// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup + /// + public TopLevel? SceneParent { get; set; } + + #endregion + + protected Control? _ghost; + + public SceneMotionActorControl(Control motionTarget) + { + MotionTarget = motionTarget; + UseRenderTransform = true; + } + + internal virtual void BuildGhost() + { + } + + public Control GetAnimatableGhost() + { + return _ghost ?? this; + } + + protected virtual Point CalculateTopLevelGhostPosition() + { + return default; + } + + /// + /// 在这个接口中,Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小 + /// + /// + /// + public virtual void NotifySceneLayerCreated(AbstractMotion motion, SceneLayer sceneLayer) + { + var ghost = GetAnimatableGhost(); + + Size motionTargetSize; + // Popup.Child can't be null here, it was set in ShowAtCore. + if (ghost.DesiredSize == default) + { + // Popup may not have been shown yet. Measure content + motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness()); + } + else + { + motionTargetSize = ghost.DesiredSize; + } + + var sceneSize = motion.CalculateSceneSize(motionTargetSize); + var scenePosition = motion.CalculateScenePosition(motionTargetSize, CalculateTopLevelGhostPosition()); + sceneLayer.MoveAndResize(scenePosition, sceneSize); + } + + /// + /// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小 + /// + public virtual void NotifyMotionTargetAddedToScene() + { + Canvas.SetLeft(this, 0); + Canvas.SetTop(this, 0); + } + + public virtual void NotifySceneShowed() + { + SceneShowed?.Invoke(this, EventArgs.Empty); + } + + internal virtual void NotifySceneLayerHostWinOpened() + { + if (_ghost is INotifyCaptureGhostBitmap captureGhost) + { + captureGhost.NotifyCaptureGhostBitmap(); + } + } + + internal override void NotifyMotionCompleted() + { + base.NotifyMotionCompleted(); + if (_ghost is INotifyCaptureGhostBitmap notifyCaptureGhostBitmap) + { + notifyCaptureGhostBitmap.NotifyClearGhostBitmap(); + } + } +} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SlideMotion.cs b/src/AtomUI.Base/MotionScene/SlideMotion.cs deleted file mode 100644 index 0d02c8f..0000000 --- a/src/AtomUI.Base/MotionScene/SlideMotion.cs +++ /dev/null @@ -1,329 +0,0 @@ -using Avalonia; -using Avalonia.Animation.Easings; -using Avalonia.Controls; - -namespace AtomUI.MotionScene; - -public class SlideUpInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(0.8), - EndValue = BuildScaleYTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class SlideUpOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = BuildScaleYTransform(1.0), - EndValue = BuildScaleYTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class SlideDownInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public SlideDownInMotion() - { - MotionRenderTransformOrigin = RelativePoint.BottomRight; - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(0.8), - EndValue = BuildScaleYTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class SlideDownOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public SlideDownOutMotion() - { - MotionRenderTransformOrigin = RelativePoint.BottomRight; - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(1.0), - EndValue = BuildScaleYTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class SlideLeftInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(0.8), - EndValue = BuildScaleXTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class SlideLeftOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = BuildScaleXTransform(1.0), - EndValue = BuildScaleXTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class SlideRightInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public SlideRightInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(0.8), - EndValue = BuildScaleXTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class SlideRightOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public SlideRightOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(1.0), - EndValue = BuildScaleXTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SlideMotionFactory.cs b/src/AtomUI.Base/MotionScene/SlideMotions.cs similarity index 64% rename from src/AtomUI.Base/MotionScene/SlideMotionFactory.cs rename to src/AtomUI.Base/MotionScene/SlideMotions.cs index 2eefc49..fe7daa0 100644 --- a/src/AtomUI.Base/MotionScene/SlideMotionFactory.cs +++ b/src/AtomUI.Base/MotionScene/SlideMotions.cs @@ -5,21 +5,18 @@ using Avalonia.Styling; namespace AtomUI.MotionScene; -internal static partial class MotionFactory +internal class SlideUpInMotion : AbstractMotion { - public static MotionConfigX BuildSlideUpInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + public SlideUpInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseOut(), fillMode) { - easing ??= new CubicEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + } + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -59,25 +56,24 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleYSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideUpOutMotion : AbstractMotion +{ + public SlideUpOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseIn(), fillMode) + { } - public static MotionConfigX BuildSlideUpOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -118,25 +114,24 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleYSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideDownInMotion : AbstractMotion +{ + public SlideDownInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseOut(), fillMode) + { } - public static MotionConfigX BuildSlideDownInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -177,25 +172,24 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleYSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideDownOutMotion : AbstractMotion +{ + public SlideDownOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseIn(), fillMode) + { } - public static MotionConfigX BuildSlideDownOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -236,25 +230,24 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleYSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideLeftInMotion : AbstractMotion +{ + public SlideLeftInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseOut(), fillMode) + { } - public static MotionConfigX BuildSlideLeftInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -295,25 +288,24 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleXSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideLeftOutMotion : AbstractMotion +{ + public SlideLeftOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseIn(), fillMode) + { } - public static MotionConfigX BuildSlideLeftOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -354,25 +346,82 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleXSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class SlideRightInMotion : AbstractMotion +{ + public SlideRightInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseOut(), fillMode) + { } - public static MotionConfigX BuildSlideRightInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CubicEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation + var animation = CreateAnimation(); + var startFrame = new KeyFrame { - Duration = duration, - Easing = easing, - FillMode = fillMode + Cue = new Cue(0.0) }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + var scaleXSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleXTransform(1.0) + }; + startFrame.Setters.Add(scaleXSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + var scaleXSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleXTransform(0.0) + }; + endFrame.Setters.Add(scaleXSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative); + + Animations.Add(animation); + } +} + +internal class SlideRightOutMotion : AbstractMotion +{ + public SlideRightOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CubicEaseIn(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -413,68 +462,8 @@ internal static partial class MotionFactory endFrame.Setters.Add(scaleXSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); } - - public static MotionConfigX BuildSlideRightOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) - { - easing ??= new CubicEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - - var startFrame = new KeyFrame - { - Cue = new Cue(0.0) - }; - { - var opacitySetter = new Setter - { - Property = Visual.OpacityProperty, - Value = 1.0 - }; - startFrame.Setters.Add(opacitySetter); - - var scaleXSetter = new Setter - { - Property = MotionActorControl.MotionTransformProperty, - Value = BuildScaleXTransform(1.0) - }; - startFrame.Setters.Add(scaleXSetter); - } - animation.Children.Add(startFrame); - - var endFrame = new KeyFrame - { - Cue = new Cue(1.0) - }; - { - var opacitySetter = new Setter - { - Property = Visual.OpacityProperty, - Value = 0.0 - }; - endFrame.Setters.Add(opacitySetter); - var scaleXSetter = new Setter - { - Property = MotionActorControl.MotionTransformProperty, - Value = BuildScaleXTransform(0.0) - }; - endFrame.Setters.Add(scaleXSetter); - } - animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(1.0, 0.0, RelativeUnit.Relative); - - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); - } -} \ No newline at end of file +} diff --git a/src/AtomUI.Base/MotionScene/ZoomMotion.cs b/src/AtomUI.Base/MotionScene/ZoomMotion.cs deleted file mode 100644 index b3e8c22..0000000 --- a/src/AtomUI.Base/MotionScene/ZoomMotion.cs +++ /dev/null @@ -1,514 +0,0 @@ -using Avalonia; -using Avalonia.Animation.Easings; -using Avalonia.Controls; - -namespace AtomUI.MotionScene; - -public class ZoomInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.2), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class ZoomOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.2), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class ZoomBigInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } -} - -public class ZoomBigOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } -} - -public class ZoomUpInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomUpInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomUpOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomUpOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomLeftInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomLeftInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomLeftOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomLeftOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomRightInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomRightInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomRightOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomRightOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomDownInMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomDownInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} - -public class ZoomDownOutMotion : AbstractMotion -{ - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public ZoomDownOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/ZoomMotions.cs b/src/AtomUI.Base/MotionScene/ZoomMotions.cs new file mode 100644 index 0000000..5bdf48d --- /dev/null +++ b/src/AtomUI.Base/MotionScene/ZoomMotions.cs @@ -0,0 +1,714 @@ +using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; +using Avalonia.Styling; + +namespace AtomUI.MotionScene; + +internal class ZoomInMotion : AbstractMotion +{ + public ZoomInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomOutMotion : AbstractMotion +{ + public ZoomOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomBigInMotion : AbstractMotion +{ + public ZoomBigInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.85) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomBigOutMotion : AbstractMotion +{ + public ZoomBigOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.85) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomUpInMotion : AbstractMotion +{ + public ZoomUpInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.5, 0.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomUpOutMotion : AbstractMotion +{ + public ZoomUpOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.5, 0.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomLeftInMotion : AbstractMotion +{ + public ZoomLeftInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.5, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomLeftOutMotion : AbstractMotion +{ + public ZoomLeftOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.0, 0.5, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomRightInMotion : AbstractMotion +{ + public ZoomRightInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(1.0, 0.5, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomRightOutMotion : AbstractMotion +{ + public ZoomRightOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(1.0, 0.5, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomDownInMotion : AbstractMotion +{ + public ZoomDownInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} + +internal class ZoomDownOutMotion : AbstractMotion +{ + public ZoomDownOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { + } + + protected override void Configure() + { + var animation = CreateAnimation(); + + var startFrame = new KeyFrame + { + Cue = new Cue(0.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 1.0 + }; + startFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(1.0) + }; + startFrame.Setters.Add(transformSetter); + } + animation.Children.Add(startFrame); + + var endFrame = new KeyFrame + { + Cue = new Cue(1.0) + }; + { + var opacitySetter = new Setter + { + Property = Visual.OpacityProperty, + Value = 0.0 + }; + endFrame.Setters.Add(opacitySetter); + + var transformSetter = new Setter + { + Property = MotionActorControl.MotionTransformProperty, + Value = BuildScaleTransform(0.01) + }; + endFrame.Setters.Add(transformSetter); + } + animation.Children.Add(endFrame); + RenderTransformOrigin = new RelativePoint(0.5, 1.0, RelativeUnit.Relative); + Animations.Add(animation); + } +} \ No newline at end of file diff --git a/src/AtomUI.Base/Platform/Windows/WindowExt.cs b/src/AtomUI.Base/Platform/Windows/WindowExt.cs deleted file mode 100644 index 65e664d..0000000 --- a/src/AtomUI.Base/Platform/Windows/WindowExt.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Reflection; -using System.Runtime.Loader; -using Avalonia.Controls; - -namespace AtomUI.Platform.Windows; - -internal static class WindowExt -{ - public const uint WS_EX_TRANSPARENT = 32; // 0x00000020 - public const uint WS_EX_LAYERED = 0x00080000; - private static readonly Type WindowImplType; - private static readonly MethodInfo GetExtendedStyleInfo; - private static readonly MethodInfo SetExtendedStyleInfo; - - static WindowExt() - { - var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("Avalonia.Win32")); - WindowImplType = assembly.GetType("Avalonia.Win32.WindowImpl")!; - GetExtendedStyleInfo = - WindowImplType.GetMethod("GetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; - SetExtendedStyleInfo = - WindowImplType.GetMethod("SetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; - } - - public static void SetTransparentForMouseEvents(this WindowBase window, bool flag) - { - var impl = window.PlatformImpl!; - var currentStyles = GetExtendedStyle(impl); - // 不是确定这样处理是否合适 - if (flag) - { - currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; - } - else - { - currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); - } - - SetExtendedStyle(impl, currentStyles, false); - } - - public static void SetTransparentForMouseEvents(this Window window, bool flag) - { - var impl = window.PlatformImpl!; - var currentStyles = GetExtendedStyle(impl); - // 不是确定这样处理是否合适 - if (flag) - { - currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; - } - else - { - currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); - } - - SetExtendedStyle(impl, currentStyles, false); - } - - private static uint GetExtendedStyle(object instance) - { - return (uint)GetExtendedStyleInfo.Invoke(instance, new object[] { })!; - } - - private static void SetExtendedStyle(object instance, uint styles, bool save) - { - SetExtendedStyleInfo.Invoke(instance, new object[] { styles, save }); - } - - public static bool IsTransparentForMouseEvents(this WindowBase window) - { - var impl = window.PlatformImpl!; - var styles = GetExtendedStyle(impl); - return (styles & WS_EX_TRANSPARENT) != 0; - } -} \ No newline at end of file diff --git a/src/AtomUI.Base/Utils/AnimationUtils.cs b/src/AtomUI.Base/Utils/AnimationUtils.cs new file mode 100644 index 0000000..b15a50c --- /dev/null +++ b/src/AtomUI.Base/Utils/AnimationUtils.cs @@ -0,0 +1,26 @@ +using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; + +namespace AtomUI.Utils; + +public class AnimationUtils +{ + protected AnimationUtils() {} + + public static ITransition CreateTransition(AvaloniaProperty targetProperty, + TimeSpan? duration = null, + Easing? easing = null) + where T : TransitionBase, new() + { + easing ??= new LinearEasing(); + duration ??= TimeSpan.FromMilliseconds(300); + var transition = new T + { + Property = targetProperty, + Easing = easing, + Duration = duration.Value + }; + return transition; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs index 794a34e..3b08374 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs @@ -1,7 +1,7 @@ using AtomUI.Data; +using AtomUI.IconPkg; using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; @@ -185,7 +185,7 @@ public class AddOnDecoratedBox : ContentControl if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) { - if (change.NewValue is PathIcon icon) + if (change.NewValue is Icon icon) { SetupIconTypeAddOnSize(icon); } @@ -201,19 +201,19 @@ public class AddOnDecoratedBox : ContentControl if (change.Property == SizeTypeProperty) { - if (LeftAddOn is PathIcon leftIconAddOn) + if (LeftAddOn is Icon leftIconAddOn) { SetupIconTypeAddOnSize(leftIconAddOn); } - if (RightAddOn is PathIcon rightIconAddOn) + if (RightAddOn is Icon rightIconAddOn) { SetupIconTypeAddOnSize(rightIconAddOn); } } } - private void SetupIconTypeAddOnSize(PathIcon icon) + private void SetupIconTypeAddOnSize(Icon icon) { if (SizeType == SizeType.Large) { diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs index ceab0f0..e1b96c2 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs @@ -1,6 +1,6 @@ using AtomUI.Theme; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Presenters; diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs index 236023c..c081dbf 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs @@ -1,7 +1,7 @@ using AtomUI.Controls.Utils; using AtomUI.Data; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs index 04a6c7a..ce4b65f 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs @@ -1,7 +1,9 @@ -using AtomUI.Media; +using AtomUI.IconPkg; +using AtomUI.IconPkg.AntDesign; +using AtomUI.Media; using AtomUI.Theme; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Theme.Utils; using AtomUI.Utils; using Avalonia; using Avalonia.Animation; @@ -185,10 +187,7 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme protected virtual void BuildClearButton(StackPanel addOnLayout, INameScope scope) { - var closeIcon = new PathIcon - { - Kind = "CloseCircleFilled" - }; + var closeIcon = AntDesignIconPackage.CloseCircleFilled(); var clearButton = new IconButton { Name = ClearButtonPart, @@ -199,11 +198,11 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme GlobalTokenResourceKey.IconSize); TokenResourceBinder.CreateGlobalTokenBinding(clearButton, IconButton.IconWidthProperty, GlobalTokenResourceKey.IconSize); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorTextQuaternary); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, Icon.ActiveFilledBrushProperty, GlobalTokenResourceKey.ColorTextTertiary); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, Icon.SelectedFilledBrushProperty, GlobalTokenResourceKey.ColorText); clearButton.RegisterInNameScope(scope); @@ -241,7 +240,7 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme largeStyle.Add(innerBoxContentStyle); } { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSizeLG); iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSizeLG); largeStyle.Add(iconStyle); @@ -259,7 +258,7 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme middleStyle.Add(innerBoxContentStyle); } { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSize); iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSize); middleStyle.Add(iconStyle); @@ -277,7 +276,7 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme smallStyle.Add(innerBoxContentStyle); } { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSizeSM); iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSizeSM); smallStyle.Add(iconStyle); @@ -511,8 +510,8 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); { var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); - iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); + selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); + iconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); errorStyle.Add(iconStyle); } Add(errorStyle); @@ -523,8 +522,8 @@ internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); { var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); - iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); + selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); + iconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); warningStyle.Add(iconStyle); } Add(warningStyle); diff --git a/src/AtomUI.Controls/Alert/Alert.cs b/src/AtomUI.Controls/Alert/Alert.cs index b67d0dc..642c032 100644 --- a/src/AtomUI.Controls/Alert/Alert.cs +++ b/src/AtomUI.Controls/Alert/Alert.cs @@ -1,6 +1,7 @@ -using AtomUI.Theme.Data; +using AtomUI.IconPkg; +using AtomUI.IconPkg.AntDesign; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; @@ -33,8 +34,8 @@ public class Alert : TemplatedControl public static readonly StyledProperty IsClosableProperty = AvaloniaProperty.Register(nameof(IsClosable)); - public static readonly StyledProperty CloseIconProperty = - AvaloniaProperty.Register(nameof(CloseIcon)); + public static readonly StyledProperty CloseIconProperty = + AvaloniaProperty.Register(nameof(CloseIcon)); public static readonly StyledProperty MessageProperty = AvaloniaProperty.Register(nameof(Message)); @@ -69,7 +70,7 @@ public class Alert : TemplatedControl set => SetValue(IsClosableProperty, value); } - public PathIcon? CloseIcon + public Icon? CloseIcon { get => GetValue(CloseIconProperty); set => SetValue(CloseIconProperty, value); @@ -144,13 +145,10 @@ public class Alert : TemplatedControl { if (CloseIcon is null) { - CloseIcon = new PathIcon - { - Kind = "CloseOutlined" - }; - TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.NormalFilledBrushProperty, + CloseIcon = AntDesignIconPackage.CloseOutlined(); + TokenResourceBinder.CreateTokenBinding(CloseIcon, Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorIcon); - TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.ActiveFilledBrushProperty, + TokenResourceBinder.CreateTokenBinding(CloseIcon, Icon.ActiveFilledBrushProperty, GlobalTokenResourceKey.ColorIconHover); } } diff --git a/src/AtomUI.Controls/Alert/AlertTheme.cs b/src/AtomUI.Controls/Alert/AlertTheme.cs index de329eb..20a540e 100644 --- a/src/AtomUI.Controls/Alert/AlertTheme.cs +++ b/src/AtomUI.Controls/Alert/AlertTheme.cs @@ -1,7 +1,9 @@ using AtomUI.Data; +using AtomUI.IconPkg; +using AtomUI.IconPkg.AntDesign; using AtomUI.Theme; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Presenters; @@ -142,13 +144,13 @@ internal class AlertTheme : BaseControlTheme private void BuildInfoIconStyle() { - var infoIconSelector = default(Selector).Nesting().Template().OfType().Name(InfoIconPart); + var infoIconSelector = default(Selector).Nesting().Template().OfType().Name(InfoIconPart); { var successStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Success)); var infoIconStyle = new Style(selector => infoIconSelector); - infoIconStyle.Add(PathIcon.KindProperty, "CheckCircleFilled"); - infoIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorSuccess); + infoIconStyle.Add(Icon.IconInfoProperty, AntDesignIconPackage.Current.GetIconInfo(AntDesignIconKind.CheckCircleFilled)); + infoIconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorSuccess); successStyle.Add(infoIconStyle); Add(successStyle); } @@ -157,8 +159,8 @@ internal class AlertTheme : BaseControlTheme var infoStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Info)); var infoIconStyle = new Style(selector => infoIconSelector); - infoIconStyle.Add(PathIcon.KindProperty, "InfoCircleFilled"); - infoIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorPrimary); + infoIconStyle.Add(Icon.IconInfoProperty, AntDesignIconPackage.Current.GetIconInfo(AntDesignIconKind.InfoCircleFilled)); + infoIconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorPrimary); infoStyle.Add(infoIconStyle); Add(infoStyle); } @@ -167,8 +169,8 @@ internal class AlertTheme : BaseControlTheme var warningStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Warning)); var infoIconStyle = new Style(selector => infoIconSelector); - infoIconStyle.Add(PathIcon.KindProperty, "ExclamationCircleFilled"); - infoIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); + infoIconStyle.Add(Icon.IconInfoProperty, AntDesignIconPackage.Current.GetIconInfo(AntDesignIconKind.ExclamationCircleFilled)); + infoIconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); warningStyle.Add(infoIconStyle); Add(warningStyle); } @@ -177,8 +179,8 @@ internal class AlertTheme : BaseControlTheme var errorStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Error)); var infoIconStyle = new Style(selector => infoIconSelector); - infoIconStyle.Add(PathIcon.KindProperty, "CloseCircleFilled"); - infoIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); + infoIconStyle.Add(Icon.IconInfoProperty, AntDesignIconPackage.Current.GetIconInfo(AntDesignIconKind.CloseCircleFilled)); + infoIconStyle.Add(Icon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); errorStyle.Add(infoIconStyle); Add(errorStyle); } @@ -311,9 +313,9 @@ internal class AlertTheme : BaseControlTheme return closeBtn; } - private PathIcon CreateInfoIcon(INameScope scope) + private Icon CreateInfoIcon(INameScope scope) { - var infoIcon = new PathIcon + var infoIcon = new Icon { Name = InfoIconPart }; diff --git a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs index 9f1392f..7e20c8c 100644 --- a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs +++ b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs @@ -1,78 +1,79 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Layout; namespace AtomUI.Controls; public enum ArrowPosition { - /// - /// Preferred location is below the target element. - /// - Bottom, + /// + /// Preferred location is below the target element. + /// + Bottom, - /// - /// Preferred location is to the right of the target element. - /// - Right, + /// + /// Preferred location is to the right of the target element. + /// + Right, - /// - /// Preferred location is to the left of the target element. - /// - Left, + /// + /// Preferred location is to the left of the target element. + /// + Left, - /// - /// Preferred location is above the target element. - /// - Top, + /// + /// Preferred location is above the target element. + /// + Top, - /// - /// Preferred location is above the target element, with the left edge of the popup - /// aligned with the left edge of the target element. - /// - TopEdgeAlignedLeft, + /// + /// Preferred location is above the target element, with the left edge of the popup + /// aligned with the left edge of the target element. + /// + TopEdgeAlignedLeft, - /// - /// Preferred location is above the target element, with the right edge of popup aligned with right edge of the target - /// element. - /// - TopEdgeAlignedRight, + /// + /// Preferred location is above the target element, with the right edge of popup aligned with right edge of the target + /// element. + /// + TopEdgeAlignedRight, - /// - /// Preferred location is below the target element, with the left edge of popup aligned with left edge of the target - /// element. - /// - BottomEdgeAlignedLeft, + /// + /// Preferred location is below the target element, with the left edge of popup aligned with left edge of the target + /// element. + /// + BottomEdgeAlignedLeft, - /// - /// Preferred location is below the target element, with the right edge of popup aligned with right edge of the target - /// element. - /// - BottomEdgeAlignedRight, + /// + /// Preferred location is below the target element, with the right edge of popup aligned with right edge of the target + /// element. + /// + BottomEdgeAlignedRight, - /// - /// Preferred location is to the left of the target element, with the top edge of popup aligned with top edge of the - /// target element. - /// - LeftEdgeAlignedTop, + /// + /// Preferred location is to the left of the target element, with the top edge of popup aligned with top edge of the + /// target element. + /// + LeftEdgeAlignedTop, - /// - /// Preferred location is to the left of the target element, with the bottom edge of popup aligned with bottom edge of - /// the target element. - /// - LeftEdgeAlignedBottom, + /// + /// Preferred location is to the left of the target element, with the bottom edge of popup aligned with bottom edge of + /// the target element. + /// + LeftEdgeAlignedBottom, - /// - /// Preferred location is to the right of the target element, with the top edge of popup aligned with top edge of the - /// target element. - /// - RightEdgeAlignedTop, + /// + /// Preferred location is to the right of the target element, with the top edge of popup aligned with top edge of the + /// target element. + /// + RightEdgeAlignedTop, - /// - /// Preferred location is to the right of the target element, with the bottom edge of popup aligned with bottom edge of - /// the target element. - /// - RightEdgeAlignedBottom + /// + /// Preferred location is to the right of the target element, with the bottom edge of popup aligned with bottom edge of + /// the target element. + /// + RightEdgeAlignedBottom } public class ArrowDecoratedBox : ContentControl, IShadowMaskInfoProvider @@ -205,9 +206,16 @@ public class ArrowDecoratedBox : ContentControl, IShadowMaskInfoProvider { return default; } - var targetRect = _arrowIndicatorLayout.Bounds; - var center = targetRect.Center; - var controlSize = Bounds.Size; + + if (_arrowIndicatorLayout.Bounds == default) + { + LayoutHelper.MeasureChild(this, Size.Infinity, Padding); + Arrange(new Rect(DesiredSize)); + } + + var targetRect = _arrowIndicatorLayout.Bounds; + var center = targetRect.Center; + var controlSize = Bounds.Size; // 计算中点 var direction = GetDirection(ArrowPosition); @@ -234,10 +242,10 @@ public class ArrowDecoratedBox : ContentControl, IShadowMaskInfoProvider { return; } - var offsetX = 0d; - var offsetY = 0d; - var position = ArrowPosition; - var size = _arrowIndicatorLayout.DesiredSize; + var offsetX = 0d; + var offsetY = 0d; + var position = ArrowPosition; + var size = _arrowIndicatorLayout.DesiredSize; var minValue = Math.Min(size.Width, size.Height); var maxValue = Math.Max(size.Width, size.Height); diff --git a/src/AtomUI.Controls/AtomUI.Controls.csproj b/src/AtomUI.Controls/AtomUI.Controls.csproj index e004f8d..544218b 100644 --- a/src/AtomUI.Controls/AtomUI.Controls.csproj +++ b/src/AtomUI.Controls/AtomUI.Controls.csproj @@ -21,6 +21,7 @@ + diff --git a/src/AtomUI.Controls/AtomUI.Controls.csproj.DotSettings b/src/AtomUI.Controls/AtomUI.Controls.csproj.DotSettings new file mode 100644 index 0000000..8b23a66 --- /dev/null +++ b/src/AtomUI.Controls/AtomUI.Controls.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/AtomUI.Controls/Badge/BadgeMotionFactory.cs b/src/AtomUI.Controls/Badge/BadgeMotion.cs similarity index 57% rename from src/AtomUI.Controls/Badge/BadgeMotionFactory.cs rename to src/AtomUI.Controls/Badge/BadgeMotion.cs index c174116..2bbeded 100644 --- a/src/AtomUI.Controls/Badge/BadgeMotionFactory.cs +++ b/src/AtomUI.Controls/Badge/BadgeMotion.cs @@ -6,21 +6,18 @@ using Avalonia.Styling; namespace AtomUI.Controls.Badge; -internal static class BadgeMotionFactory +internal class BadgeZoomBadgeInMotion : AbstractMotion { - public static MotionConfigX BuildBadgeZoomBadgeInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + public BadgeZoomBadgeInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new ExponentialEaseOut(), fillMode) { - easing ??= new ExponentialEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; + } + protected override void Configure() + { + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -36,7 +33,7 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(0.0) + Value = BuildScaleTransform(0.01) }; startFrame.Setters.Add(transformSetter); } @@ -57,30 +54,29 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(1.0) + Value = BuildScaleTransform(1.0) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class BadgeZoomBadgeOutMotion : AbstractMotion +{ + public BadgeZoomBadgeOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new ExponentialEaseIn(), fillMode) + { } - public static MotionConfigX BuildBadgeZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new ExponentialEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -96,7 +92,7 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(1.0) + Value = BuildScaleTransform(1.0) }; startFrame.Setters.Add(transformSetter); } @@ -117,30 +113,29 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(0.0) + Value = BuildScaleTransform(0.01) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class CountBadgeNoWrapperZoomBadgeInMotion : AbstractMotion +{ + public CountBadgeNoWrapperZoomBadgeInMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseOut(), fillMode) + { } - public static MotionConfigX BuildCountBadgeNoWrapperZoomBadgeInMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CircularEaseOut(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -156,7 +151,7 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(0.0, 0.0) + Value = BuildScaleTransform(0.01, 0.01) }; startFrame.Setters.Add(transformSetter); } @@ -177,30 +172,29 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(1.0, 1.0) + Value = BuildScaleTransform(1.0, 1.0) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); + } +} + +internal class CountBadgeNoWrapperZoomBadgeOutMotion : AbstractMotion +{ + public CountBadgeNoWrapperZoomBadgeOutMotion(TimeSpan duration, + Easing? easing = null, + FillMode fillMode = FillMode.Forward) + : base(duration, easing ?? new CircularEaseIn(), fillMode) + { } - public static MotionConfigX BuildCountBadgeNoWrapperZoomBadgeOutMotion(TimeSpan duration, Easing? easing = null, - FillMode fillMode = FillMode.None) + protected override void Configure() { - easing ??= new CircularEaseIn(); - var animations = new List(); - RelativePoint transformOrigin = default; - var animation = new Animation - { - Duration = duration, - Easing = easing, - FillMode = fillMode - }; - + var animation = CreateAnimation(); var startFrame = new KeyFrame { Cue = new Cue(0.0) @@ -216,7 +210,7 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(1.0, 1.0) + Value = BuildScaleTransform(1.0, 1.0) }; startFrame.Setters.Add(transformSetter); } @@ -237,14 +231,14 @@ internal static class BadgeMotionFactory var transformSetter = new Setter { Property = MotionActorControl.MotionTransformProperty, - Value = MotionFactory.BuildScaleTransform(0.0, 0.0) + Value = BuildScaleTransform(0.01, 0.01) }; endFrame.Setters.Add(transformSetter); } animation.Children.Add(endFrame); - transformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative); + RenderTransformOrigin = new RelativePoint(0.5, 0.5, RelativeUnit.Relative); - animations.Add(animation); - return new MotionConfigX(transformOrigin, animations); + Animations.Add(animation); } -} \ No newline at end of file +} + diff --git a/src/AtomUI.Controls/Badge/CountBadge.cs b/src/AtomUI.Controls/Badge/CountBadge.cs index 695190b..7ebc93f 100644 --- a/src/AtomUI.Controls/Badge/CountBadge.cs +++ b/src/AtomUI.Controls/Badge/CountBadge.cs @@ -1,7 +1,7 @@ using AtomUI.Data; +using AtomUI.Theme.Data; using AtomUI.Theme.Palette; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; diff --git a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs index fe6c3c5..c5183a0 100644 --- a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs +++ b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs @@ -1,9 +1,8 @@ using AtomUI.Controls.Badge; using AtomUI.MotionScene; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; -using Avalonia.Animation; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Media; @@ -142,7 +141,6 @@ internal class CountBadgeAdorner : TemplatedControl #endregion - private Panel? _rootLayout; private MotionActorControl? _indicatorMotionActor; private CancellationTokenSource? _motionCancellationTokenSource; private bool _needInitialHide; @@ -231,9 +229,8 @@ internal class CountBadgeAdorner : TemplatedControl if (_indicatorMotionActor is not null) { _indicatorMotionActor.IsVisible = false; - var zoomBadgeInMotionConfig = BadgeMotionFactory.BuildBadgeZoomBadgeInMotion(MotionDuration, null, - FillMode.Forward); - MotionInvoker.Invoke(_indicatorMotionActor, zoomBadgeInMotionConfig, () => + var motion = new BadgeZoomBadgeInMotion(MotionDuration); + MotionInvoker.Invoke(_indicatorMotionActor, motion, () => { _indicatorMotionActor.IsVisible = true; }, null, _motionCancellationTokenSource!.Token); @@ -244,12 +241,11 @@ internal class CountBadgeAdorner : TemplatedControl { if (_indicatorMotionActor is not null) { - var zoomBadgeOutMotionConfig = BadgeMotionFactory.BuildBadgeZoomBadgeOutMotion(MotionDuration, null, - FillMode.Forward); + var motion = new BadgeZoomBadgeOutMotion(MotionDuration); _motionCancellationTokenSource?.Cancel(); _motionCancellationTokenSource = new CancellationTokenSource(); - MotionInvoker.Invoke(_indicatorMotionActor, zoomBadgeOutMotionConfig, null, () => + MotionInvoker.Invoke(_indicatorMotionActor, motion, null, () => { completedAction(); }, _motionCancellationTokenSource.Token); diff --git a/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs b/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs index 04dd88d..d9f682e 100644 --- a/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs +++ b/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs @@ -1,7 +1,7 @@ using AtomUI.Controls.Badge; using AtomUI.MotionScene; +using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Animation; using Avalonia.Controls; @@ -15,13 +15,13 @@ internal class DotBadgeAdorner : TemplatedControl public static readonly StyledProperty BadgeDotColorProperty = AvaloniaProperty.Register( nameof(BadgeDotColor)); - + public static readonly DirectProperty StatusProperty = AvaloniaProperty.RegisterDirect( nameof(Status), o => o.Status, (o, v) => o.Status = v); - + internal IBrush? BadgeDotColor { get => GetValue(BadgeDotColorProperty); @@ -73,7 +73,7 @@ internal class DotBadgeAdorner : TemplatedControl get => GetValue(OffsetProperty); set => SetValue(OffsetProperty, value); } - + #region 内部属性定义 internal static readonly StyledProperty MotionDurationProperty = @@ -85,9 +85,9 @@ internal class DotBadgeAdorner : TemplatedControl get => GetValue(MotionDurationProperty); set => SetValue(MotionDurationProperty, value); } - + #endregion - + private MotionActorControl? _indicatorMotionActor; private CancellationTokenSource? _motionCancellationTokenSource; @@ -109,28 +109,23 @@ internal class DotBadgeAdorner : TemplatedControl if (_indicatorMotionActor is not null) { _indicatorMotionActor.IsVisible = false; - var zoomBadgeInMotionConfig = BadgeMotionFactory.BuildBadgeZoomBadgeInMotion(MotionDuration, null, - FillMode.Forward); - MotionInvoker.Invoke(_indicatorMotionActor, zoomBadgeInMotionConfig, () => - { - _indicatorMotionActor.IsVisible = true; - }, null, _motionCancellationTokenSource!.Token); + _motionCancellationTokenSource?.Cancel(); + _motionCancellationTokenSource = new CancellationTokenSource(); + var motion = new BadgeZoomBadgeInMotion(MotionDuration, null, FillMode.Forward); + MotionInvoker.Invoke(_indicatorMotionActor, motion, () => _indicatorMotionActor.IsVisible = true, + null, _motionCancellationTokenSource.Token); } } - + private void ApplyHideMotion(Action completedAction) { if (_indicatorMotionActor is not null) { - var zoomBadgeOutMotionConfig = BadgeMotionFactory.BuildBadgeZoomBadgeOutMotion(MotionDuration, null, - FillMode.Forward); _motionCancellationTokenSource?.Cancel(); - _motionCancellationTokenSource = new CancellationTokenSource(); - - MotionInvoker.Invoke(_indicatorMotionActor, zoomBadgeOutMotionConfig, null, () => - { - completedAction(); - }, _motionCancellationTokenSource.Token); + _motionCancellationTokenSource = new CancellationTokenSource(); + var motion = new BadgeZoomBadgeOutMotion(MotionDuration, null, FillMode.Forward); + MotionInvoker.Invoke(_indicatorMotionActor, motion, null, () => completedAction(), + _motionCancellationTokenSource.Token); } } @@ -145,7 +140,7 @@ internal class DotBadgeAdorner : TemplatedControl } } } - + private void SetupBadgeColor() { if (Status is not null) @@ -190,6 +185,7 @@ internal class DotBadgeAdorner : TemplatedControl offsetY -= dotSize.Height / 3; _indicatorMotionActor.Arrange(new Rect(new Point(offsetX, offsetY), dotSize)); } + return size; } @@ -199,16 +195,16 @@ internal class DotBadgeAdorner : TemplatedControl { return; } - + adornerLayer.Children.Remove(this); - + AdornerLayer.SetAdornedElement(this, adorned); AdornerLayer.SetIsClipEnabled(this, false); adornerLayer.Children.Add(this); - + _motionCancellationTokenSource?.Cancel(); - _motionCancellationTokenSource = new CancellationTokenSource(); - + _motionCancellationTokenSource = new CancellationTokenSource(); + ApplyShowMotion(); } diff --git a/src/AtomUI.Controls/Badge/DotBadgeIndicator.cs b/src/AtomUI.Controls/Badge/DotBadgeIndicator.cs index 1eda028..b3e91b6 100644 --- a/src/AtomUI.Controls/Badge/DotBadgeIndicator.cs +++ b/src/AtomUI.Controls/Badge/DotBadgeIndicator.cs @@ -1,5 +1,5 @@ -using AtomUI.Theme.Styling; -using AtomUI.Utils; +using AtomUI.Theme.Data; +using AtomUI.Theme.Styling; using Avalonia; using Avalonia.Controls; using Avalonia.Media; diff --git a/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerTheme.cs b/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerTheme.cs index d235b63..15adcee 100644 --- a/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerTheme.cs +++ b/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerTheme.cs @@ -1,8 +1,9 @@ -using AtomUI.Media; +using AtomUI.IconPkg; +using AtomUI.IconPkg.AntDesign; +using AtomUI.Media; using AtomUI.Theme; using AtomUI.Theme.Data; using AtomUI.Theme.Styling; -using AtomUI.Theme.Utils; using AtomUI.Utils; using Avalonia.Animation; using Avalonia.Controls; @@ -104,15 +105,12 @@ internal class ButtonSpinnerTheme : BaseControlTheme TokenResourceBinder.CreateTokenBinding(spinnerLayout, Layoutable.WidthProperty, ButtonSpinnerTokenResourceKey.HandleWidth); + + var increaseButtonIcon = AntDesignIconPackage.UpOutlined(); - var increaseButtonIcon = new PathIcon - { - Kind = "UpOutlined" - }; - - TokenResourceBinder.CreateGlobalTokenBinding(increaseButtonIcon, PathIcon.ActiveFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(increaseButtonIcon, Icon.ActiveFilledBrushProperty, ButtonSpinnerTokenResourceKey.HandleHoverColor); - TokenResourceBinder.CreateGlobalTokenBinding(increaseButtonIcon, PathIcon.SelectedFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(increaseButtonIcon, Icon.SelectedFilledBrushProperty, GlobalTokenResourceKey.ColorPrimaryActive); var increaseButton = new IconButton @@ -140,14 +138,11 @@ internal class ButtonSpinnerTheme : BaseControlTheme ButtonSpinnerTokenResourceKey.HandleIconSize); increaseButton.RegisterInNameScope(scope); - var decreaseButtonIcon = new PathIcon - { - Kind = "DownOutlined" - }; + var decreaseButtonIcon = AntDesignIconPackage.DownOutlined(); - TokenResourceBinder.CreateGlobalTokenBinding(decreaseButtonIcon, PathIcon.ActiveFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(decreaseButtonIcon, Icon.ActiveFilledBrushProperty, ButtonSpinnerTokenResourceKey.HandleHoverColor); - TokenResourceBinder.CreateGlobalTokenBinding(decreaseButtonIcon, PathIcon.SelectedFilledBrushProperty, + TokenResourceBinder.CreateGlobalTokenBinding(decreaseButtonIcon, Icon.SelectedFilledBrushProperty, GlobalTokenResourceKey.ColorPrimaryActive); var decreaseButton = new IconButton diff --git a/src/AtomUI.Controls/Buttons/BaseButtonTheme.cs b/src/AtomUI.Controls/Buttons/BaseButtonTheme.cs index f909cff..eda3b35 100644 --- a/src/AtomUI.Controls/Buttons/BaseButtonTheme.cs +++ b/src/AtomUI.Controls/Buttons/BaseButtonTheme.cs @@ -1,4 +1,5 @@ -using AtomUI.Icon; +using AtomUI.IconPkg; +using AtomUI.IconPkg.AntDesign; using AtomUI.Theme; using AtomUI.Theme.Styling; using Avalonia; @@ -31,12 +32,9 @@ internal abstract class BaseButtonTheme : BaseControlTheme { return new FuncControlTemplate