diff --git a/src/AtomUI.Base/MotionScene/MotionInvoker.cs b/src/AtomUI.Base/MotionScene/MotionInvoker.cs index 2497379ce..a9b5ad28f 100644 --- a/src/AtomUI.Base/MotionScene/MotionInvoker.cs +++ b/src/AtomUI.Base/MotionScene/MotionInvoker.cs @@ -17,32 +17,11 @@ internal static class MotionInvoker }); } - 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); - } - 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) { var sceneLayer = PrepareSceneLayer(motion, actor); var compositeDisposable = new CompositeDisposable(); @@ -59,10 +38,9 @@ internal static class MotionInvoker actor.NotifySceneShowed(); actor.IsVisible = false; - await Dispatcher.UIThread.InvokeAsync(async () => + Dispatcher.UIThread.InvokeAsync(async () => { // 主要等待正常窗体显示出来再隐藏对话层,不然感觉会闪屏 - await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken); await motion.RunAsync(actor, aboutToStart, () => { if (completedAction is not null) diff --git a/src/AtomUI.Controls/Flyouts/Flyout.cs b/src/AtomUI.Controls/Flyouts/Flyout.cs index 7e19bc371..d51cac049 100644 --- a/src/AtomUI.Controls/Flyouts/Flyout.cs +++ b/src/AtomUI.Controls/Flyouts/Flyout.cs @@ -346,10 +346,12 @@ public class Flyout : PopupFlyoutBase } IsOpen = true; - Dispatcher.UIThread.InvokeAsync(async () => + Dispatcher.UIThread.InvokeAsync(() => { - await Popup.OpenAsync(); - HandlePopupOpened(placementTarget); + Popup.MotionAwareOpen(() => + { + HandlePopupOpened(placementTarget); + }); }); return true; } @@ -375,11 +377,7 @@ public class Flyout : PopupFlyoutBase } IsOpen = false; - Dispatcher.UIThread.InvokeAsync(async () => - { - await Popup.CloseAsync(); - HandlePopupClosed(); - }); + Dispatcher.UIThread.InvokeAsync(() => { Popup.MotionAwareClose(HandlePopupClosed); }); return true; } diff --git a/src/AtomUI.Controls/Popup/Popup.cs b/src/AtomUI.Controls/Popup/Popup.cs index 5c306eaa0..82d55dbce 100644 --- a/src/AtomUI.Controls/Popup/Popup.cs +++ b/src/AtomUI.Controls/Popup/Popup.cs @@ -226,10 +226,7 @@ public class Popup : AvaloniaPopup, { if (popupHostProvider.PopupHost != pointerEventArgs.Root) { - Dispatcher.UIThread.InvokeAsync(async () => - { - await CloseAsync(); - }); + MotionAwareClose(); } } } @@ -464,24 +461,20 @@ public class Popup : AvaloniaPopup, }; } - public async Task OpenAsync() + public void MotionAwareOpen(Action? opened = null) { // AbstractPopup is currently open if (IsOpen || _openAnimating || _closeAnimating) { - await Task.CompletedTask; + return; } - if (!IsMotionEnabled) { Open(); - await Task.CompletedTask; + opened?.Invoke(); + return; } - _openAnimating = true; - - var tsc = new TaskCompletionSource(); - Open(); var popupRoot = Host as PopupRoot; @@ -492,17 +485,14 @@ public class Popup : AvaloniaPopup, Dispatcher.UIThread.Post(() => { popupRoot.Opacity = 1.0; - RunOpenAnimation(popupRoot, tsc); + RunOpenAnimation(popupRoot, opened); }); + return; } - else - { - RunOpenAnimation(popupRoot, tsc); - } - await tsc.Task; + RunOpenAnimation(popupRoot, opened); } - private void RunOpenAnimation(PopupRoot popupRoot, TaskCompletionSource tsc) + private void RunOpenAnimation(PopupRoot popupRoot, Action? opened = null) { var placementTarget = GetEffectivePlacementTarget(); var popupOffset = popupRoot.PlatformImpl!.Position; @@ -536,34 +526,34 @@ public class Popup : AvaloniaPopup, { _shadowLayer?.Open(); popupRoot.Show(); + opened?.Invoke(); _isNeedWaitFlipSync = false; - _openAnimating = false; + _openAnimating = false; if (RequestCloseWhereAnimationCompleted) { RequestCloseWhereAnimationCompleted = false; - Dispatcher.UIThread.InvokeAsync(async () => { await CloseAsync(); }); + Dispatcher.UIThread.InvokeAsync(() => { Close(); }); } - tsc.SetResult(); }); }); } - public async Task CloseAsync() + public void MotionAwareClose(Action? closed = null) { if (_closeAnimating) { - await Task.CompletedTask; + return; } if (_openAnimating) { RequestCloseWhereAnimationCompleted = true; - await Task.CompletedTask; + return; } if (!IsOpen) { - await Task.CompletedTask; + return; } if (!IsMotionEnabled) @@ -571,11 +561,11 @@ public class Popup : AvaloniaPopup, _shadowLayer?.Close(); _isNeedDetectFlip = true; Close(); - await Task.CompletedTask; + closed?.Invoke(); + return; } _closeAnimating = true; - var tsc = new TaskCompletionSource(); var motion = new ZoomBigOutMotion(MotionDuration); @@ -600,22 +590,20 @@ public class Popup : AvaloniaPopup, motionTarget.DesiredSize); motionActor.SceneParent = topLevel; - Dispatcher.UIThread.Post(() => { MotionInvoker.InvokeInPopupLayer(motionActor, motion, () => { _shadowLayer?.Close(); - popupRoot.Hide(); + popupRoot.Opacity = 0; }, () => { _closeAnimating = false; _isNeedDetectFlip = true; Close(); - tsc.SetResult(); + closed?.Invoke(); }); }); - await tsc.Task; } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) diff --git a/src/AtomUI.Controls/Tooltip/ToolTip.cs b/src/AtomUI.Controls/Tooltip/ToolTip.cs index 922f4645d..1bb05302f 100644 --- a/src/AtomUI.Controls/Tooltip/ToolTip.cs +++ b/src/AtomUI.Controls/Tooltip/ToolTip.cs @@ -397,11 +397,8 @@ public class ToolTip : ContentControl, { TemplateApplied += DeferSetupArrowDecoratedBox; } - - Dispatcher.UIThread.InvokeAsync(async () => - { - await _popup.OpenAsync(); - }); + + _popup.MotionAwareOpen(); } private void DeferSetupArrowDecoratedBox(object? sender, TemplateAppliedEventArgs args) @@ -460,21 +457,20 @@ public class ToolTip : ContentControl, var args = new RoutedEventArgs(ToolTipClosingEvent); adornedControl.RaiseEvent(args); } - - Dispatcher.UIThread.InvokeAsync(async () => + + if (_popup is not null) { - if (_popup is not null) + _popup.MotionAwareClose(() => { - await _popup.CloseAsync(); _popup.SetPopupParent(null); _popup.PlacementTarget = null; if (_popup is IPopupHostProvider popupHostProvider) { popupHostProvider.PopupHostChanged -= HandlePopupHostChanged; } - } - _subscriptions?.Dispose(); - }); + _subscriptions?.Dispose(); + }); + } } private void SetToolTipColor(Control control)