|
|
|
@ -1,5 +1,6 @@ |
|
|
|
using System; |
|
|
|
using System.ComponentModel; |
|
|
|
using System.Diagnostics.CodeAnalysis; |
|
|
|
using Avalonia.Reactive; |
|
|
|
using Avalonia.Automation.Peers; |
|
|
|
using Avalonia.Controls.Diagnostics; |
|
|
|
@ -152,9 +153,7 @@ namespace Avalonia.Controls.Primitives |
|
|
|
{ |
|
|
|
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false); |
|
|
|
ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e)); |
|
|
|
IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged((AvaloniaPropertyChangedEventArgs<bool>)e)); |
|
|
|
VerticalOffsetProperty.Changed.AddClassHandler<Popup>((x, _) => x.HandlePositionChange()); |
|
|
|
HorizontalOffsetProperty.Changed.AddClassHandler<Popup>((x, _) => x.HandlePositionChange()); |
|
|
|
IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged((AvaloniaPropertyChangedEventArgs<bool>)e)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -720,18 +719,7 @@ namespace Avalonia.Controls.Primitives |
|
|
|
{ |
|
|
|
if (_openState != null) |
|
|
|
{ |
|
|
|
var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType<Control>(); |
|
|
|
if (placementTarget == null) |
|
|
|
return; |
|
|
|
_openState.PopupHost.ConfigurePosition(new PopupPositionRequest( |
|
|
|
placementTarget, |
|
|
|
Placement, |
|
|
|
new Point(HorizontalOffset, VerticalOffset), |
|
|
|
PlacementAnchor, |
|
|
|
PlacementGravity, |
|
|
|
PlacementConstraintAdjustment, |
|
|
|
PlacementRect, |
|
|
|
CustomPopupPlacementCallback)); |
|
|
|
UpdateHostPosition(_openState.PopupHost, _openState.PlacementTarget); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -977,7 +965,20 @@ namespace Avalonia.Controls.Primitives |
|
|
|
|
|
|
|
private void WindowPositionChanged(PixelPoint pp) => HandlePositionChange(); |
|
|
|
|
|
|
|
private void PlacementTargetLayoutUpdated(object? src, EventArgs e) => HandlePositionChange(); |
|
|
|
private void PlacementTargetLayoutUpdated(object? src, EventArgs e) |
|
|
|
{ |
|
|
|
if (_openState is null) |
|
|
|
return; |
|
|
|
|
|
|
|
// A LayoutUpdated event is raised for the whole visual tree:
|
|
|
|
// the bounds of the PlacementTarget might not have effectively changed.
|
|
|
|
var newBounds = _openState.PlacementTarget.Bounds; |
|
|
|
if (newBounds == _openState.LastPlacementTargetBounds) |
|
|
|
return; |
|
|
|
|
|
|
|
_openState.LastPlacementTargetBounds = newBounds; |
|
|
|
UpdateHostPosition(_openState.PopupHost, _openState.PlacementTarget); |
|
|
|
} |
|
|
|
|
|
|
|
private void ParentPopupPositionChanged(object? src, PixelPointEventArgs e) => HandlePositionChange(); |
|
|
|
|
|
|
|
@ -1006,6 +1007,7 @@ namespace Avalonia.Controls.Primitives |
|
|
|
{ |
|
|
|
private readonly IDisposable _cleanup; |
|
|
|
private IDisposable? _presenterCleanup; |
|
|
|
private Control _placementTarget; |
|
|
|
|
|
|
|
public PopupOpenState(Control placementTarget, TopLevel topLevel, IPopupHost popupHost, IDisposable cleanup) |
|
|
|
{ |
|
|
|
@ -1016,7 +1018,20 @@ namespace Avalonia.Controls.Primitives |
|
|
|
} |
|
|
|
|
|
|
|
public TopLevel TopLevel { get; } |
|
|
|
public Control PlacementTarget { get; set; } |
|
|
|
|
|
|
|
public Control PlacementTarget |
|
|
|
{ |
|
|
|
get => _placementTarget; |
|
|
|
[MemberNotNull(nameof(_placementTarget))] |
|
|
|
set |
|
|
|
{ |
|
|
|
_placementTarget = value; |
|
|
|
LastPlacementTargetBounds = value.Bounds; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Rect LastPlacementTargetBounds { get; set; } |
|
|
|
|
|
|
|
public IPopupHost PopupHost { get; } |
|
|
|
|
|
|
|
public void SetPresenterSubscription(IDisposable? presenterCleanup) |
|
|
|
|