@ -1,4 +1,5 @@
using System ;
using System.ComponentModel ;
using Avalonia.Controls.Diagnostics ;
using Avalonia.Controls.Metadata ;
using Avalonia.Controls.Primitives ;
@ -79,8 +80,9 @@ namespace Avalonia.Controls
internal static readonly AttachedProperty < ToolTip ? > ToolTipProperty =
AvaloniaProperty . RegisterAttached < ToolTip , Control , ToolTip ? > ( "ToolTip" ) ;
private I PopupHost ? _ popupHost ;
private Popup ? _ popup ;
private Action < IPopupHost ? > ? _ popupHostChangedHandler ;
private CompositeDisposable ? _ subscriptions ;
/// <summary>
/// Initializes static members of the <see cref="ToolTip"/> class.
@ -88,10 +90,6 @@ namespace Avalonia.Controls
static ToolTip ( )
{
IsOpenProperty . Changed . Subscribe ( IsOpenChanged ) ;
HorizontalOffsetProperty . Changed . Subscribe ( RecalculatePositionOnPropertyChanged ) ;
VerticalOffsetProperty . Changed . Subscribe ( RecalculatePositionOnPropertyChanged ) ;
PlacementProperty . Changed . Subscribe ( RecalculatePositionOnPropertyChanged ) ;
}
internal Control ? AdornedControl { get ; private set ; }
@ -309,21 +307,9 @@ namespace Avalonia.Controls
}
}
private static void RecalculatePositionOnPropertyChanged ( AvaloniaPropertyChangedEventArgs args )
{
var control = ( Control ) args . Sender ;
var tooltip = control . GetValue ( ToolTipProperty ) ;
if ( tooltip = = null )
{
return ;
}
IPopupHost ? IPopupHostProvider . PopupHost = > _ popup ? . Host ;
tooltip . RecalculatePosition ( control ) ;
}
IPopupHost ? IPopupHostProvider . PopupHost = > _ popupHost ;
internal IPopupHost ? PopupHost = > _ popupHost ;
internal IPopupHost ? PopupHost = > _ popup ? . Host ;
event Action < IPopupHost ? > ? IPopupHostProvider . PopupHostChanged
{
@ -331,47 +317,61 @@ namespace Avalonia.Controls
remove = > _ popupHostChangedHandler - = value ;
}
internal void RecalculatePosition ( Control control )
{
_ popupHost ? . ConfigurePosition ( control , GetPlacement ( control ) , new Point ( GetHorizontalOffset ( control ) , GetVerticalOffset ( control ) ) ) ;
}
private void Open ( Control control )
{
Close ( ) ;
if ( _ popup is null )
{
_ popup = new Popup ( ) ;
_ popup . Child = this ;
_ popup . WindowManagerAddShadowHint = false ;
_ popupHost = OverlayPopupHost . CreatePopupHost ( control , null ) ;
_ popupHost . SetChild ( this ) ;
( ( ISetLogicalParent ) _ popupHost ) . SetParent ( control ) ;
ApplyTemplatedParent ( this , control . TemplatedParent ) ;
_ popup . Opened + = OnPopupOpened ;
_ popup . Closed + = OnPopupClosed ;
}
_ popupHost . ConfigurePosition ( control , GetPlacement ( control ) ,
new Point ( GetHorizontalOffset ( control ) , GetVerticalOffset ( control ) ) ) ;
_ subscriptions = new CompositeDisposable ( new [ ]
{
_ popup . Bind ( Popup . HorizontalOffsetProperty , control . GetBindingObservable ( HorizontalOffsetProperty ) ) ,
_ popup . Bind ( Popup . VerticalOffsetProperty , control . GetBindingObservable ( VerticalOffsetProperty ) ) ,
_ popup . Bind ( Popup . PlacementProperty , control . GetBindingObservable ( PlacementProperty ) )
} ) ;
WindowManagerAddShadowHintChanged ( _ popupHost , false ) ;
_ popup . PlacementTarget = control ;
_ popup . SetPopupParent ( control ) ;
_ popupHost . Show ( ) ;
_ popupHostChangedHandler ? . Invoke ( _ popupHost ) ;
_ popup . IsOpen = true ;
}
private void Close ( )
{
if ( _ popupHost ! = null )
_ subscriptions ? . Dispose ( ) ;
if ( _ popup is not null )
{
_ popupHost . SetChild ( null ) ;
_ popupHost . Dispose ( ) ;
_ popupHost = null ;
_ popupHostChangedHandler ? . Invoke ( null ) ;
Closed ? . Invoke ( this , EventArgs . Empty ) ;
_ popup . IsOpen = false ;
_ popup . SetPopupParent ( null ) ;
_ popup . PlacementTarget = null ;
}
}
private void WindowManagerAddShadowHintChanged ( IPopupHost host , bool hint )
private void OnPopupClosed ( object? sender , EventArgs e )
{
if ( host is PopupRoot pr )
// This condition is true, when Popup was closed by any other reason outside of ToolTipService/ToolTip, keeping IsOpen=true.
if ( AdornedControl is { } adornedControl
& & GetIsOpen ( adornedControl ) )
{
pr . WindowManagerAddShadowHint = hint ;
adornedControl . SetCurrentValue ( IsOpenProperty , false ) ;
}
_ popupHostChangedHandler ? . Invoke ( null ) ;
Closed ? . Invoke ( this , EventArgs . Empty ) ;
}
private void OnPopupOpened ( object? sender , EventArgs e )
{
_ popupHostChangedHandler ? . Invoke ( ( ( Popup ) sender ! ) . Host ) ;
}
private void UpdatePseudoClasses ( bool newValue )