mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-29 18:38:16 +08:00
Refactor Tooltip Motion
This commit is contained in:
parent
b521c64a99
commit
369501d400
@ -35,24 +35,24 @@ internal class AbstractMotion : IMotion
|
||||
{
|
||||
using var originRestore = new RenderTransformOriginRestore(actor);
|
||||
actor.RenderTransformOrigin = RenderTransformOrigin;
|
||||
actor.NotifyMotionPreStart();
|
||||
NotifyPreStart();
|
||||
if (aboutToStart is not null)
|
||||
{
|
||||
aboutToStart();
|
||||
}
|
||||
actor.NotifyMotionPreStart();
|
||||
NotifyPreStart();
|
||||
|
||||
actor.IsVisible = true;
|
||||
foreach (var animation in Animations)
|
||||
{
|
||||
await animation.RunAsync(actor, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
actor.NotifyMotionCompleted();
|
||||
NotifyCompleted();
|
||||
if (completedAction is not null)
|
||||
{
|
||||
completedAction();
|
||||
}
|
||||
actor.NotifyMotionCompleted();
|
||||
NotifyCompleted();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,4 +3,5 @@
|
||||
internal interface INotifyCaptureGhostBitmap
|
||||
{
|
||||
public void NotifyCaptureGhostBitmap();
|
||||
public void NotifyClearGhostBitmap();
|
||||
}
|
@ -44,32 +44,32 @@ internal static class MotionInvoker
|
||||
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);
|
||||
await Task.Delay(100);
|
||||
sceneLayer.Hide();
|
||||
sceneLayer.Dispose();
|
||||
});
|
||||
}));
|
||||
var ghost = actor.GetAnimatableGhost();
|
||||
sceneLayer.SetMotionTarget(ghost);
|
||||
actor.NotifyMotionTargetAddedToScene(ghost);
|
||||
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();
|
||||
}
|
||||
|
||||
compositeDisposable.Dispose();
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,16 @@ internal class MoveDownInMotion : AbstractMotion
|
||||
|
||||
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 MoveDownOutMotion : AbstractMotion
|
||||
@ -173,6 +183,11 @@ internal class MoveDownOutMotion : AbstractMotion
|
||||
|
||||
Animations.Add(animation);
|
||||
}
|
||||
|
||||
internal override Size CalculateSceneSize(Size actorSize)
|
||||
{
|
||||
return actorSize.WithHeight(actorSize.Height * 2);
|
||||
}
|
||||
}
|
||||
|
||||
internal class MoveUpInMotion : AbstractMotion
|
||||
@ -257,6 +272,16 @@ internal class MoveUpInMotion : AbstractMotion
|
||||
|
||||
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
|
||||
@ -351,6 +376,11 @@ internal class MoveUpOutMotion : AbstractMotion
|
||||
|
||||
Animations.Add(animation);
|
||||
}
|
||||
|
||||
internal override Size CalculateSceneSize(Size actorSize)
|
||||
{
|
||||
return actorSize.WithHeight(actorSize.Height * 2);
|
||||
}
|
||||
}
|
||||
|
||||
internal class MoveLeftInMotion : AbstractMotion
|
||||
@ -438,6 +468,16 @@ internal class MoveLeftInMotion : AbstractMotion
|
||||
|
||||
Animations.Add(animation);
|
||||
}
|
||||
|
||||
internal override Size CalculateSceneSize(Size actorSize)
|
||||
{
|
||||
return actorSize.WithWidth(actorSize.Width * 2);
|
||||
}
|
||||
|
||||
internal override Point CalculateScenePosition(Size actorSize, Point actorPosition)
|
||||
{
|
||||
return actorPosition.WithX(actorPosition.X - actorSize.Width);
|
||||
}
|
||||
}
|
||||
|
||||
internal class MoveLeftOutMotion : AbstractMotion
|
||||
@ -521,6 +561,11 @@ internal class MoveLeftOutMotion : AbstractMotion
|
||||
|
||||
Animations.Add(animation);
|
||||
}
|
||||
|
||||
internal override Size CalculateSceneSize(Size actorSize)
|
||||
{
|
||||
return actorSize.WithHeight(actorSize.Width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
internal class MoveRightInMotion : AbstractMotion
|
||||
@ -606,6 +651,16 @@ internal class MoveRightInMotion : AbstractMotion
|
||||
|
||||
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
|
||||
@ -690,4 +745,9 @@ internal class MoveRightOutMotion : AbstractMotion
|
||||
|
||||
Animations.Add(animation);
|
||||
}
|
||||
|
||||
internal override Size CalculateSceneSize(Size actorSize)
|
||||
{
|
||||
return actorSize.WithHeight(actorSize.Width * 2);
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ 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 @@ internal 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 @@ internal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,15 @@ namespace AtomUI.MotionScene;
|
||||
internal class SceneMotionActorControl : MotionActorControl
|
||||
{
|
||||
public event EventHandler? SceneShowed;
|
||||
|
||||
#region 公共属性定义
|
||||
|
||||
/// <summary>
|
||||
/// 动画实体
|
||||
/// </summary>
|
||||
public Control MotionTarget { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
@ -18,8 +27,14 @@ internal class SceneMotionActorControl : MotionActorControl
|
||||
#endregion
|
||||
|
||||
protected Control? _ghost;
|
||||
|
||||
public SceneMotionActorControl(Control motionTarget)
|
||||
{
|
||||
MotionTarget = motionTarget;
|
||||
UseRenderTransform = true;
|
||||
}
|
||||
|
||||
protected virtual void BuildGhost()
|
||||
internal virtual void BuildGhost()
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,6 +51,7 @@ internal class SceneMotionActorControl : MotionActorControl
|
||||
/// <summary>
|
||||
/// 在这个接口中,Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小
|
||||
/// </summary>
|
||||
/// <param name="motion"></param>
|
||||
/// <param name="sceneLayer"></param>
|
||||
public virtual void NotifySceneLayerCreated(AbstractMotion motion, SceneLayer sceneLayer)
|
||||
{
|
||||
@ -61,15 +77,31 @@ internal class SceneMotionActorControl : MotionActorControl
|
||||
/// <summary>
|
||||
/// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小
|
||||
/// </summary>
|
||||
/// <param name="motionTarget"></param>
|
||||
public virtual void NotifyMotionTargetAddedToScene(Control motionTarget)
|
||||
public virtual void NotifyMotionTargetAddedToScene()
|
||||
{
|
||||
Canvas.SetLeft(motionTarget, 0);
|
||||
Canvas.SetTop(motionTarget, 0);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -151,7 +151,7 @@ internal class ZoomBigInMotion : AbstractMotion
|
||||
var transformSetter = new Setter
|
||||
{
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleTransform(0.8)
|
||||
Value = BuildScaleTransform(0.85)
|
||||
};
|
||||
startFrame.Setters.Add(transformSetter);
|
||||
}
|
||||
@ -177,7 +177,7 @@ internal class ZoomBigInMotion : AbstractMotion
|
||||
endFrame.Setters.Add(transformSetter);
|
||||
}
|
||||
animation.Children.Add(endFrame);
|
||||
RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
|
||||
RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative);
|
||||
Animations.Add(animation);
|
||||
}
|
||||
}
|
||||
@ -231,12 +231,12 @@ internal class ZoomBigOutMotion : AbstractMotion
|
||||
var transformSetter = new Setter
|
||||
{
|
||||
Property = MotionActorControl.MotionTransformProperty,
|
||||
Value = BuildScaleTransform(0.8)
|
||||
Value = BuildScaleTransform(0.85)
|
||||
};
|
||||
endFrame.Setters.Add(transformSetter);
|
||||
}
|
||||
animation.Children.Add(endFrame);
|
||||
RenderTransformOrigin = new RelativePoint(0.0, 0.0, RelativeUnit.Relative);
|
||||
RenderTransformOrigin = new RelativePoint(1.0, 1.0, RelativeUnit.Relative);
|
||||
Animations.Add(animation);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.MotionScene;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Diagnostics;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Primitives.PopupPositioning;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Input.Raw;
|
||||
@ -78,7 +80,7 @@ public class Popup : AvaloniaPopup
|
||||
AffectsMeasure<Popup>(PlacementProperty);
|
||||
AffectsMeasure<Popup>(PlacementAnchorProperty);
|
||||
AffectsMeasure<Popup>(PlacementGravityProperty);
|
||||
|
||||
|
||||
IsLightDismissEnabledProperty.OverrideDefaultValue<Popup>(false);
|
||||
}
|
||||
|
||||
@ -159,7 +161,7 @@ public class Popup : AvaloniaPopup
|
||||
AdjustPopupHostPosition(placementTarget!);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!_animating)
|
||||
{
|
||||
CreateShadowLayer();
|
||||
@ -173,15 +175,16 @@ public class Popup : AvaloniaPopup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool _firstDetected = true;
|
||||
|
||||
|
||||
private void HandleMouseClick(RawInputEventArgs args)
|
||||
{
|
||||
if (!IsOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args is RawPointerEventArgs pointerEventArgs)
|
||||
{
|
||||
if (pointerEventArgs.Type == RawPointerEventType.LeftButtonUp)
|
||||
@ -191,6 +194,7 @@ public class Popup : AvaloniaPopup
|
||||
_firstDetected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this is IPopupHostProvider popupHostProvider)
|
||||
{
|
||||
if (popupHostProvider.PopupHost != pointerEventArgs.Root)
|
||||
@ -320,10 +324,10 @@ public class Popup : AvaloniaPopup
|
||||
new ManagedPopupPositionerScreenInfo(s.Bounds.ToRect(1), s.WorkingArea.ToRect(1)))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
return Array.Empty<ManagedPopupPositionerScreenInfo>();
|
||||
}
|
||||
|
||||
|
||||
// TODO review 后可能需要删除
|
||||
private static Rect GetParentClientAreaScreenGeometry(TopLevel topLevel)
|
||||
{
|
||||
@ -461,49 +465,41 @@ public class Popup : AvaloniaPopup
|
||||
{
|
||||
return;
|
||||
}
|
||||
Open();
|
||||
return;
|
||||
|
||||
// _animating = true;
|
||||
//
|
||||
// var placementTarget = GetEffectivePlacementTarget();
|
||||
//
|
||||
// Open();
|
||||
//
|
||||
// var popupRoot = (Host as PopupRoot)!;
|
||||
// // 获取 popup 的具体位置,这个就是非常准确的位置,还有大小
|
||||
// // TODO 暂时只支持 WindowBase popup
|
||||
// popupRoot.Hide();
|
||||
// var popupOffset = popupRoot.PlatformImpl!.Position;
|
||||
// var offset = new Point(popupOffset.X, popupOffset.Y);
|
||||
// var topLevel = TopLevel.GetTopLevel(placementTarget);
|
||||
// var scaling = topLevel?.RenderScaling ?? 1.0;
|
||||
//
|
||||
// // 调度动画
|
||||
// var director = Director.Instance;
|
||||
// var motion = new ZoomBigInMotion();
|
||||
// motion.ConfigureOpacity(MotionDuration);
|
||||
// motion.ConfigureRenderTransform(MotionDuration);
|
||||
//
|
||||
// var motionActor =
|
||||
// new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
|
||||
// motionActor.DispatchInSceneLayer = true;
|
||||
// motionActor.SceneParent = topLevel;
|
||||
//
|
||||
// motionActor.Completed += (sender, args) =>
|
||||
// {
|
||||
// CreateShadowLayer();
|
||||
// popupRoot.Show();
|
||||
//
|
||||
// if (RequestCloseWhereAnimationCompleted)
|
||||
// {
|
||||
// RequestCloseWhereAnimationCompleted = false;
|
||||
// Dispatcher.UIThread.Post(() => { CloseAnimation(); });
|
||||
// }
|
||||
//
|
||||
// _animating = false;
|
||||
// };
|
||||
// director?.Schedule(motionActor);
|
||||
_animating = true;
|
||||
|
||||
var placementTarget = GetEffectivePlacementTarget();
|
||||
|
||||
Open();
|
||||
|
||||
var popupRoot = (Host as PopupRoot)!;
|
||||
// 获取 popup 的具体位置,这个就是非常准确的位置,还有大小
|
||||
// TODO 暂时只支持 WindowBase popup
|
||||
popupRoot.Hide();
|
||||
var popupOffset = popupRoot.PlatformImpl!.Position;
|
||||
var offset = new Point(popupOffset.X, popupOffset.Y);
|
||||
var topLevel = TopLevel.GetTopLevel(placementTarget);
|
||||
var scaling = topLevel?.RenderScaling ?? 1.0;
|
||||
|
||||
// 调度动画
|
||||
var motion = new ZoomBigInMotion(MotionDuration);
|
||||
|
||||
var motionActor = new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot);
|
||||
motionActor.SceneParent = topLevel;
|
||||
|
||||
MotionInvoker.InvokeInPopupLayer(motionActor, motion, null, () =>
|
||||
{
|
||||
CreateShadowLayer();
|
||||
popupRoot.Show();
|
||||
|
||||
if (RequestCloseWhereAnimationCompleted)
|
||||
{
|
||||
RequestCloseWhereAnimationCompleted = false;
|
||||
Dispatcher.UIThread.Post(() => { CloseAnimation(); });
|
||||
}
|
||||
|
||||
_animating = false;
|
||||
});
|
||||
}
|
||||
|
||||
public void CloseAnimation(Action? closed = null)
|
||||
@ -513,51 +509,41 @@ public class Popup : AvaloniaPopup
|
||||
RequestCloseWhereAnimationCompleted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!IsOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Close();
|
||||
|
||||
// _animating = true;
|
||||
//
|
||||
// var director = Director.Instance;
|
||||
// var motion = new ZoomBigOutMotion();
|
||||
// motion.ConfigureOpacity(MotionDuration);
|
||||
// motion.ConfigureRenderTransform(MotionDuration);
|
||||
//
|
||||
// var popupRoot = (Host as PopupRoot)!;
|
||||
// var popupOffset = popupRoot.PlatformImpl!.Position;
|
||||
// var offset = new Point(popupOffset.X, popupOffset.Y);
|
||||
// var placementTarget = GetEffectivePlacementTarget();
|
||||
// var topLevel = TopLevel.GetTopLevel(placementTarget);
|
||||
//
|
||||
// var scaling = topLevel?.RenderScaling ?? 1.0;
|
||||
//
|
||||
// var motionActor = new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot, motion);
|
||||
// motionActor.DispatchInSceneLayer = true;
|
||||
// motionActor.SceneParent = topLevel;
|
||||
//
|
||||
// motionActor.SceneShowed += (sender, args) =>
|
||||
// {
|
||||
// HideShadowLayer();
|
||||
// popupRoot.Opacity = 0;
|
||||
// };
|
||||
//
|
||||
// motionActor.Completed += (sender, args) =>
|
||||
// {
|
||||
// _animating = false;
|
||||
// _isNeedFlip = true;
|
||||
// Close();
|
||||
// if (closed is not null)
|
||||
// {
|
||||
// closed();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// director?.Schedule(motionActor);
|
||||
_animating = true;
|
||||
|
||||
var motion = new ZoomBigOutMotion(MotionDuration);
|
||||
|
||||
var popupRoot = (Host as PopupRoot)!;
|
||||
var popupOffset = popupRoot.PlatformImpl!.Position;
|
||||
var offset = new Point(popupOffset.X, popupOffset.Y);
|
||||
var placementTarget = GetEffectivePlacementTarget();
|
||||
var topLevel = TopLevel.GetTopLevel(placementTarget);
|
||||
|
||||
var scaling = topLevel?.RenderScaling ?? 1.0;
|
||||
|
||||
var motionActor = new PopupMotionActor(MaskShadows, offset, scaling, Child ?? popupRoot);
|
||||
motionActor.SceneParent = topLevel;
|
||||
|
||||
MotionInvoker.InvokeInPopupLayer(motionActor, motion, () =>
|
||||
{
|
||||
HideShadowLayer();
|
||||
popupRoot.Opacity = 0;
|
||||
}, () =>
|
||||
{
|
||||
_animating = false;
|
||||
_isNeedFlip = true;
|
||||
Close();
|
||||
if (closed is not null)
|
||||
{
|
||||
closed();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,40 +7,40 @@ using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
// internal class PopupMotionActor : MotionActor
|
||||
// {
|
||||
// private readonly BoxShadows _boxShadows;
|
||||
// private readonly Point _offset;
|
||||
// private readonly double _scaling;
|
||||
//
|
||||
// public PopupMotionActor(BoxShadows boxShadows,
|
||||
// Point offset,
|
||||
// double scaling,
|
||||
// Control motionTarget,
|
||||
// AbstractMotion motion)
|
||||
// : base(motionTarget, motion)
|
||||
// {
|
||||
// _offset = offset;
|
||||
// _scaling = scaling;
|
||||
// _boxShadows = boxShadows;
|
||||
// }
|
||||
//
|
||||
// protected override Point CalculateTopLevelGhostPosition()
|
||||
// {
|
||||
// var boxShadowsThickness = _boxShadows.Thickness();
|
||||
// var winPos = _offset; // TODO 可能需要乘以 scaling
|
||||
// var scaledThickness = boxShadowsThickness * _scaling;
|
||||
// return new Point(winPos.X - scaledThickness.Left, winPos.Y - scaledThickness.Top);
|
||||
// }
|
||||
//
|
||||
// protected override void BuildGhost()
|
||||
// {
|
||||
// if (_ghost is null)
|
||||
// {
|
||||
// _ghost = new MotionGhostControl(MotionTarget, _boxShadows)
|
||||
// {
|
||||
// Shadows = _boxShadows
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
internal class PopupMotionActor : SceneMotionActorControl
|
||||
{
|
||||
private readonly BoxShadows _boxShadows;
|
||||
private readonly Point _offset;
|
||||
private readonly double _scaling;
|
||||
|
||||
public PopupMotionActor(BoxShadows boxShadows,
|
||||
Point offset,
|
||||
double scaling,
|
||||
Control motionTarget)
|
||||
: base(motionTarget)
|
||||
{
|
||||
_offset = offset;
|
||||
_scaling = scaling;
|
||||
_boxShadows = boxShadows;
|
||||
}
|
||||
|
||||
protected override Point CalculateTopLevelGhostPosition()
|
||||
{
|
||||
var boxShadowsThickness = _boxShadows.Thickness();
|
||||
var winPos = _offset; // TODO 可能需要乘以 scaling
|
||||
var scaledThickness = boxShadowsThickness * _scaling;
|
||||
return new Point(winPos.X - scaledThickness.Left, winPos.Y - scaledThickness.Top);
|
||||
}
|
||||
|
||||
internal override void BuildGhost()
|
||||
{
|
||||
if (_ghost is null)
|
||||
{
|
||||
_ghost = new MotionGhostControl(MotionTarget, _boxShadows)
|
||||
{
|
||||
Shadows = _boxShadows
|
||||
};
|
||||
Child = _ghost;
|
||||
}
|
||||
}
|
||||
}
|
@ -149,7 +149,7 @@ internal class MotionGhostControl : Control, INotifyCaptureGhostBitmap
|
||||
|
||||
offsetX += _maskOffset.X;
|
||||
offsetY += _maskOffset.Y;
|
||||
|
||||
// 不知道这里为啥不行
|
||||
var renderers = new List<Control>();
|
||||
for (var i = 0; i < shadows.Count; ++i)
|
||||
{
|
||||
@ -217,4 +217,10 @@ internal class MotionGhostControl : Control, INotifyCaptureGhostBitmap
|
||||
_layout!.Children.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyClearGhostBitmap()
|
||||
{
|
||||
_ghostBitmap = null;
|
||||
InvalidateVisual();
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Primitives.PopupPositioning;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@ -678,7 +677,7 @@ public class ToolTip : TemplatedControl, IShadowMaskInfoProvider
|
||||
{
|
||||
popupHostProvider.PopupHostChanged += HandlePopupHostChanged;
|
||||
}
|
||||
|
||||
|
||||
// TODO 可能是多余的,因为有那个对反转事件的处理
|
||||
SetupArrowPosition(placement);
|
||||
// 后期看能不能检测对应字段的改变
|
||||
@ -728,6 +727,7 @@ public class ToolTip : TemplatedControl, IShadowMaskInfoProvider
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_popup is IPopupHostProvider popupHostProvider)
|
||||
{
|
||||
popupHostProvider.PopupHostChanged -= HandlePopupHostChanged;
|
||||
|
Loading…
Reference in New Issue
Block a user